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文字を signed に変換してからunsigned として出力するため、おそらく問題があることはわかっていuint8_tます。しかし、それらを無署名形式で出力する必要があります。int32_t入力整数を ASCII 文字列に変換する方法がわかりませんuint8_t

4

1 に答える 1

6

あなたのアーキテクチャでintは、 は であり、 ではint16_tありませんint32_t。したがって、としてitoa扱います。理由は次のとおりです。123456-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);
  ...
}

プラットフォームに がない場合に限り、2 番目の引数 ( )snprintfを使用および削除できます。あなたの頼りになる機能は、あなたの足を撃つための弾丸を1つ減らすので、常にバリアントでなければなりません:)sprintfsizeof(str)n

C++コンパイラでコンパイルしているので、少なくとも半分まともだと思いますが、上記は不要なコードをすべて発行することなく、移植可能な方法で「正しいこと」を行うはずです。に渡されるテスト条件は、ifコンパイル時の定数式です。一部のかなり古い C コンパイラでさえ、このような問題を適切に処理できます。

要点: int8_ta が使用される場所では使用しないでcharください。itoa、などは、バッファーではなくバッファーをs[n]printf想定しています。charint8_t

于 2016-01-13T15:48:40.607 に答える