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?