Forum: Mikrocontroller und Digitale Elektronik 4x3 Keypad Matrix


von Florian (Gast)


Lesenswert?

Servus Leute,

Ich habe hier ein 4x3 Keypad mit
PA3:PA0 ^= Row    (OUT)
PA6:PA4 ^= Column (IN)
Externe Pullups an den Eingängen vorhanden.

Matrix:
1
    PA6  PA5  PA4
2
PA3  x    x    x
3
PA2  x    x    x
4
PA1  x    x    x
5
PA0  x    x    x
Ich setzte nach der Reihe die Reihen PA3 bis PA0 auf High und lese an 
PA6 bis PA4, ob der Taster gedruckt worden ist.

Aber irgendetwas scheine ich falsch zu machen.
Kann mir jemand sagen, wass ich da falsch mache, abgesehen vom return?
1
uint8_t key_check2(){
2
  uint8_t delay   = 100;
3
  uint8_t row    = 0;
4
  uint8_t col    = 0;
5
  //Ausgänge
6
  DDRA |= (1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3);
7
  
8
  //Eingänge
9
  DDRA &= ~(1<<PA4) & ~(1<<PA5) & ~(1<<PA6);
10
  
11
  for(uint8_t i=0;i<4;i++){
12
    
13
    if(i==0){
14
      PORTA |=  (1<<PA3);
15
      PORTA &= ~(1<<PA2) & ~(1<<PA1) & ~(1<<PA0);
16
      row = 1;
17
    }else if(i==1){
18
      PORTA |=  (1<<PA2);
19
      PORTA &= ~(1<<PA3) & ~(1<<PA1) & ~(1<<PA0);
20
      row = 2;
21
    }else if(i==3){
22
      PORTA |=  (1<<PA1);
23
      PORTA &= ~(1<<PA3) & ~(1<<PA2) & ~(1<<PA0);
24
      row = 3;
25
    }else if(i==3){
26
      PORTA |=  (1<<PA0);
27
      PORTA &= ~(1<<PA3) & ~(1<<PA2) & ~(1<<PA1);
28
      row = 4;
29
    }
30
    
31
    if(PINA & (1<<PA6)){
32
      _delay_ms(delay);
33
      col = 1;
34
    }else if(PINA & (1<<PA5)){
35
      _delay_ms(delay);
36
      col = 2;
37
    }else if(PINA & (1<<PA4)){
38
      _delay_ms(delay);
39
      col = 3;
40
    }
41
  }
42
  return (row*col);
43
}

Danke!

Florian

von Stefan F. (sfrings)


Lesenswert?

Funktionieren die Pull-Up WIderstände? Wenn sie zu hochohmig sind, wird 
es nicht klappen, denn du fragst die Eingänge ziemlich schnell nach dem 
Setzen der Ausgänge ab. Ich schätze 10k Ohm oder weniger sollten gehen.

Was passiert denn zur Zeit? Du hast geschrieben, dass es nicht 
funktioniert, aber nicht, wass denn stattdessen passiert.

von Stefan F. (sfrings)


Lesenswert?

Wenn Du mit Pull-Up Widerständen arbeitest, musst Du die Ausgänge auf 
LOW setzen und die Eingänge auf LOW prüfen. Dein Code funktioniert nur 
mit Pull-Down Widerständen.

Korrekturvorschlag:
1
uint8_t key_check2() {
2
  // Ein/Ausgänge konfigurieren
3
  DDRA = (1<<PA0) | (1<<PA1) | (1<<PA2) | (1<<PA3);
4
5
  // erste Reihe ansteuern
6
  PORTA = ~PA3;
7
8
  for (uint8_t row=1; row<5; row++) {
9
10
    // Rückgabewert entsprechend der gedrückten Spalte berechnen
11
    if (!(PINA & (1<<PA6))) {
12
      delay(100);
13
      result=1*row;
14
    }
15
    else if (!(PINA & (1<<PA5))) {
16
      delay(100);
17
      return 2*row;
18
    }
19
    else if (!(PINA & (1<<PA4))) {
20
      delay(100);
21
      return 3*row;
22
    }
23
24
    // nächste Reihe ansteuern
25
    PORTA = (PORTA>>1) | 128;
26
  } 
27
28
  // keine Taste gedrückt
29
  return 0;
30
}
Als Nebeneffekt aktiviert dieser Code die internen Pull-Up Widerstände. 
Ich hoffe, das stört Dich nicht. Wenn Du ein bisschen Zeit zwischen dem 
Setzen der Ausgänge und dem Lesen der Eingänge einfügst, kannst Du auf 
externe Pull-Up's verzichten:
1
  for (uint8_t row=1; row<5; row++) {
2
3
    // Ein bisschen Zeit verplempern
4
    (PINA); (PINA);
5
6
    // Rückgabewert entsprechend der gedrückten Spalte berechnen
7
    ...
8
  }
Diese beiden Lesezugriffe auf PINA werden vom Compiler nicht weg 
optimiert.

von Florian (Gast)


Lesenswert?

Servus Stefan,

danke für den Hinweis mit den Pullups!
Diesen blöden Fehler hab ich noch nie gemacht...

jetzt funktioniert der Code auch ;-)

Besten Gruß,
Florian

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.