PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : "Anschubser" für 4x4 Keypadauswertung gesucht



oderlachs
05.06.2014, 21:09
Hallo Kenner !

Ich bin gerade dabei eine Routine zuum Auswerten eines 4x4 Keypads zu schreiben. Am KPd Port sind 4 Pins auf Input und 4 auf Output geschaltet. Je nach Maskierung(Binäre Angabe) ist immer eine Spalte COL1...4 auf Low gezogen. Je nach gedrückter Taste wird dann einer der 4 Eingänge, von HI auf Low gezogen..

Bei der Auswertungschleife breche ich mir den Kopf entwei und finde keinen rechten Anfang.

Ich habe hier mal den Code und hoffe er ist gut genug kommentiert, um zu zeigen wo nach ich suche. Am Port D sind erst mal 8 LED vom Stk500 als Auswertung(Binär).
Ich hoffe es kann mir wer einen "Tritt in den ..." geben, damit ich weiterfinde. ;)


/* ================================================== ======================== */
/* */
/* 4x4 Keypad-Abfrage */
/* */
/* ================================================== ======================== */

#include<avr/io.h>
#ifndef F_CPU
#define F_CPU 1600000UL
#endif
#include<util/delay.h>
#include <avr/io.h>


/* ================================================== ======================== */
/* PC0...PC3 = Row1...Row4 Taste gedrückt = LOW Pegel */
/* */
/* PC4...PC7 = Col4...Col1 über 5k6 R Schutzwiderstand */
/* */
/* ================================================== ======================== */
int main(void)
{
//DDR PortD als Ausgabe für LED Auswertung
DDRD = 0xFF;
//alles auf HI = LED OFF(STK500)
PORTD = 0xFF;
//INPUT/OUTPUT Einstellen für PORTC
DDRC = 0xF0; // PC0..3 Input PC4..7 Output
PORTC = 0x0F; // PullUpR an PC0..3
while (1)
{
// Voreinstellungen je Col Abfrage
//PORTC = 0b01111111 //Col 1 abfragen
//PORTC = 0b10111111 //Col 2 abfragen
//PORTC = 0b11011111 //Col 3 abfragen
//PORTC = 0b11101111 //Col 4 abfragen
if (bit_is_clear(PINC, 0)) PORTD = 0xFE; // 0xFE = LED 0 am STK500 ON ..COL1/ROW1
else PORTD =0xFF;
if (bit_is_clear(PINC, 1)) PORTD = 0xFD; // 0xFD = LED 1 am STK500 ON...COL1/ROW2
else PORTD =0xFF;
}


return 0;

}



Gruss und Dank
Gerhard

damfino
05.06.2014, 21:46
Ich würde einfach eine for schleife einbauen, mit dem Zähler die Spalten einzeln einschalten und dann alle 4 Eingänge überprüfen.

Ein/Ausgänge schreibe ich meistens als defines, zB #define Bumper (!(PINA &(1 << PINA4))) oder #define LED_gr_ein (PORTB &= ~(1<<DDB5)).

Die Abfrage im Code ist einfach: if (Bumper) {...} oder LED_gr_ein;
So kann man den Code leichter lesen, aber für guten Code habe ich selbst noch einiges zu lernen....

LG!

oderlachs
06.06.2014, 08:10
Danke vorerst !
ich werde es auch in einer Schleife machen..nur hatte ich beim ersten Versuch nur negative Aussagen, es wurden alle Tasten bestätigt obwohl keine gedrückt war. Darum habe ich das obere Listing zum Test geschrieben.
Nun muss ich sehen das ich immer die benutzte Taste(Row/Col) indentifizieren kann, also richtig auswerten kann.. Das ist mein Code jetzt, geht immer noch nicht, LED an BIT 1+2 sowie 4+5 leuchten ständig...Die Tastenauswertung zeigt den Wasserstand Honulullu... ;) aber nix logisches


/* ================================================== ======================== */
/* */
/* 4x4 Keypad-Abfrage */
/* */
/* ================================================== ======================== */

