在LCD屏幕上显示整数

3

我正在尝试在LCD显示屏上显示整数。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;

    //...

}

如果我试图在LCD上显示123456,实际上它会显示-7616,显然不是正确的整数。

我知道问题可能是因为我将字符转换为带符号的int8_t,然后以无符号的uint8_t输出它们。但我必须以无符号格式输出它们。我不知道如何将int32_t输入整数转换为ASCII uint8_t字符串。


你的 char* 是有符号的还是无符号的也是一个问题。你必须在 itoa 内部进行转换,这表明它是无符号的。 - SergeyA
真正的ASCII是七位,绝对包括数字——你选择如何解释最高有效位/符号位不应该有影响。因此,强制转换不应该成为问题。只是一种语法上的痛苦。 - Tommy
1个回答

6
在您的架构中,intint16_t 而不是 int32_t。因此,itoa123456 视为 -7616,原因如下:
123456 = 0x0001_E240
 -7616 = 0xFFFF_E240

如果将它们截断为16位,它们就相同 - 这就是您的代码所做的。 您可以选择以下选项而不是使用itoa

  1. 自己计算ASCII表示法;
  2. 如果可用,使用ltoa(long value, char * buffer, int radix);或者
  3. 如果可用,利用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并删除第二个参数(sizeof(str))。你应该总是使用n变体函数,因为它少了一个容易出错的地方 :)

由于您正在使用至少半过得去的C++编译器进行编译,以上代码应该以一种可移植的方式完成“正确的事情”,而不会发出所有不必要的代码。传递给if的测试条件是编译时常量表达式。甚至一些相当古老的C编译器也能正确处理这样的表达式。

小问题:在可以使用char的地方,请勿使用int8_titoas[n]printf等函数需要char缓冲区,而不是int8_t缓冲区。


3
请问我能借用你的水晶球吗? - SergeyA
他可能可以使用sprintf(或者最好是sprintf)和ll说明符,不过当然需要知道编译器是否将long long等同于32位。 - Tommy
1
你真的需要将你那个水晶球技术公开化...... - specializt
这是我首先想到的事情。我认为这代表了使用默认截断整数和编译器不警告此事的语言通常出现的问题。C语言可以强制执行显式缩小转换,但它没有这样做,这些错误就是结果。最糟糕的部分:这种行为使得默认类型如“int”几乎无用。可移植代码需要专门使用<stdint.h>中的整数类型(并在需要时使用char来调用库API)。 - Kuba hasn't forgotten Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接