将十进制转换为BCD

时间:2016-02-12 18:57:46

标签: c msp430 code-composer

我目前正致力于使用微控制器和电路通过LED显示二进制十进制的分配。我必须使用三个按钮:一个增加,一个减少,最后一个重置。我完成了接线和配置。另一方面,我的代码有一些小问题,我无法修复,只有我的腰带上的C类介绍。我正在使用Code Composer。第一个问题:我的计数器在" Tens" section(MSB)不会在9处停止,而是开始显示二进制10-15。前四位是1(右)和后4位,数十(左)ex: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--){
    }
}
}

5 个答案:

答案 0 :(得分:1)

I don't have a strip of LEDs handy right now, but this shows how to work within a decimal range, but only convert at the point of output. The actual value is kept in the range 0..99 (note how the modulus is done when I decrement). Then you split the value into BCD nibbles, and combine them for output.

#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;
}

Program output

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

答案 1 :(得分:1)

Why you see 95?

As mentioned by @Olaf, msp430 uses 16bit integer.

When you do from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.platypus import Paragraph class MultiFontParagraph(Paragraph): # Created by B8Vrede for http://stackoverflow.com/questions/35172207/ def __init__(self, text, style, fonts_locations): font_list = [] for font_name, font_location in fonts_locations: # Load the font font = TTFont(font_name, font_location) # Get the char width of all known symbols font_widths = font.face.charWidths # Register the font to able it use pdfmetrics.registerFont(font) # Store the font and info in a list for lookup font_list.append((font_name, font_widths)) # Set up the string to hold the new text new_text = u'' # Loop through the string for char in text: # Loop through the fonts for font_name, font_widths in font_list: # Check whether this font know the width of the character # If so it has a Glyph for it so use it if ord(char) in font_widths: # Set the working font for the current character new_text += u'<font name="{}">{}</font>'.format(font_name, char) break Paragraph.__init__(self, new_text, style) , count acutally wraps to count = 0u -1;

65535

Why tens can to beyond 10

Same problem, because your input is greater than 99.

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
}

What you should do?

In your code, limit the range to 0-99, you have the choice of either wrap-around (99+1=0, and 0-1=99)or saturation (99+1=99, 0-1=0). But whatevenr you need, you need to write it yourself: C language does not provide it.

答案 2 :(得分: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);
}

答案 3 :(得分:0)

Let us keep count in 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

or use a BCD increment function

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;
}

答案 4 :(得分: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--){
    }
}
}