1

マイクロコントローラATmega16 から 7 セグメント ディスプレイへの入力を表示しようとしています。

http://www.avr-tutorials.com/projects/atmega16-based-digital-clockで次のコードを見つけましたが、実装しても機能しません。出力が変動します。つまり、特定のピンで出力を制御できません。 temp1 と temp2 の 2 つの入力があり、それぞれを 3 つの 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;
}}
4

2 に答える 2

0

DDRをどこにも出力するように設定しません。出力として使用するピンは、DDRx の対応するビットを 1 に設定する必要があります。それ以外の場合、入力ピンのままになります。

入力ピンは出力を示しますが、電流が少なくなり、エッジの立ち上がりが遅くなります。その電流を液晶で吸い込むと、電圧降下の原因となることがあります。

于 2015-06-02T16:14:44.120 に答える
0

これらの 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();

等々。

于 2015-06-02T11:00:09.217 に答える