I am doing an ADC12 conversion and sending this value to ADC12MEM0. Once the ADC12 is complete, I am sending the ADC12MEM0 values upper and lower 8 bits to the hyperterminal. I understand that it is simply sending the hex values in the register over as ascii, but I would like to display these values as hex on the hyperterminal. I would like to copy the register exactly as it appears to the hyperterminal (0x0FFF on ADC12MEM0 would make hyperterminal display 0x0FFF... etc.). I have looked at hex to ascii tables and I understand how this works, but I have no idea how to write this as code in code composer studio. Is there some advice you could give me or an example code I can look at to better understand. Below I have provided my code. Thanks!
# include <msp430xG46x.h>volatile unsigned int temp;volatile unsigned int i;void main(void){WDTCTL = WDTPW+WDTHOLD; // Stop watchdog// Initialization of ADC12//P6SEL |= 0x01; // Enable A/D channel A0ADC12CTL0 &= ~ENC;ADC12CTL0 = ADC12ON + SHT0_2 + REFON + REF2_5V+MSC; // turn on ADC12, set samp timeADC12CTL1 = SHP+CONSEQ_2; // Use sampling timerADC12MCTL0 = SREF_1 + INCH_0; // Vr+=VeREF+ (external)ADC12CTL0 |= ENC; // Enable conversions// Initialization of Rs-232//FLL_CTL0 |= XCAP14PF; // Configure load capsdo{IFG1 &= ~OFIFG; // Clear OSCFault flag//_delay_cycles(50000); // Time for flag to set}while ((IFG1 & OFIFG)); // OSCFault flag still set?P2SEL |= 0x30; // P2.4,5 = USCI_A0 RXD/TXDUCA0CTL1 |= UCSSEL_1; // CLK = ACLKUCA0BR0 = 0x03; // 32k/9600 - 13.65UCA0BR1 = 0x00; //UCA0MCTL = 0x06; // ModulationUCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**IE2 |= UCA0TXIE + UCA0RXIE; // enable RXD and TXD interrupt;while (1){// ADC loop //ADC12CTL0 |= ADC12SC; // Start conversions//while (!(ADC12IFG & 0x0001)); // Conversion done?temp = ADC12MEM0; // Move result__no_operation(); // SET BREAKPOINT HERE// RS-232 loop //UCA0TXBUF = temp; // send lower part__no_operation();//while(!(IFG2 & UCA0TXIFG))//{//_delay_cycles(1000); // wait for first transmit//}UCA0TXBUF = temp >> 8;// send upper part__no_operation();// _delay_cycles(1000);//UCA0TXBUF = temp;}}
Have you given up trying to do this "manually", then?
Preston Lortieit would not print serially to PUTTY
So you've switched from Hyperterminal - are you sure that you have PUTTY correctly configured?
Preston Lortiedo I have to do anything special to get the printf command to work?
do I have to do anything special to get the printf command to work?
Note that printf() is a library function - not a "command".
The thing with printf() is - where does the output go? The standard 'C' library defines it to go to stdout; on a PC, that is "the console" - but what does that mean on a microcontroller?
You need to check your CCS documentation to see whether there is a default, and/or whether you have to provide some "driver" for it...
Alternatively, you could just use sprintf() to put the output into a buffer, and then send that buffer "manually"...
This Wiki page contains a link to the MSP430 Compiler Manual:
http://processors.wiki.ti.com/index.php/Printf_support_in_compiler
Preston LortieIE2 |= UCA0TXIE + UCA0RXIE; // enable RXD and TXD interrupt;
Hi Preston, first don't enable interrupt if no service routine are in place, this can generate program restart you cannot explain why.
Preston LortieUCA0TXBUF = temp; // send lower part__no_operation();//while(!(IFG2 & UCA0TXIFG))//{//_delay_cycles(1000); // wait for first transmit//}UCA0TXBUF = temp >> 8;// send upper part__no_operation();// _delay_cycles(1000);//UCA0TXBUF = temp;
Don't try this way build some libraries instead:
void Putch(unsigned char ch) { while (!(IFG2&UCA0TXIFG)) // USCI_A0 TX buffer ready? __no_operation(); UCA0TXBUF = ch; // TX -> character }
void PutStr (const char * ch) { while (*ch) Putch(*ch++); }after that use sprintf and pass the buffer string to PutStr
The putch routine is the basic of printf usage but use a smarter way writing some code to output:
char mybuffer[40];
sprintf(mybuffer,"hello world 0x%x\n",temp);
PutStr(mybuffer);
Regards
Roberto
Please login & click Verify Answer if this post answered your question.
While printf is convenient, it is also slow, requires lots of stack space and significantly raises the size of the binary.
Speed is an issue if you try to send the result form within an ISR. Don't do this. You'll run into timing problems rather sooner than later.Stack usage is an issue on MSPs with low ram. Like the G series. Or the 1232.High size is a problem not only on MSPs with small flash, but even on bigger ones, it can make the generated binary larger than the allowed size for the free compiler versions. And paying several hundred bucks for a full compiler license jsut to use printf...
However, a fast and cheap version can be implemented easily (and there is some code already posted in an older thread):
Count, how often you can subtract 10.000 from the value before it becoems <10000. Do NOT use "/" as divisions are slooow (this also applies to "%"). Do really a loopfor (count='0'; value>10000; count++, value-=10000);
The '0' is not a typo! After the loop, count will directly hold the ASCII letter representing the 10k's and can be directly sent to HyperTerm.
Then repeat for 1000, 100, 10. Finally, add '0' to the remaining value for the last digit. You'll get a 5 digit decimal number with leading zeroes. Fast and small and no stack usage.You can turn it into a function by passing the 'digit' value. A bit slower then, requires a bit stack, but even smaller code :) And can be used for ASCII conversions of octals or even binary numbers too :)
_____________________________________Before posting bug reports or ask for help, do at least quick scan over this article. It applies to any kind of problem reporting. On any forum. And/or look here.If you cannot discuss your problem in the public, feel free to start a private conversation: click on my name and then 'start conversation'. But please do so only if you really cannot do it in a public thread, as I usually read all threads. And I prefer to answer where others can profit from it (or contribute to it) too.
How about this
static const char hex_string[] = "0123456789ABCDEF";
void
print_hex(uint8_t c){char output_short[] = {"XX"};output_short[0] = hex_string[(c >> 4) & 0x0F];output_short[1] = hex_string[ c & 0x0F];TXString(output_short, 2 /* sizeof(output_short) */ );}
Bruce Mitchellprint_hex(uint8_t c){char output_short[] = {"XX"};
Hi this part generate string on stack so time and space are wasted out...
May be better to direct transfer character calling two time the txstring:
print_hex(uint8_t c){TXString(hex_string[(c >> 4) & 0x0F],1);TXString(hex_string[ c & 0x0F],1);}
//Also consider to convert bin to HEX by function:
char bin2hexdigit(char c)
{
c&=0x0f; // 4 bit
if(c>9) c+=('A'-'0'-10); // ASCII offset from number to capital letters
// if(c>9) c+=('a'-'0'-10); // ASCII offset from number to small letters
return(c+'0'); // Add character offset to binary value
}
The value ('A'-'0'-10) evaluate to 7 and is the difference to add to character '0' to obtain the character 'A' when binary value is 10, compiler calculate this value but I used this form for clarity.
also the difference between small and capital is 32 so to convert to hex with small letter need add 39 -> ('a'-'0'-10) instead of 7
Hi Roberto
I think use sprintf will increase more memory size
You can try use a sub-function like this...
//in while loop
TX_Byte((uint8_t)uartBuffer[0]); //Byte0, Carriage return uartBuffer[0] = 0x0D;
//HexToASCII
void TX_Byte (uint8_t TX_DATA){ while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = (unsigned char *)TX_DATA; // TX_DATA}
Best Regards,