2016-01-13 86 views
3

我試圖在液晶顯示器上顯示一個整數。液晶顯示器的工作方式是將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_tString。

+0

還有一個你的char *被簽名或未簽名的問題。你必須在'itoa'內進行轉換的事實表明沒有簽名。 – SergeyA

+0

真正的ASCII碼是七位的,絕對包括數字 - 你如何選擇解釋最重要的/符號位應該沒有效果。所以演員不應該有問題。只是語法上的痛苦。 – Tommy

回答

6

在您的架構上,intint16_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); 
    ... 
} 

如果,且僅當您的平臺沒有snprintf,你可以使用sprintf和刪除第二個參數(sizeof(str))。你的前往功能應該始終是n變體,因爲它可以讓你的子彈擊中一腳:)

由於您使用的是C++編譯器,我假設它至少有一半體面,上面應該以便攜的方式做「正確的事情」,而不必發佈所有不必要的代碼。傳遞給if的測試條件是編譯時常量表達式。即使是一些相當老的C編譯器也可以正確處理。

Nitpick:不要使用int8_t其中char會做。 itoa,s[n]printf等期待char緩衝區,而不是int8_t緩衝區。

+3

我可以借用你的水晶球嗎? – SergeyA

+0

...他不可能只用'sprintf'(或者理想的'snprintf')和'll'說明符?在不知道編譯器的情況下,當然,它是否等同於32位長整數。 – Tommy

+1

@Tommy這是真正的問題,的確... –

相關問題