4x3 Keypad Matrix

Gast #2780219
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
#2780225
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.
#2780251
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.

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