数字显示不正确,无法控制特定引脚的输出

Digits not displayed properly, Unable to control output at particular pin

我正在尝试将我的输入显示在微控制器 ATmega16 到 7 段显示器上。

我在 http://www.avr-tutorials.com/projects/atmega16-based-digital-clock 上找到了以下代码,但是当我实现它时,它不起作用。我得到一个 波动的输出 我无法控制特定引脚的输出。 我有两个输入 temp1 和 temp2,我想在三个 7 段显示器上显示它们中的每一个。另外,我没有使用引脚 2 和 3,因为它们是中断引脚,我在其他地方使用过它们。 Pin0,1,4,5,6,7 被使用。

添加一些延迟后代码工作正常,否则输出会在随机引脚生成。 即我想从 PIND1 显示的输出显示在所有引脚上,

我的代码:

    #include <avr/delay.h>
    #include <avr/io.h>
    #include <avr/interrupt.h>

    #define SegDataPort     PORTC
    #define SegDataPin      PINC
    #define SegDataDDR      DDRC

    #define SegCntrlPort    PORTD
    #define SegCntrlPin     PIND
    #define SegCntrlDDR     DDRD

/*
* Function Description:
* Encode a Decimal Digit 0-9 to its Seven Segment Equivalent.
*
* Function Arguments:
* digit - Decimal Digit to be Encoded
* common - Common Anode (0), Common Cathode(1)
* SegVal - Encoded Seven Segment Value 
*
* Connections:
* Encoded SegVal is return in the other G-F-E-D-C-B-A that is A is the least
* significant bit (bit 0) and G bit 6.
*/
unsigned char DigitTo7SegEncoder(int digit, unsigned char common)
{
    unsigned char SegVal;

    switch(digit)   
    {   
        case 0: if(common == 1) SegVal = 0b00111111;
                else            SegVal = ~0b00111111;
                break;
        case 1: if(common == 1) SegVal = 0b00000110;
                else            SegVal = ~0b00000110;
                break;
        case 2: if(common == 1) SegVal = 0b01011011;
                else            SegVal = ~0b01011011;
                break;
        case 3: if(common == 1) SegVal = 0b01001111;
                else            SegVal = ~0b01001111;
                break;
        case 4: if(common == 1) SegVal = 0b01100110;
                else            SegVal = ~0b01100110;
                break;
        case 5: if(common == 1) SegVal = 0b01101101;
                else            SegVal = ~0b01101101;
                break;
        case 6: if(common == 1) SegVal = 0b01111101;
                else            SegVal = ~0b01111101;
                break;
        case 7: if(common == 1) SegVal = 0b00000111;
                else            SegVal = ~0b00000111;
                break;
        case 8: if(common == 1) SegVal = 0b01111111;
                else            SegVal = ~0b01111111;
                break;
        case 9: if(common == 1) SegVal = 0b01101111;
                else            SegVal = ~0b01101111;       
    }       
    return SegVal;
}



int main(void)
{
int temp1,temp2;
//Suppose my input is 105 and 210, i.e. temp1=105 and temp2=210;
// it contains other information also, not required here
SegDataDDR = 0xFF;
SegCntrlDDR = 0xF3;
SegCntrlPort = 0xF3;
SegDataPort = 0x00;
  while(1){
            SegDataPort = DigitTo7SegEncoder(temp1%10,1);
        SegCntrlPort = ~0x01;
        SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1); 
        SegCntrlPort = ~0x02;
        SegDataPort = DigitTo7SegEncoder(temp1/100,1);
        SegCntrlPort = ~0x10;
        SegDataPort = DigitTo7SegEncoder(temp2%10,1); 
        SegCntrlPort = ~0x20;
        SegDataPort = DigitTo7SegEncoder((temp2/10)%10,1); 
        SegCntrlPort = ~0x40;
        SegDataPort = DigitTo7SegEncoder(temp2/100,1);
        SegCntrlPort = ~0x80;
}}

假设这些 7 段组件内部不包含任何时序逻辑,这就是实际发生的情况:

SegDataPort = DigitTo7SegEncoder(temp1%10,1);       // You write the data
SegCntrlPort = ~0x01;                               // You enable the first 7-segment component
// Then without any delay...
SegDataPort = DigitTo7SegEncoder((temp1/10)%10,1);  // You write other data
SegCntrlPort = ~0x02;                               // You enable the second component
// The without any delay...

所以实际上 7 段组件会在短时间内同时显示前后数字。

这个呢? (只是一个伪代码)

SegCntrlPort = 0xFF;   // hide everything

SetDataPort = ... value1 ...;
SegCntrlPort = ~0x01;   // show it
WaitForAWhile();

SegCntrlPort = 0xFF;   // hide everything to avoid unwanted transitions

SetDataPort = ... value2 ...;
SegCntrlPort = ~0x02;   // show it
WaitForAWhile();

以此类推

您没有将 DDR 设置为在任何地方输出。要用作输出的引脚必须将 DDRx 中的相应位设置为 1。否则它仍然是输入引脚。

输入引脚将显示输出,但电流较低且上升沿较慢。用 LCD 吸收该电流可能会导致电压下降。