This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
As a beginner, I am happy to be writing and running code for my MSP430G2553 launchpad to send and recieve characters over the UART using a FTDI USB-serial cable connected and running PUTTY terminal at 115200. I have gotten to the point of printing out a menu and interpreting character inputs, such as turning on and off the LED when I enter 'a'. I echo input characters and everything works great for simple control.
But now I am at a point where I would like to input and output integer values. Converting a series of UART digit input characters (e. g. 0123456789) by multiplying by the appropriate 10's place seems to be a doable algorithm for me to formulate in C. While the reverse, UART outputing a string of characters that represents an integer value is a more complicated task.
I know both these operations are likely done routinely in many applications, so my question is: Is there a standard C library function in Code Composer that can assist in this, or does everyone write their own basic C code for these conversions?
BJF
Braden Fessler said:I know both these operations are likely done routinely in many applications, so my question is: Is there a standard C library function in Code Composer that can assist in this, or does everyone write their own basic C code for these conversions?
BJF
You can write your own function.
The following is an integer to ASCII function that I stumbled upon, that you can include in your code.
This function is not included in standard C library.
void itoa(long unsigned int value, char* result, int base) { // check that the base if valid if (base < 2 || base > 36) { *result = '\0';} char* ptr = result, *ptr1 = result, tmp_char; int tmp_value; do { tmp_value = value; value /= base; *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)]; } while ( value ); // Apply negative sign if (tmp_value < 0) *ptr++ = '-'; *ptr-- = '\0'; while(ptr1 < ptr) { tmp_char = *ptr; *ptr--= *ptr1; *ptr1++ = tmp_char; } }
Thanks, I saw that code when reviewing various related posts. But it is to expert, too hard for me to understand. Don't know why the long string is there. Anyway, I went ahead and wrote my own, as you suggested, using my beginner-type coding, and it works good. Maybe this will be useful for someone in the early stages like myself. Hey, I finally contributed something to the Forum!
int string_to_int (char *std) //std is a pointer to a string
{
int aa; //length of string excluding trailing \0
int bb; //intermediate value
int cc = 0; //intermediate addend
int ee; //10s value for multiplier
aa = strlen(std); //returns
for (i = 0; i < aa; i++)
{
switch (i) //assumes string is 4 or less digits
{
case 3: {ee = 1000; break;}
case 2: {ee = 100; break;}
case 1: {ee = 10; break;}
case 0: {ee = 1; break;}
}
bb = transint(std[aa-1-i]) * ee;
cc = cc + bb;
}
return cc;
}
int transint(char c)
{
switch (c)
{
case '0': return 0;
case '1': return 1;
case '2': return 2;
case '3': return 3;
case '4': return 4;
case '5': return 5;
case '6': return 6;
case '7': return 7;
case '8': return 8;
case '9': return 9;
case '\r': return 10;
default: return -1;
}
}
The long string in that itoa() implementation is a lookup table the maps an integer digit to an ASCII character. It is one of more unusual implementations because that table handles digits from -35 to 35. That implementation is attributed to Lukas Chmela.
Your string_to_int() is essentially the same as the standard atoi() function. Going from string to integer is easier to code than integer to string. Here is an implementation of atoi. I have tried avoid pointers and the more compact C language constructs. It is limited to positive numbers. A full atoi() implementation would handle the '-' character.
int atoi(const char *s)
{
int a; // Accumulator
char c; // Current character
int d; // Current digit
int i; // Array index
i = 0; // Init array index
a = 0; // Init accumulator to zero.
c = s[i]; // Get first character
i++; //Advance the index
// Convert while not null terminator and is a numeric character
while((c!=0)&&(c>='0')&&(c<='9'))
{
d = c - '0'; // Convert character to digit
a = a * 10; // Make room for digit
a = a + d; // Add digit to accumulator
c = s[i]; // Get next character
i++; //Advance the index
}
return(a);
}
There are a lot of itoa() implementations out there.
http://www.jb.man.ac.uk/~slowe/cpp/itoa.html
The simple and straight forward implementations of itoa() use division and multiplication that on the MSP430 can be very slow. The repeated subtraction method is faster but the code can be difficult to understand.
Yes thank you Norman, I studied your code and it is very understandable. The subtraction of '0' to yield the integer value is now obvious to me, having reviewed the ascii table of character representations. Also, your shifting of the accumulator is much more efficient than the 'switch' statement I used. Finally, with these hints, I was able to understand the code with the lookup table.
I've tried incorporating this code into an MSP430FR4133 Launchpad. At first the code did not work at all ( mystery to me how you guys were able to get it to work ) until I was forced to do the following in main.c :
unsigned int aInt = 12345;
char* myString;
myString = (char *) malloc(10*sizeof(char));
memset(myString, 0, sizeof(myString));
itoa( aInt, myString, 10 );
So nothing worked ( myString was never set to anything ) until I did the memset/malloc stuff above. HOWEVER! The code STILL does not return the original int as a string ... something gets jumbled up.
For example, when I pass the values of aInt as below, I get the wrong string for myString but in a semi-predictable way, as follows:
aInt ---> myString
12345 ---> 12332
23456 ---> 23443
13579 ---> 13553
10101 ---> 10110
33333 ---> 33333
11111 ---> 11111
It is as if iota works correctly up until the center digit of aInt, and then makes a 180 and turns back around and starts going back up again toward the most significant digit. I cannot figure out the pointer arithmetic going on here in order to debug what is going on.
Anyone have a clue or advice?
**Attention** This is a public forum