Я пытаюсь отобразить целое число на ЖК-дисплее. Lcd работает так, что вы отправляете ему 8-битный ASCII-символ, и он отображает этот символ.
Код, который у меня пока есть:
unsigned char text[17] = "ABCDEFGHIJKLMNOP";
int32_t n = 123456;
lcd.printInteger(text, n);
//-----------------------------------------
void LCD::printInteger(unsigned char headLine[17], int32_t number)
{
//......int8_t str[17];
itoa(number,(char*)str,10);for(int i = 0; i < 16; i++)
{
if(str[i] == 0x0)
break;
this->sendCharacter(str[i]);
_delay_ms(2);
}
}
void LCD::sendCharacter(uint8_t character)
{
//....
*this->cOutputPort = character;
//...
}
Так что, если я пытаюсь отобразить 123456
на ЖК-дисплее, это на самом деле отображает -7616
что, очевидно, не является правильным целым числом.
Я знаю, что, вероятно, есть проблема, потому что я конвертирую символы в подписанные int8_t
а затем вывести их как неподписанные uint8_t
, Но я должен вывести их в неподписанном формате. Я не знаю, как я могу преобразовать int32_t
входное целое число в ASCII uint8_t
-String.
На вашей архитектуре, int
является int16_t
не int32_t
, Таким образом, itoa
лечит 123456
как -7616
, так как:
123456 = 0x0001_E240
-7616 = 0xFFFF_E240
Они одинаковы, если вы урезаете их до 16 бит — вот что делает ваш код. Вместо того, чтобы использовать itoa
, у вас есть следующие варианты:
ltoa(long value, char * buffer, int radix)
, если доступно, илиs[n]printf
если доступно.Для последнего варианта вы можете использовать следующий «в основном» переносимый код:
void LCD::printInteger(unsigned char headLine[17], int32_t number) {
...
char str[17];
if (sizeof(int) == sizeof(int32_t))
snprintf(str, sizeof(str), "%d", num);
else if (sizeof(long int) == sizeof(int32_t))
snprintf(str, sizeof(str), "%ld", num);
else if (sizeof(long long int) == sizeof(int32_t))
snprintf(str, sizeof(str), "%lld", num);
...
}
Если и только если ваша платформа не имеет snprintf
, ты можешь использовать sprintf
и убрать 2-й аргумент (sizeof(str)
). Ваша функция всегда должна быть n
вариант, так как дает вам на одну пулю меньше, чтобы выстрелить вам в ногу 🙂
Так как вы компилируете с помощью компилятора C ++, который, я полагаю, по крайней мере наполовину приличный, вышеприведенное должно делать «правильные вещи» переносимым способом, не вынимая весь ненужный код. Условия испытаний переданы if
являются константными выражениями времени компиляции. Даже некоторые довольно старые C-компиляторы могут справиться с этим должным образом.
Nitpick: не использовать int8_t
где char
сделал бы. itoa
, s[n]printf
и т.д. ожидаем char
буферы, а не int8_t
буферы.
Других решений пока нет …