2016-02-12 120 views
0

我正在處理當前使用微控制器和電路通過LED顯示二進制小數的分配。我必須使用三個按鈕:一個增加,一個減少,最後一個重置。我的佈線和配置已完成。另一方面,我的代碼有一些小故障,我不能用C語言簡介來解決這個問題。我正在使用Code Composer。問題一:我的「十幾」部分(MSB)的計數器不是停在9,而是開始顯示二進制10-15。前四位是(右)和後四位,十位(左)ex:1010 0001,但最大值是1001 1001。問題二:從零開始,如果我遞減數值,計數器顯示95而不是99. 例如:從0000 0000開始遞減顯示1001 0101。我嘗試使用if語句爲MSB停止,如果大於十,但代碼不運行的條件。幾乎對我的代碼做的任何修改都會阻止它正常工作。將十進制轉換爲BCD

#include <msp430.h> 

unsigned int dec2bcd(unsigned int num); 
void delay(void); 

int main(void) { 
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer 

P1DIR = 0xFF; 
P2DIR = 0xF0; 
unsigned int c; 
unsigned int count = 0x00; 

while(1){ 
    if((P2IN & BIT0) == BIT0){ 
     count++; 
     c = dec2bcd(count); 
    } 

    else if((P2IN&BIT1) == BIT1){ 
     count--; 
     c = dec2bcd(count); 
    } 

    else if((P2IN&BIT2) == BIT2){ 
     count = 0x00; 
     c = dec2bcd(count); 
    } 

    delay(); 
    P1OUT = c; 

} 

} 

unsigned int dec2bcd(unsigned int num) 
{ 
    unsigned int ones = 0; 
    unsigned int tens = 0; 
    unsigned int temp = 0; 

    ones = num%10; 
    temp = num/10; 
    tens = temp<<4; 
    return (tens + ones); 
} 

void delay(void) 
{ 
    volatile unsigned int i, j; 
    for(i=10000; i>0; i--) 
    { 
     for(j=3; j>0; j--){ 
    } 
} 
} 
+0

想一想。如果這個項目是增加和減少顯示器上的十進制數。如果增量後的變量大於9,則可以分別跟蹤每個數字,然後增加十個數字並使其爲零。一直把二進制分成十進制是一個很大的開銷,特別是對於一個msp430。 –

+0

如果你的約數是0,它將換算成最大的非零值int,但是你的dectobcd最多隻能處理99 – user3528438

+0

最大值是多少?顯示多少個BCD數字?可以增加溢出嗎?可以遞減下溢? – chux

回答

0

爲什麼你看到的95?

正如@Olaf所說,msp430使用16位整數。

當你做count = 0u -1時,算上包裝65535;

unsigned int dec2bcd(unsigned int num) // num is now 65535 
{ 
    unsigned int ones = 0; 
    unsigned int tens = 0; 
    unsigned int temp = 0; 

    ones = num%10; // 65535%10 = 5 
    temp = num/10; // 65535/10 = 6553 
    tens = temp<<4; // what's displayed is by tens is actually the lower 
        // 4 bits of tens, so tens is 6553%16=9 
    return (tens + ones);// so the result is 95 
} 

爲什麼幾十可以超越10

同樣的問題,因爲你的輸入大於99

unsigned int dec2bcd(unsigned int num) // say num is now 100 
{ 
    unsigned int ones = 0; 
    unsigned int tens = 0; 
    unsigned int temp = 0; 

    ones = num%10; // 100%10 = 0 
    temp = num/10; // 100/10 = 10, or 0x0A 
    tens = temp<<4; 
    return (tens + ones);// so the result is A0 
} 

你應該做些什麼?

在您的代碼中,將範圍限制爲0-99,您可以選擇環繞(99 + 1 = 0和0-1 = 99)或飽和度(99 + 1 = 99,0) -1 = 0)。但是你需要,你需要自己寫:C語言不提供它。

+0

這是非常有用的,因爲我知道必須有某種限制。我修改了當前的代碼dec2bcd'tens =(temp%10)<< 4;',它似乎解決了在「十」部分顯示大於9的任何東西的第一個問題。現在爲了環繞,使用if-else-if-loop與環繞條件是否明智? – MarineUTEP

+0

@MarineUTEP我認爲這是好的 – user3528438

+0

這是我的新代碼,使其正常工作的變化。 – MarineUTEP

0

是有使用這個任何約束:

if((P2IN & BIT0) == BIT0){ 
    count++; 
    if (count == 100) 
     count = 0; 
    c = dec2bcd(count); 
} 

else if((P2IN&BIT1) == BIT1){ 
    if (count == 0) 
     count = 100; 
    count--; 
    c = dec2bcd(count); 
} 
+0

首先,在msp430上調用/ 100非常慢,所以將它稱爲兩次是不明智的;其次,這個解決方案不能解決99/95問題。 – user3528438

+0

