Forum: Mikrocontroller und Digitale Elektronik Keypad - Interrupt


von Rico H. (Firma: FHNW) (2she)


Lesenswert?

Hallo Liebe Leute

ich stehe vor einem kleineren Problem.

Und zwar hab ich ein Displaymodul inklusive Folientastatur 
(Matrix-Ansteuerung) von Display-3000. Ich hab mich dafür entschieden, 
die Kolonnen der Tastaturmatrix auf Interruptleitungen zu ziehen (es 
waren ein,zwei zusätzliche Leitungen auf dem Board notwendig).
Die Interrupts funktionieren einwandfrei. Das Problem ist es jedoch in 
der Interruptroutine die Zeile, d.h. die richtige Taste auszulesen.

Die Interruptroutine sieht zur Zeit folgendermassen aus:
1
ISR(INT5_vect)
2
{
3
  key_press();
4
5
}

Im Unterprogramm key_press() wird eine case abfrage der gedrückten Taste 
gemacht, was normalerweise auch funktioniert hat. Ich nehme an, dass das 
Problem darin liegt, dass dieses Unterprogramm nur gerade einmal 
durchlaufen wird und die Taste nicht richtig erkannt wird...

Habt Ihr mir irgendwelche Vorschläge?
Besten Dank schon im Vorraus

von 4toTakoe (Gast)


Lesenswert?

Rico H. schrieb:
> key_press()

zeigen.

von Karol B. (johnpatcher)


Lesenswert?

Ich kenne die Charakteristik von Folientastaturen nicht, aber im 
Allgemeinen ist es immer ein schlechter Ansatz Taster und ähnliches 
direkt per Interrupt auszuwerten, da diese dazu tendieren zu "prellen", 
siehe [1].

Bemühe einfach mal die Suchmachine deiner Wahl (z.B. [2]), um dir 
anzusehen wie es andere gelöst haben. Du bist nicht der erste der eine 
Matrixtastatur per Mikrocontroller auswerten möchte ;).

[1]: https://www.mikrocontroller.net/articles/Entprellung
[2]: 
https://www.google.de/webhp?q=matrix+tastatur+site:mikrocontroller.net

von Peter D. (peda)


Lesenswert?

Es stimmt schon, daß man für Tasten einlesen/entprellen einen Interrupt 
benötigt. Es ist allerdings der Timerinterrupt.

von Rico H. (Firma: FHNW) (2she)


Lesenswert?

4toTakoe schrieb:
> Rico H. schrieb:
>> key_press()
>
> zeigen.
1
  void Init_Key_Port()
2
  {
3
    /* All Ports input of the matrix keyboard */
4
    DDRE = ( (0<<DDE7) | (0<<DDE6) | (0<<DDE5) | (0<<DDE4));
5
    DDRD = ( (0<<DDD7) | (0<<DDD4) );
6
    DDRG = ( (0<<DDG3) | (0<<DDG0) );
7
    /* Pullup resistance active for keyboard ports*/
8
    PORTE = ( (1<<PE7) | (1<<PE6) | (1<<PE5) | (1<<PE4));
9
    PORTD = ( (1<<PD7) | (1<<PD4) );
10
    PORTG = ( (1<<PG3) | (1<<PG0) );
11
  }
12
13
  char key_press(int pos, int site)
