Forum: Mikrocontroller und Digitale Elektronik ATMega644 mit 7-Segmentanzeigen


von Axel L. (ligonap)


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.

von MaWin (Gast)


Lesenswert?

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.

von Axel L. (ligonap)


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.

von Axel L. (ligonap)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.