我認爲延遲函數的存在意味着有意施加放緩因素。但是如果這真的是個**問題,那麼賦值可以變成num =(num + 100k)%100;其中** 100k **是最大可能的乘數100. – AliVar

+0

那麼它溢出 – user3528438

0

讓我們保持計數countBDC。

unsigned countBCD = 0; 
unsigned count = 0; 
while(1){ 
    if((P2IN & BIT0) == BIT0){ 
     count++; 
     countBCD++; 
     if ((countBCD & 0xF) >= 0xA) { 
      // of course can combine these 2 lines 
      countBCD -= 0xA; 
      countBCD += 0x10; 
      if ((countBCD & 0xF0) >= 0xA0) { 
      countBCD -= 0xA0; 
      countBCD += 0x100; 
      ... 
    // similar code for decrement 

或使用BCD遞增函數

unsigned BCD_inc(unsigned x) { 
    unsigned carry = 1; 
    unsigned mask10 = 10; 
    unsigned maskNibble = 15; 
    while (carry) { 
    x += carry; 
    if ((x & maskNibble) >= mask10) { 
     x -= mask10; 
     mask10 <<= 4; 
     maskNibble <<= 4; 
     carry <<= 4; 
    } else { 
     carry = 0; 
    } 
    } 
    return x; 
} 
+0

使用'無符號變量'與'無符號整型變量'是否有顯着區別? – MarineUTEP

+1

它們是同義詞。 –

1

我沒有LED的得心應手條的權利,但這種說明如何將十進制範圍內工作,但只能在點轉換的輸出。實際值保持在0..99範圍內(請注意,當我遞減時模數是如何完成的)。然後,將值分成BCD半字節,並將它們組合起來輸出。

#include <stdio.h> 

void display(int num, char *msg) 
{ 
    int lsnib = num % 10;      // decimal value of each nibble 
    int msnib = num/10; 
    int ledpatt = (msnib << 4) + lsnib;   // recombine as BCD 
    printf("%02X Expected %s\n", ledpatt, msg); 
} 

int main(void){ 
    int value; 

    value = 42; 
    display (value, "forty two");  // display 42 

    value = 0; 
    display (value, "zero");   // display 0 

    value = 99; 
    display (value, "ninety nine");  // display 99 

    value = (value + 1) % 100;   // increment from 99 
    display (value, "zero");   // should display 0 

    value = (value -1 + 100) % 100;  // decrement from 0 
    display (value, "ninety nine");  // should display 99 

    return 0; 
} 

程序輸出

42 Expected forty two 
00 Expected zero 
99 Expected ninety nine 
00 Expected zero 
99 Expected ninety nine 
+0

這個回答犧牲了usnigned整數範圍的一半來處理0-1 = 99。 – user3528438

+0

@ user3528438我確定'0..99'是OP的範圍。你是否暗示我僅僅因爲'int'已經足夠了而使用'char'?或者當'int'足夠時,你認爲它應該是'unsigned int'。請解釋。 –

+0

在MSP430上使用模數進行換行是一個壞主意:速度太慢,代碼太多。更好的比較和設置。 – Olaf

0

下面是解決了我之前遇到的問題的新代碼。它可能不是最優的,但我設法使它工作。我添加了兩條創建環繞的if語句,並通過實現模數來修改dec2bcd轉換器。 「十」部分的模數有助於擺脫顯示問題。 謝謝你們幫助我!現在我明白我的語法錯誤,並感謝向我展示了我需要關注的更廣泛的範圍。祝我好運,我希望得到額外的信貸。直到下次。

#include <msp430g2553.h> 

unsigned int dec2bcd(unsigned int num); 
void delay(void); 

int main(void) { 
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer 

P1DIR = 0xFF; 
P2DIR = 0x00; 
unsigned int c; 
unsigned int count = 0x00; 

//Here are some modified portions to create wrap around 
while(1){ 
    if((P2IN & BIT0) == BIT0){ 
     count++; 
     if(count == (99+1)){ 
      count = 0x00; 
     } 
     c = dec2bcd(count); 
    } 

    else if((P2IN&BIT1) == BIT1){ 
     count--; 
     if(count == (0-1)){ 
      count = 0x63; 
     } 
     c = dec2bcd(count); 
    } 

    else if((P2IN&BIT2) == BIT2){ 
     count = 0x00; 
     c = dec2bcd(count); 
    } 
    delay(); 
    P1OUT = c; 

} 

} 

unsigned int dec2bcd(unsigned int num) 
{ 
    unsigned int ones = 0; 
    unsigned int tens = 0; 
    unsigned int temp = 0; 

    ones = num%10; 
    temp = num/10; 
    //I used modulus here to get rid of the improper display issue 
    tens = (temp%10)<<4; 
    return (tens + ones); 
} 

void delay(void) 
{ 
    volatile unsigned int i, j; 
    for(i=10000; i>0; i--) 
    { 
     for(j=3; j>0; j--){ 
    } 
} 
} 
相關問題