2014-10-04 67 views
0

努力学习一些低级AVR-C,我试图学习如何驱动2个7段显示器和2个引脚,并从7个引脚供电(在理论)。两个显示器的所有七段都由相同的端口(PortC)驱动。驱动器2 7段显示器有一个寄存器

我使用this tutorial作为指导。我的版本在学习过程中要简单得多。我附上了粗略的示意图(请给我!)和我的代码。

根据我的显示器接线方式,即第1段和第2段上的共阴极连接到PIN码A0和A1(PC0/PC1)。当这些PINS变低时,电路完成并且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

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

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

复用两个公共阴极显示设备的硬件必须是这样的:

  • 连接对应的段(即AG)一起
  • 它们连接到7行寄存器/端口的要使用
  • 使用两条线,每条阴极各一条。

为了正确,您应该使用电阻器限制每个段中的电流,但对于实验而言,您可以避开处理器的内部限制。

然后,软件应该这样做:

初始化:

  • 集合中的所有使用位(段和阴极),以1
  • 设定的所有端口为输出

环路:

  • 设置要在显示器1点亮以1
  • 设置位显示1至低(显示屏应显示数)
  • 等待了一下位,说10ms的
  • 切换显示的位1到高(关)

  • 设置要在显示器2的光,以1

  • 为显示器2的位设置为低的位(显示应显示数)
  • 等待位,比如10ms
  • 将显示器2的位切换为高(关)

  • 转至循环。

+0

谢谢 - 请参阅我的编辑。我尝试了你的建议。我快到了。第一位数字显示一个数字,但闪烁。如何防止闪烁的号码? – PhillyNJ 2014-10-04 22:26:13

+0

明显闪烁意味着你的程序中有一些东西慢到足以引起它。你在调用正确的延迟例程吗?第二个数字是否出现(可能是数字闪烁,因为第二个数字没有出现)?请注意,在2次10ms(即每秒50次)时,应该显示很少的闪烁。 – jcoppens 2014-10-05 17:31:21