14
  {
15
    cli();
16
    char number=0;
17
    int keycode, keyflag = 4;
18
    Init_Key_Port();                  // make sure all keyboard ports are initialized
19
20
    /* check line D */
21
    PORTD = (0<<PD4);                   // PORT D4 at pullup desactive
22
    DDRD = (1<<DDD4);                   // PORT D4 in input
23
    keycode = 0x08 &0x0F;                // line code
24
    /* check column */
25
    if ((PINE &(1<<PINE7)) == 0) ;            // faking condition
26
    else if ((PINE &(1<<PINE5)) == 0) keycode += 0x10 &0xF0;
27
    else if ((PINE &(1<<PINE4)) == 0) keycode += 0x20 &0xF0;
28
    else if ((PINE &(1<<PINE6)) == 0) keycode += 0x40 &0xF0;
29
    else keyflag --;
30
    PORTD = (1<<PD4);                   // PORT D4 at pullup active
31
    DDRD = (0<<DDD4);                   // PORT D4 in output
32
33
    if (keyflag == 3)
34
    {
35
      /* check line C */
36
      PORTD = (0<<PD7);                 // PORT D7 at pullup desactive
37
      DDRD = (1<<DDD7);                 // PORT D7 in input
38
      keycode = 0x04 &0x0F;              // line code
39
      /* check column */
40
      if ((PINE &(1<<PINE7)) == 0) ;          // faking condition
41
      else if ((PINE &(1<<PINE5)) == 0) keycode += 0x10 &0xF0;
42
      else if ((PINE &(1<<PINE4)) == 0) keycode += 0x20 &0xF0;
43
      else if ((PINE &(1<<PINE6)) == 0) keycode += 0x40 &0xF0;
44
      else keyflag --;
45
      PORTD = (1<<PD7);                 // PORT D7 at pullup active
46
      DDRD = (0<<DDD7);                 // PORT D7 in output
47
    }
48
49
    if (keyflag == 2)
50
    {
51
      /* check line B */
52
      PORTG = (0<<PG0);                 // PORT G0 at pullup desactive
53
      DDRG = (1<<DDG0);                 // PORT G0 in input
54
      keycode = 0x02 &0x0F;              // line code
55
      /* check column */
56
      if ((PINE &(1<<PINE7)) == 0) ;          // faking condition
57
      else if ((PINE &(1<<PINE5)) == 0) keycode += 0x10 &0xF0;
58
      else if ((PINE &(1<<PINE4)) == 0) keycode += 0x20 &0xF0;
59
      else if ((PINE &(1<<PINE6)) == 0) keycode += 0x40 &0xF0;
60
      else keyflag --;
61
      PORTG = (1<<PG0);                 // PORT G0 at pullup active
62
      DDRG = (0<<DDG0);                 // PORT G0 in output
63
    }
64
    
65
    if (keyflag == 1)
66
    {
67
      /* check line A */
68
      PORTG = (0<<PG3);                 // PORT G3 at pullup desactive
69
      DDRG = (1<<DDG3);                 // PORT G3 in input
70
      keycode = 0x01 &0x0F;              // line code
71
      /* check column */
72
      if ((PINE &(1<<PINE7)) == 0) ;          // faking condition
73
      else if ((PINE &(1<<PINE5)) == 0) keycode += 0x10 &0xF0;
74
      else if ((PINE &(1<<PINE4)) == 0) keycode += 0x20 &0xF0;
75
      else if ((PINE &(1<<PINE6)) == 0) keycode += 0x40 &0xF0;
76
      else keyflag --;
77
      PORTG = (1<<PG3);                // PORT G3 at pullup active
78
      DDRG = (0<<DDG3);                 // PORT G3 in output
79
    }
80
81
    /* Switch table which return the value of the pressed key */
82
    /****************************************************************************/
83
    /* Change the following code lines to attribute some action for each button */
84
    /****************************************************************************/
85
    switch (keycode)
86
    {
87
      case 0x21 :  number = '0';
88
      break;
89
      case 0x18 : number = '1';
90
      break;
91
      case 0x28 : number = '2';
92
      up();
93
      break;
94
      case 0x48 : number = '3';
95
      break;
96
      case 0x14 : number = '4';
97
      break;
98
      case 0x24 : number = '5';
99
      break;
100
      case 0x44 : number = '6';
101
      break;
102
      case 0x12 :  number = '7';
103
      Test_Interrupt();
104
      break;
105
      case 0x22 : number = '8';
106
      down();
107
      break;
108
      case 0x42 : number = '9';
109
      break;
110
      case 0x00 :  number = 'N';
111
      break;
112
      case 0x81 :  number = 'S';
113
      
114
      break;
115
      case 0x41 : number = 'E';
116
      break;
117
    }
118
    
119
    /* Interrupt Ports input */
120
    DDRE = ( (0<<DDE7) | (0<<DDE6) | (0<<DDE5) | (0<<DDE4));
121
    /* Ports output */
122
    DDRD = ( (1<<DDD7) | (1<<DDD4) );
123
    DDRG = ( (1<<DDG3) | (1<<DDG0) );
124
    /* Pullup resistance Interrupt Ports active */
125
    PORTE = ( (1<<PE7) | (1<<PE6) | (1<<PE5) | (1<<PE4));
126
    /* Pullup resistance output Ports inactive */
127
    PORTD = ( (0<<PD7) | (0<<PD4) );
128
    PORTG = ( (0<<PG3) | (0<<PG0) );
129
    sei();
130
    return number;
131
  }

von Peter D. (peda)


Lesenswert?

1
#include <avr\io.h>
2
3
#define NOP();  asm volatile("nop"::);
4
5
6
#define KEY_PIN         PINB
7
#define KEY_PORT        PORTB
8
#define KEY_DDR         DDRB
9
10
// Pin 0..3 = column 1..4
11
// Pin 4..6 = row 1..3
12
13
14
uint8_t keyscan( void )
15
{
16
  uint8_t col = 0, row = 0;
17
18
  KEY_PORT |= 0x7F;                     // all pullups on
19
  KEY_DDR = (KEY_DDR & 0x80) | 0x70;    // pin 6..4 = output
20
  KEY_PORT &= 0x8F;                     // pin 6..4 = output low
21
  NOP();                                // wait until inputs sampled
22
  if( ~KEY_PIN & 1<<0 )                 // if pin 0 = low
23
    col = 4;
24
  if( ~KEY_PIN & 1<<1 )
25
    col = 3;
26
  if( ~KEY_PIN & 1<<2 )
27
    col = 2;
28
  if( ~KEY_PIN & 1<<3 )
29
    col = 1;
30
  row = col;
31
  if( col ){                            // if column found, check row
32
    KEY_PORT |= 0x7F;                   // all pullups on
33
    KEY_DDR = (KEY_DDR & 0x80) | 0x0F;  // pin 3..0 = output
34
    KEY_PORT &= 0xF0;                   // pin 3..0 = output low
35
    NOP();                              // wait until inputs sampled
36
    if( ~KEY_PIN & 1<<4 )
37
      row = 5;
38
    if( ~KEY_PIN & 1<<5 )
39
      row = 9;
40
    if( ~KEY_PIN & 1<<6 )
41
      row = 13;
42
  }                                     // 0 = no key
43
  return row - col;                     // 1..12 = key
44
}

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.