【问题标题】:Displaying integer on an LCD在 LCD 上显示整数
【发布时间】:2016-01-13 15:44:52
【问题描述】:

我正在尝试在 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-String。

【问题讨论】:

  • 还有一个问题是您的 char* 被签名或未签名。您必须在 itoa 内部进行转换这一事实表明未签名。
  • 真正的 ASCII 是 7 位的,绝对包括数字——你选择如何解释最高有效位/符号位应该没有影响。所以演员阵容应该没有问题。只是语法上的痛苦。

标签: c++ string ascii uint8t


【解决方案1】:

在您的架构中,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 编译器也能很好地处理这种情况。

Nitpick:不要在 char 可以使用的地方使用 int8_titoas[n]printf 等期望 char 缓冲区,而不是 int8_t 缓冲区。

【讨论】:

  • 我可以借你的水晶球吗?
  • ...他不可能只使用sprintf(或者,理想情况下,snprintf)和ll 说明符吗?当然,在不知道编译器以及它是否等同于 long long 与 32 位的情况下。
  • 你真的需要公开你的水晶球技术......
  • 这是我首先想到的。我认为这代表了您使用默认截断整数的语言和不警告您这一事实的编译器时遇到的典型问题。 C 可以强制执行显式缩小强制转换,但它没有,结果就是这样的错误。最糟糕的部分:这种行为使int 等默认类型几乎毫无用处。可移植代码需要专门使用来自&lt;stdint.h&gt; 的整数类型(以及库 API 需要的 char)。
猜你喜欢
  • 2017-04-04
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多