ATMega644 mit 7-Segmentanzeigen

OP #3658721
Lesenswert?

Hallo Zusammenen,

ich möchte eine ATMega644 mit drei 7-Segmentanzeigen und einem/zwei
Schalter betreiben.
Irgendwie ist der Wurm in der Programmierung und ich sehen den Wald
vor Bäumen nicht.

Hier der Code:
1
//#########################################################
2
// Steuerung ATMega644 mit 16 MHz + drei 7-Segmentanzeigen
3
//#########################################################
4
#include <avr/io.h>
5
#include <avr/iom644.h>
6
#include <avr/interrupt.h>
7

8

9
//#########################################################
10
// Rahmenbedingungen
11
//#########################################################
12

13
// Counter
14
uint8_t muxflag;
15
uint8_t e, z, h;
16

17

18
//#########################################################
19
//Segmente für die Zahlenwerte Port A
20
//#########################################################
21

22
uint8_t num[] =
23
{
24
  0b01101111 ,   // 0
25
  0b00100100 ,   // 1
26
  0b01110011 ,   // 2
27
  0b01110110 ,   // 3
28
  0b00111110 ,   // 4
29
  0b01011110 ,   // 5
30
  0b01011111 ,   // 6
31
  0b01100100 ,   // 7
32
  0b01111111 ,   // 8 max LED-Anzahl
33
  0b01111110     // 9
34
};
35

36

37

38
//#########################################################
39
// Timer0 für Displayrefresh
40
void counter_init(void)
41
//#########################################################
42
{
43
  TCCR0B |= (1<<CS02) ; // Prescaler = FCPU/256  = 62500  Hz -> 81.38  Hz pro Segment
44
  TIMSK0 |= (1<<TOIE0) ; //  Overflow Interrupt Enable
45
  TCNT0=0 ;  // Init Counter - Zähler auf 0 setzen
46
}
47

48

49

50
//#########################################################
51
// ISR für Timer0
52
ISR(TIMER0_OVF_vect)
53
//#########################################################
54
{
55
  
56
  // Alle Segmente aus
57
  PORTC &= ~(1<<PC3);
58
  PORTC &= ~(1<<PC4);
59
  PORTC &= ~(1<<PC5);
60

61
  if(muxflag==0)
62
  {
63
  PORTA = num[h];
64
  PORTC |= (1<<PC3);
65
  }
66

67
  if(muxflag==1)
68
  {
69
  PORTA = num[z];
70
  PORTC |= (1<<PC4);
71
  }
72

73
  if(muxflag==2)
74
  {
75
  PORTA = num[e];
76
  PORTC |= (1<<PC5);
77
  
78
  muxflag=0;
79
  }
80
   else
81
  {
82
  muxflag = muxflag + 1;
83
  }
84
    
85
}
86

87

88
//#########################################################
89
/* Hauptprogramm */
90
int main(void)
91
//#########################################################
92
{
93

94
// Als Ausgänge und Eingänge sind Definiert:
95
DDRA = 0b11111111; // Counter-Anzeige
96
DDRB = 0b11111111;
97
DDRC = 0b00111000; // Segmente (PC3-PC5) 
98
DDRD = 0b10000000; // Tasterabfrage (PD2 & PD3)  
99

100
// Internal Pull-Up aktivieren
101
PORTD = 0b01111111;  // Taste PD2 & PD3
102
 
103

104
sei();          //enable interrupts
105

106

107
// Startwerte für 7-Segmente und Magazin
108
muxflag = 0;
109
h = 5; // 5-Hundert -> Zeigt 0 an
110
z = 0; // 0-Zehner
111
e = 0; // 0-Einer
112

113

114
counter_init(); // Timer0 ein
115

116

117
// Variantion 1
118

119
// while ( (PIND & (1<<PIND2))  ) ; // Taster an PB2 gedrückt?
120

121
// h = 4; // -> Zeigt 0 an. Wieso??
122

123
// while ( (PIND & (1<<PIND3))  ) ; // Taster an PB3 gedrückt?
124

125
// h = 6; // -> Zeigt 6 an oder jeden anderen gewählten Wert!
126

127

128
// Variantion 2
129

130
while ( (PIND & (1<<PIND3))  ) ; // Taster an PB3 gedrückt?
131

132
h = 4; // -> Zeigt 0 an. Wieso??
133

134
while ( (PIND & (1<<PIND2))  ) ; // Taster an PB2 gedrückt?
135

136
h = 7; // -> Zeigt 7 an oder jeden anderen gewählten Wert!
137

138

139
  
140
while(1); //Ende
141

142
}

Egal ob ich erst die Taste an PD2 und dann die Taste an PD3 drücke oder
umgekehrt, bis zum zweiten Tastendruck wird immer 000 angezeigt.

Keine Ahung. Irgendwie stehe ich auf dem Schlauch.
OP #3658749
Lesenswert?

MaWin schrieb:
> Du hast wohl noch nie was von der Notwendigkeit gehört, Taster zu
> entprellen.
>
> Auch ist ein Programm, welches nach dem zweiten prellen in einem
> while(1); für immer stoppt (RIP), etwas unbrauchbar.


Da dies ein Testprogramm ist, soll am Ende alles Stoppen.

Entprellen wird ein wenig überschätzt. Brauchte ich bisher nicht und ist 
hier auch nicht notwenig. Ob Variante 1 oder Variante 2 oder erstmal 
keine Taste, es wird immer 000 angezeigt.
OP #3659012
Lesenswert?

Ich habe die Lösung endlich gefunden. Es lag an den Rahmenbedingungen.
1
//###################################
2
// Rahmenbedingungen
3
//###################################
4

5
// Counter
6
volatile  uint8_t muxflag;
7
volatile  uint8_t h, z, e;

Da die Vaiablen h, z und e im Hauptprogramm geändert werden und diese 
Werte global gelten sollen, muss volatile verwendet werden.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren