0

我目前正在做一项任务,该任务使用微控制器和电路通过 LED 显示二进制十进制。我必须使用三个按钮:一个用于递增,一个用于递减,最后一个用于重置。我的接线和配置已完成。另一方面,我的代码有一些小故障,我无法通过仅介绍 C 类来解决这些小故障。我正在使用代码编辑器。问题一:我在“十位”部分(MSB)上的计数器不会停在 9,而是开始显示二进制 10-15。前四位是个位(右),后四位是十位(左),例如:1010 0001但最大值是1001 1001. 问题二:如果我从零开始递减值,计数器显示 95 而不是 99。例如:从0000 0000递减开始显示1001 0101. 我尝试使用 if 语句为 MSB 设置条件,如果大于 10 则停止但代码不运行。我对代码所做的几乎所有修改都会阻止它正常工作。

#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--){
    }
}
}
4

5 回答 5

1

为什么你看到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 语言不提供。

于 2016-02-12T20:33:37.797 回答
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
于 2016-02-12T19:30:15.507 回答
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;
}
于 2016-02-12T19:27:32.947 回答
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--){
    }
}
}
于 2016-02-15T14:32:12.577 回答
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);
}
于 2016-02-12T19:11:46.983 回答