I am writing to an LCD and have developed the drivers to accept a string input for the value. I have a variable called "cycles" that is a uint16. I need to convert that value to a string and write it to the display. My string write function prototype is as follows:
void lcd_string(uint8_t column, uint8_t page, const uint8_t *font_address, const char *str)
My way of displaying the value is to break the value into individual digits and write them individually to the display at the proper position.
I have the following code that works for what I want to do, but I would like to eliminate the long if/else if statement if possible.
loop = 0;
while (cycles_1 > 0) {
temp = cycles_1 % 10;
if (temp == 9) lcd_string(36 - (6 * loop),6,font_6x8_num,"9");
else if (temp == 8) lcd_string(36 - (6 * loop),6,font_6x8_num,"8");
else if (temp == 7) lcd_string(36 - (6 * loop),6,font_6x8_num,"7");
else if (temp == 6) lcd_string(36 - (6 * loop),6,font_6x8_num,"6");
else if (temp == 5) lcd_string(36 - (6 * loop),6,font_6x8_num,"5");
else if (temp == 4) lcd_string(36 - (6 * loop),6,font_6x8_num,"4");
else if (temp == 3) lcd_string(36 - (6 * loop),6,font_6x8_num,"3");
else if (temp == 2) lcd_string(36 - (6 * loop),6,font_6x8_num,"2");
else if (temp == 1) lcd_string(36 - (6 * loop),6,font_6x8_num,"1");
else if (temp == 0) lcd_string(36 - (6 * loop),6,font_6x8_num,"0");
cycles_1 /= 10;
loop ;
}
I tried the following but the string was not writing to the display.
loop = 0;
while (cycles_1 > 0) {
temp = cycles_1 % 10;
lcd_string(36 - (6 * loop),6,font_6x8_num,{0x30 temp, '\0'});
cycles_1 /= 10;
loop ;
}
I figured adding 0x30 to the temp value would convert it to an ASCII number and then I would terminate it with a null termination character, but this doesn't seem to be working. Any suggestions of what I might try?
CodePudding user response:
If you have a number named temp
between 0 and 9, you can convert it to a 1-character C string with a null terminator using this code:
char str[2] = { '0' temp };
There is no need to have a separate case for each digit.
CodePudding user response:
As you tagged the question [avr], you are using GNU tools for AVR, which use AVR-LibC as their libc implementation. It provides utoa
which converts an unsigned
(which is uint16_t
) to string. Notice that utoa
is non-standard.
#include <stdlib.h>
#include <stdint.h>
...
uint16_t cycles_1 = 12345;
char buf[6];
utoa (cycles_1, buf, 10);
lcd_string (..., buf, ...);
In case cycles_1
is a 16-bit signed type, there is itoa
.
utoa
and itoa
are implemented in assembly; they are fast and have a small foot-print. They don't use division or modulo.
If you really want to output each character individually, you can
char buf[2], var = 3;
buf[1] = '\0';
buf[0] = '1'; lcd_string (..., buf, ...);
buf[0] = '2'; lcd_string (..., buf, ...);
buf[0] = '0' var; lcd_string (..., buf, ...);
...
or, using it with your code:
uint8_t loop = 0;
while (cycles_1 > 0)
{
char temp = cycles_1 % 10;
char str[2] = { '0' temp, 0 };
lcd_string (36 - loop, 6, font_6x8_num, str);
cycles_1 /= 10;
loop = 6;
}
Notice however that this is slow and expensive, as it need division (and perhaps also modulo) for each digit.