使用一个寄存器驱动2个7段显示器

时间:2014-10-04 19:57:58

标签: c bit-manipulation avr

为了学习一些低级别的AVR-c,我试图学习如何从7个引脚(理论上)驱动2个7引脚显示器和2个引脚和电源。两个显示器的所有七个段都由相同的端口(PortC)驱动。

我使用this tutorial作为指南。我的版本对于学习练习来说简单得多。我附上了原始示意图(请给我!)和我的代码。

根据显示器的接线方式,即Segment1和Segment2上的公共阴极连接到PIN A0和A1(PC0 / PC1)。当这些PIN变低时,电路完成,LED亮起。

在本教程中,他们将每个段LED的阳极(A-G)串联连接,并使用6个引脚驱动7个显示器。在我的,我只有2个显示器。

我怎样才能做到这一点?

2-7 Segment Display

#include "avr/delay.h"

void setLedPorts (uint8_t dig);

void setup()
{
    Serial.begin(115200);
    DDRD |= 0b11111100;
    DDRB |= 0b00000011;
    DDRC |= 0b00000011; // Control port A0 / PC0 && A2 / PC1


}

void loop()
{
    uint8_t cmask = 0b11111100;
    while(1)
    {
        for(int i = 0; i < 100; i++){

            setLedPorts(i/10);
            PORTC = ~(0x01);

            //setLedPorts(i%10);// when I uncomment these to lines, Segment2 only works         
            //PORTC = ~(0x02);

            _delay_ms(100);
        }
    }
}


void setLedPorts (uint8_t dig){
    uint8_t dmask = 0b00000011;
    uint8_t bmask = 0b11111100;
    switch (dig)
    {

        case 0:

        PORTD = 0b10111100 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        case 1:
        PORTD = 0b00001000 & ~dmask;
        PORTB = 0b00000010 & ~bmask;
        break;
        case 2:
        PORTD = 0b11110000 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        case 3:
        PORTD = 0b1011000 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        case 4:
        PORTD = 0b01001100 & ~dmask;
        PORTB = 0b00000010 & ~bmask;
        break;
        case 5:
        PORTD = 0b11011100 & ~dmask;
        PORTB = 0b00000001 & ~bmask;
        break;
        case 6:
        PORTD = 0b11111100 & ~dmask;
        PORTB = 0b00000001 & ~bmask;
        break;
        case 7:
        PORTD = 0b10001000 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        case 8:
        PORTD = 0b11111100 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        case 9:
        PORTD = 0b11001100 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
        default:
        PORTD = 0b11111100 & ~dmask;
        PORTB = 0b00000011 & ~bmask;
        break;
    }

}

修改

我几乎得到了它。通过将while循环更改为:

for(int i = 0; i < 100; i++){
    setLedPorts(i/10);      
    PORTC = ~(0x01);                    
    _delay_ms(10);      
    setLedPorts(i%10);
    PORTC = ~(0x02); 
    _delay_ms(1000);
}

Segment1,显示第一个数字,但闪烁。我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

在尝试阅读图表和文本后,我有点困惑。不要试着看一下电路和/或程序的细节。你很快就会迷路。

如果您想查看所有可能的数字,则需要所有细分。这意味着7个段(如果你想要小数点也是8段),所以你需要一个端口的7(或8)位。然后是数字阴极的另外两个端口位。

要复用两个共阴极显示器,硬件必须如下:

  • 将相应的片段(即A-G)连接在一起
  • 将它们连接到您要使用的寄存器/端口的7行
  • 使用两条线,每条阴极一条线。

要正确,您应该使用电阻器限制每个段中的电流,但是对于实验,您可以摆脱处理器的内部限制。

然后,软件应该这样做:

初始化:

  • 将所有使用的位(段和阴极)设置为1
  • 将所有端口设置为输出

循环:

  • 在显示屏上设置要点亮的位1到1
  • 将显示1的位设置为低(显示屏应显示数字)
  • 等一下,比如10ms
  • 将显示1的位切换为高(关闭)

  • 在显示屏上设置要点亮的位2到1

  • 将显示器2的位设置为低(显示屏应显示数字)
  • 等一下,比如10ms
  • 将显示屏2的位切换为高电平(关闭)

  • 转到循环。