zeke 693 Posted March 2, 2011 Share Posted March 2, 2011 If you need the printf() function and you have enough code space in your device then this routine will be your best bet, in my opinion. Help! CCS4.0 with MSP430F2252 has Trouble with 32 bit (Long) Data. For long term storage, this is the message that contains the code: Posted by Bin replied on 30 Dec 2009 1:55 PM Verified by Bin Verified Answer Prodigy80 Points Good inspiration. I casted all numbers with (long int) when calling printf() and it works! I think it is acceptable. A warning (is also an explanation) is written into the printf() comment section. See following source code. The printf() is ok to use now. Everyone is free to use and modify the source code below and I assume no responsibility. /*------------------------------------------------------------------- DESCRIPTION: Send one char in TX buffer, if it is not busy. Wait until not busy. INPUTS: One char. OUTPUTS: Send all the char in TX buffer. RETURNS: None. ---------------------------------------------------------------------*/ // Modify this routine so that it points to YOUR UART (zeke) void putChar(unsigned char byte) { while (!(IFG2 & UCA0TXIFG)); // USCI_A0 TX buffer ready? UCA0TXBUF = byte; // Load Tx register that clear UCA0TXIFG } /*------------------------------------------------------------------- DESCRIPTION: Move numbers of lines up in the HyperTerminal. INPUTS: None. OUTPUTS: Line up to TX buffer. RETURNS: None. ---------------------------------------------------------------------*/ void linesUp(unsigned char lines) { unsigned char i; for (i = 0; i < lines; ++i) { putChar(0x1b); putChar(0x5b); putChar(0x41); } } /*------------------------------------------------------------------- DESCRIPTION: Send out charater strings with defined width, justification and padding. Width = 0 or width < string length means unlimited width. Normal padding is space and left justification, but it can pad '0' or pad to the right side, depending on pad value. pad justification padding char bxxxxxx00 left ' ' bxxxxxx1x right ' ' or '0' bxxxxxxx1 left or right '0' INPUTS: Valid string and special charater in form of "\n" for example refered by pointer *string. Output field width. Justification and padding flag pad. OUTPUTS: Sent formated string to com port output. RETURNS: Total of chars sent. ---------------------------------------------------------------------*/ #define PAD_RIGHT 0x01 #define PAD_ZERO 0x02 int prints(char *string, unsigned char width, unsigned char pad) { int pc = 0; unsigned char padchar = ' '; // The pading char is space normally if (width > 0) // If output width is defined { unsigned char len = 0; char *ptr; for (ptr = string; *ptr; ++ptr) ++len; // Calculate string length and put it in len if (len >= width) width = 0; // If string is longer than width, then width is not applicable define as zero else width -= len; // Else redefine width as padding spaces if (pad & PAD_ZERO) padchar = '0'; // If padding char is zero, then get padchar as zero ready instead of original space } if (!(pad & PAD_RIGHT)) // If not right padding - left justification { for (; width > 0; --width) // If ther is padding width. Output padding char as '0' or ' '. { putChar (padchar); ++pc; } } for (; *string ; ++string) // Output the full string { putChar (*string); ++pc; } for (; width > 0; --width) { // Write padding char to the right if normal left justification putChar (padchar); ++pc; } return pc; // Return the output char number } /*------------------------------------------------------------------- * DESCRIPTION: Print 32 bit signed interger in dec or hex. In specific * width, padding and justification using prints(). Use 12 byte buffer * which is enough for 32 bit int. * INPUTS: Up to 32 byte signed interger i. Counting base: 10 or 16. * Sign flag sg. Output string width. padding and justification flag. * Leter base for number conversion. * OUTPUTS: Sent formated interger as string to com port output. * RETURNS: Total of chars sent. ---------------------------------------------------------------------*/ #define PRINT_BUF_LEN 12 int printi(long int i, unsigned char b, unsigned char sg, unsigned char width, unsigned char pad, unsigned char letbase) { char print_buf[PRINT_BUF_LEN]; // Interger as string array char *s; char neg = 0; unsigned long int t; unsigned long int u = i; int pc = 0; if (i == 0) // If output char is 0, then just output it with padding and width. { print_buf[0] = '0'; print_buf[1] = '\0'; // Always remenber to put string end return prints(print_buf, width, pad); //Print out zero and done. } if (sg && (b == 10) && (i < 0)) // If it is a negative int, then record the '-' and number as positive { neg = 1; u = -i; } s = print_buf + PRINT_BUF_LEN-1; // Point s to the end of the output buffer and put a null there. *s = '\0'; while (u) // Convert the positive int to string with whatever counting base, dec, or hex. { t = u % b; if( t >= 10 ) t += letbase - '0' - 10; *--s = t + '0'; u /= b; } if (neg) { // If it is a negative number if( width && (pad & PAD_ZERO) ) { // If there is width, right justified and pad with zero, output negative sign. putChar ('-'); ++pc; --width; } else *--s = '-'; // Otherwise put the '-' to string buffer. } return pc + prints (s, width, pad); // Output the string buffer and return the output counter. } /*------------------------------------------------------------------- * DESCRIPTION: short form of printf. Print argument strings with mixed * varables (string or interger)inside formated. * INPUTS: Argument string pointer. * OUTPUTS: print out the argument with style using prints() and printi(). * RETURNS: Total of chars sent. * Warning!!! varables and constant numbers even 0, must casted with * (long int)in printf(), if it is going to print out using * format "u", "d", "X" and "x"! Or the complier will assigned * 16-bit for data smaller than 16 bit and the argument pointer * will fetch a wrong 32-bit data and the argument point * increament will be in wrong size. * Limitations: 1) It treats all interger as 32 bit data only. * 2) No floating point data presentation. * 3) Has left/right alignment with 0 padding. * 4) Has format code "s", "d", "X", "x", "u" and "c" only. ---------------------------------------------------------------------*/ int printf(char *format, ...) { int width, pad; int pc = 0; char scr[2]; va_list args; va_start(args, format); for (; *format != 0; ++format) { if (*format == '%') { ++format; width = pad = 0; if (*format == '\0') break; if (*format == '%') goto out; if (*format == '-') { ++format; pad = PAD_RIGHT; } while (*format == '0') { ++format; pad |= PAD_ZERO; } for ( ; *format >= '0' && *format <= '9'; ++format) { width *= 10; width += *format - '0'; } if( *format == 's' ) { char *s = (char *)va_arg( args, int ); pc += prints (s?s:"(null)", width, pad); continue; } if( *format == 'd' ) { pc += printi (va_arg( args, long int ), 10, 1, width, pad, 'a'); continue; } if( *format == 'x' ) { pc += printi (va_arg( args, long int ), 16, 0, width, pad, 'a'); continue; } if( *format == 'X' ) { pc += printi (va_arg( args, long int ), 16, 0, width, pad, 'A'); continue; } if( *format == 'u' ) { pc += printi (va_arg( args, long int ), 10, 0, width, pad, 'a'); continue; } if( *format == 'c' ) { // char are converted to int then pushed on the stack scr[0] = (char)va_arg( args, int ); scr[1] = '\0'; pc += prints (scr, width, pad); continue; } } else { out: putChar(*format); ++pc; } } va_end( args ); return pc; } /* Test printf() below */ main { char *ptr = "Hello world!"; char *np = 0; long int i = 5; int bs = sizeof(long int)*8; // Bit to shift long int mi = ((long int)1 << (bs-1)) + 1; // Maximum negative number printf("%s\n", ptr); printf("printf test\n"); printf("%s is null pointer\n", np); printf("%d = 5\n", (long int)i); printf("%d = - max int\n", mi); printf("Long int 123456789 print out is %u", (long int)123456789); printf("\nmi in hex is %x\n", (long int)mi); printf("bs in dec is %u\n", (long int)bs); printf("char %c = 'a'\n", 'a'); printf("hex %x = ff\n", (long int)0xff); printf("hex %02x = 00\n", (long int)0); printf("signed %d = unsigned %u = hex %x\n", (long int)-32767, (long int)-32767, (long int)-32767); printf("signed %d = unsigned %u = hex %x\n", (long int)-3, (long int)-3, (long int)-3); printf("%d %s(s)%", (long int)0, "message"); printf("\n"); printf("%d %s(s) with %%\n", (long int)0, "message"); printf("justif: \"%-10s\"\n", "left"); printf("justif: \"%10s\"\n", "right"); printf(" 3: %04d zero padded\n", (long int)3); printf(" 3: %-4d left justif.\n", (long int)3); printf(" 3: %4d right justif.\n", (long int)3); printf("-3: %04d zero padded\n", (long int)-3); printf("-3: %-4d left justif.\n", (long int)-3); printf("-3: %4d right justif.\n\n\n", (long int)-3); } Result: Hello world! printf test (null) is null pointer 5 = 5 -2147483647 = - max int Long int 123456789 print out is 123456789 mi in hex is 80000001 bs in dec is 32 char a = 'a' hex ff = ff hex 00 = 00 signed -32767 = unsigned 4294934529 = hex ffff8001 signed -3 = unsigned 4294967293 = hex fffffffd 0 message(s) 0 message(s) with % justif: "left " justif: " right" 3: 0003 zero padded 3: 3 left justif. 3: 3 right justif. -3: -003 zero padded -3: -3 left justif. -3: -3 right justif. To use this code, modify the putChar() function so that it points to your UART. To verify it works, run the sample main() routine and compare the output to what is posted here. @Bin, wherever you are, Thank you! GeekDoc and bluehash 2 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.