Hallo miteinander,
ich bin gerade dabei eine 4x4 Tastenmatrix mit Hilfe eines Mega328
auszuwerten.
Meine Schaltung sieht folgendermaßen aus:
1 | PD5 PD4 PD3 PD2
|
2 | | | | |
|
3 | | | | |
|
4 | PB1----a-----b-----c-----d
|
5 | | | | |
|
6 | PB0----e-----f-----g-----h
|
7 | | | | |
|
8 | PD7----i-----j-----k-----l
|
9 | | | | |
|
10 | PD6----m-----n-----o-----p
|
Dabei werden PD5 - PD2 als Eingang mit aktivem Pullup und PB1, PB0, PD7
und PD6 mit hochomig initialisiert.
Dann multiplexe ich die Reihen in einem Timerinterrupt alle 10 ms und
lese dabei PD5 - PD2 aus.
Nun hab ich folgendes Problem, dass wenn ich die Taste a drücke, erkennt
er einen Tastendruck auf a und e. Drücke ich Taste e, dann erkennt er
einen Tastendruck auf e und i. Drücke ich jedoch eine beliebige andere
Taste (außer a und e), so erkennt er korrekt nur eine Taste.
Mein Code:
Init:
1 | // Ausgangspins fuer Tastenmatrix setzen
|
2 | // Reihen auf Eingang ohne Pullup
|
3 | DDRB &= ~(1 << 1);
|
4 | DDRB &= ~(1 << 0);
|
5 | DDRD &= ~(1 << 7);
|
6 | DDRD &= ~(1 << 6);
|
7 | // Spalten auf Eingang mit Pullup
|
8 | DDRD &= ~(1 << 5);
|
9 | DDRD &= ~(1 << 4);
|
10 | DDRD &= ~(1 << 3);
|
11 | DDRD &= ~(1 << 2);
|
12 | PORTD |= (1 << 5);
|
13 | PORTD |= (1 << 4);
|
14 | PORTD |= (1 << 3);
|
15 | PORTD |= (1 << 2);
|
ISR:
1 | ISR(TIMER1_COMPA_vect)
|
2 | {
|
3 | DDRD &= ~((1 << 7) | (1 << 6));
|
4 | PORTD &= ~((1 << 7) | (1 << 6));
|
5 | DDRB &= ~((1 << 1) | (1 << 0));
|
6 | PORTB &= ~((1 << 1) | (1 << 0));
|
7 | switch (btn_row)
|
8 | {
|
9 | case 0:
|
10 | DDRB |= (1 << 1);
|
11 | PORTB &= ~(1 << 1);
|
12 | break;
|
13 | case 1:
|
14 | DDRB |= (1 << 0);
|
15 | PORTB &= ~(1 << 0);
|
16 | break;
|
17 | case 2:
|
18 | DDRD |= (1 << 7);
|
19 | PORTD &= ~(1 << 7);
|
20 | break;
|
21 | case 3:
|
22 | DDRD |= (1 << 6);
|
23 | PORTD &= ~(1 << 6);
|
24 | break;
|
25 | }
|
26 | btns[btn_row][0] = (!(PIND & (1 << 5))) ? 1 : 0;
|
27 | btns[btn_row][1] = (!(PIND & (1 << 4))) ? 1 : 0;
|
28 | btns[btn_row][2] = (!(PIND & (1 << 3))) ? 1 : 0;
|
29 | btns[btn_row][3] = (!(PIND & (1 << 2))) ? 1 : 0;
|
30 | btn_row++;
|
31 | if (btn_row >= 4) {btn_row = 0;};
|
32 | }
|
Vielleicht kann mir jemand auf die Sprünge helfen. Danke im vorraus.