Forum: Mikrocontroller und Digitale Elektronik Auswertung einer 3x4 Matrix


von Hugo P. (portisch)


Lesenswert?

Hallo!

Da ich nicht den originalen Post von Peter Dannegger verunstallten 
wollte hier meine Frage dazu.

Ich habe den Code so umgeändert um ein 3x4 Keypad einzulesen.
Es hat 3 Spalten und 4 Zeilen.
Nun habe ich aber alle Pins auf einen Port gelegt. Kann das so gehen 
oder kommt es da zum Kurzschluss?
Muss man die Richtung des Ports (Output/Input) vorher noch setzen?
1
/* keyboard Interface:
2
 * 4 rows x 3 columns: P0.0 - P0.3 * P2
3
 * support multiple keys pressed simultaniously
4
 * if more than two keys pressed, then every key need a decoupling diode
5
 *
6
 * 0x00         = no key changed
7
 * 0x01 .. 0x0C = key released
8
 * 0x81 .. 0x8C = key pressed
9
 */
10
11
/* P0 == PORTD
12
 * PD0    COL 1
13
 * PD1    COL 2
14
 * PD2    COL 3
15
 
16
 * P2 == PIND
17
 * PD3    ROW A 
18
 * PD4    ROW B
19
 * PD5    ROW C
20
 * PD6    ROW D
21
 */   
22
23
//#pragma cd pl(9999)
24
#include <avr/io.h>
25
26
#define idata
27
#define code
28
29
#define P0 PORTD
30
#define P2 PIND
31
32
#define KEY_PRESS_MASK  0x80
33
34
#define nop() \
35
   asm volatile ("nop")
36
37
uint8_t n_keys_pressed;        // 0, 1 or 2
38
static uint8_t idata valid_keys[3];    // last returned values
39
static uint8_t idata last_keys[3];    // t - 1
40
41
42
void InitKeyboard( void )
43
{
44
  uint8_t i;
45
46
  for( i = 0; i < 3; ++i ){
47
    valid_keys[i] = 0xFF;        // low active
48
    last_keys[i]  = 0xFF;
49
  }
50
  n_keys_pressed = 0;
51
}
52
53
54
uint8_t GetKey( void )    // call with debouncing time (10..200msec)
55
{
56
  uint8_t i, j;
57
  uint8_t mask;
58
  uint8_t key;
59
  uint8_t column;
60
  uint8_t key_nr = 0;
61
  uint8_t code ROW[] = { ~0x08, ~0x10, ~0x20, ~0x40 };    // low active
62
63
  for( i = 0; i < 4;  ++i ){
64
65
    P2 |= 0x07;
66
    P0 &= ROW[i];          // set rows
67
  
68
  nop();
69
  
70
    column = P2;          // read column
71
72
    if( column != valid_keys[i] && key_nr == 0 ){
73
      for( mask = 1, j = 0; j < 3; mask <<= 1, j++ ){
74
75
        key = column & mask;        // check bitwise
76
77
        if( key == (last_keys[i] & mask) ){    // debouncing
78
79
    if( key != (valid_keys[i] & mask) ){    // key not handled
80
81
      valid_keys[i] = valid_keys[i] & ~mask | key;
82
      key_nr = 3 * i + j + 1;      // 0x01 ... 0x0C
83
84
      if( key == 0 ){        // low active
85
        n_keys_pressed++;
86
        key_nr |= KEY_PRESS_MASK;      // 0x81 ... 0x8C
87
      }else{
88
        n_keys_pressed--;
89
      }
90
      break;
91
    }
92
        }
93
      }
94
    }
95
    last_keys[i] = column;        // for next debouncing
96
  }
97
  return key_nr;
98
}

Auch wie läuft das Entprellen ab? Muss ich in meiner Hauptschleife 
sozusagen dann vor jedem Aufruf von KetKey ein Delay drinnen haben?

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.