#include<avr/io.h>
#ifndef F_CPU
#define F_CPU 1600000UL
#endif
#include<util/delay.h>
#include <avr/io.h>


/* ================================================== ======================== */
/* PC0...PC3 = Row1...Row4 Taste gedrückt = LOW Pegel */
/* */
/* PC4...PC7 = Col4...Col1 über 5k6 R Schutzwiderstand */
/* */
/* ================================================== ======================== */
int main(void)
{
//DDR PortD als Ausgabe für LED Auswertung
DDRD = 0xFF;
//alles auf HI = LED OFF(STK500)
PORTD = 0xFF;
//INPUT/OUTPUT Einstellen für PORTC
DDRC = 0b11110000; // PC0..3 Input PC4..7 Output
PORTC = 0b00001111; // PullUpR an PC0..3
while (1)
{ //PORTD = 0xFF; //Alles wieder OFF (LED= LOW aktiv)
// Voreinstellungen je Col Abfrage
//PORTC = 0b01111111 //Col 1 abfragen
//PORTC = 0b10111111 //Col 2 abfragen
//PORTC = 0b11011111 //Col 3 abfragen
//PORTC = 0b11101111 //Col 4 abfragen

PORTC = 0b01111111; //Col 1 abfragen PINC 7 = LOW

if (!(PINC & (1 << PC3))) PORTD=0b11111110;
if (!(PINC & (1 << PC2))) PORTD=0b11111101;
if (!(PINC & (1 << PC1))) PORTD=0b11111011;
if (!(PINC & (1 << PC0))) PORTD=0b11110111;

PORTC = 0b10111111; //Col 2 abfragen PINC 6 = LOW

if (bit_is_clear(PINC, 3)) PORTD=0b11110111;
if (bit_is_clear(PINC, 2)) PORTD=0b11101111;
if (bit_is_clear(PINC, 1)) PORTD=0b11011111;
if (bit_is_clear(PINC, 0)) PORTD=0b10111111;

PORTC = 0b11011111; //Col 3 abfragen PINC 5 = LOW

if (bit_is_clear(PINC, 3)) PORTD=0b11111110;
if (bit_is_clear(PINC, 2)) PORTD=0b11111101;
if (bit_is_clear(PINC, 1)) PORTD=0b11111011;
if (bit_is_clear(PINC, 0)) PORTD=0b11110111;

PORTC = 0b11101111; //Col 4 abfragen PINC 4 = LOW

if (bit_is_clear(PINC, 3)) PORTD=0b11110111;
if (bit_is_clear(PINC, 2)) PORTD=0b11101111;
if (bit_is_clear(PINC, 1)) PORTD=0b11011111;
if (bit_is_clear(PINC, 0)) PORTD=0b10111111;
}

return 0;

}




Nochmals zum Verständnis, die gedrückte Taste zieht den PINC0..3 Eingang auf LOW dann soll der PIND0..7 Ausgang auf LOW.
Es gibt 4x4 versch Auswertungen je welcher PINC4...7 auf LOW ist und welcher PINC0..3 auf LOW gezogen wird durch die Taste.

Hat wer einen Rat..ich bin im Gedanken-Dschugel angekommen

mfg
Gerhard

Thomas$
06.06.2014, 11:02
"nur hatte ich beim ersten Versuch nur negative Aussagen, es wurden alle Tasten bestätigt obwohl keine gedrückt war" welche kapaziäten weist das tastenpad auf? und wie schnell fragst du es ab?

nach jedem neuen beschreiben des PORTC mal eine pause einfügen

oderlachs
06.06.2014, 11:52
Ja das gäbe es zu berücksichtigen wenn das Keypad angeschlossen wäre, so meine(!) Gedanken dabei. Es ist ja nix angeschlossen, wo das auch auftritt , das 4 LED ON sind...darum so paradox für mich...da denke ich das es am Code liegt.
Gewiss spielen Kapazitäten eine Rolle, aber sollen sie so gross sind um einen Eingang mit PullUP auf Low zu ziehen ?

Werde aber es mal mit ner Pause versuchen, danke für den Hinweis.

Gerhard