Hallo,
ich hab ein problem mit einem atmega8.
kurz das setup:
4 kurzhubtaster hängen zwischen PD4, PD5, PD6, PD7 und masse. alle
schalter werden als input initialisiert und anschließend die pullup
widerstände eingeschaltet.
die eingaben werden mit einem timer softwareentprellt.
das ganze ist teil eines weckers.
das hat so bislang immer tadellos funktioniert.
gestern habe ich den controller neu programmiert, jedoch nur eine
marginale änderung am programm vorgenommen. Nach dem programmieren habe
ich die taster bedient um zeit und datum des weckers einzustellen. dabei
ist der controller "abstürzt". Abgestürzt bedeutet in diesem falle
plötzlich sind alle ausgänge auf high geschaltet worden und nichts ging
mehr.
controller neu gestartet und alles ist in ordnung - dachte ich.
jetzt zu meinem eigentlichen problem:
seit diesem zeitpunkt wird bei etwa jedem 20-30 tastendruck die funktion
eines anderen tasters ausgeführt. das passiert sogar wenn ein taster im
programm völlig auskommentiert wurde oder das alte programm aufgespielt
wurde.
alle anderen funktionen des weckers funktionieren wie vorher auch.
auffällug ist auch, dass wenn ein taster gedrückt gehalten wird der
controller sich lokal leicht erwärmt. nicht stark, aber so dass man es
mit der lippe deutlich fühlen kann.
die frage ist eigentlich garnicht ob der controller kaputt ist, sondern
eher warum. habe ich irgendwo einen groben fehler gemacht? könnte das
problem durch esd verursacht worden sein (die platine hat noch kein
richtiges gehäuse). aber wenn esd der grund ist, wieso dann nur die
eingänge an denen taster hängen und wieso alle vier??
hier noch die wichtigen code teile:
1 | #define BUTTON1 !(PIND & (1<<PD7))
|
2 | #define BUTTON2 !(PIND & (1<<PD6))
|
3 | #define BUTTON3 !(PIND & (1<<PD5))
|
4 | #define BUTTON4 !(PIND & (1<<PD4))
|
...
1 |
|
2 | DDRD |= (1<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4); // buttons as input
|
3 | PORTD |= (1<<PD7) | (1<<PD6) | (1<<PD5) | (1<<PD4); // enable pull-up resistors for buttons
|
4 |
|
5 | TCCR0 |= (1<<CS02) | (1<<CS00); // Timer0 prescaler 1024
|
6 | TIMSK |= (1 << TOIE0); // enable Timer0 overflow interrupt
|
7 |
|
8 | sei(); //enable Global Interrupts
|
...
1 | //Interrupt Service Routine for Timer0 overflow to debunce buttons
|
2 | ISR (TIMER0_OVF_vect)
|
3 | {
|
4 | // if any button pressed
|
5 | if ((g_btnDown == 1 && BUTTON1) || (g_btnDown == 2 && BUTTON2) || (g_btnDown == 3 && BUTTON3) || (g_btnDown == 4 && BUTTON4))
|
6 | {
|
7 | // if button was hold for X interrupts
|
8 | if ((g_btnDownCounter == 1) || (!(g_btnDownCounter % 4) && (g_btnDownCounter > 15)))
|
9 | {
|
10 | lcdLightOnTimed(); // turn on backlight
|
11 | if (g_btnDown == 1)
|
12 | {
|
13 | g_snoozeAlarmFlag = TRUE;
|
14 | }
|
15 | else if (g_btnDown == 2)
|
16 | {
|
17 | g_action1Flag = TRUE;
|
18 | }
|
19 | else if (g_btnDown == 3)
|
20 | {
|
21 | g_action2Flag = TRUE;
|
22 | }
|
23 | else if (g_btnDown == 4)
|
24 | {
|
25 | g_action3Flag = TRUE;
|
26 | }
|
27 | }
|
28 | g_btnDownCounter++;
|
29 | }
|
30 | else
|
31 | {
|
32 | g_btnDown = 0;
|
33 | g_btnDownCounter = 0;
|
34 |
|
35 | if (BUTTON1)
|
36 | {
|
37 | g_btnDown = 1;
|
38 | }
|
39 | else if (BUTTON2)
|
40 | {
|
41 | g_btnDown = 2;
|
42 | }
|
43 | else if (BUTTON3)
|
44 | {
|
45 | g_btnDown = 3;
|
46 | }
|
47 | else if (BUTTON4)
|
48 | {
|
49 | g_btnDown = 4;
|
50 | }
|
51 | }
|
52 | }
|
der interrupt wird alle 43ms ausgeführt. alle actions werden in der
main-loop ausgeführt.