Habe mal ein C-Programm geschrieben, mit dem ich folgendes vorhabe...
Ich habe eine Tastenblock mit 12 Tasten. (3x4 Matrix Anschluß)-->also 3
Spalten und vier Zeilen. Um das Auslesen zuz realisieren habe ich die
Spalten als Eingänge mit Pull ups und die Zeilen als Ausgänge definiert.
Ausgangspegel =high ("1"). Das heißt jetzt wenn ich eine Taste z.b die
Zahl 3 erkennen möchte (Zeile 1 und Spalte 3) , schreibe ich am ausgang
Zeile 1 eine "0" und überprüfe ob eine "0" in Spalte 3 eingelesen wird.
--> Ich möchte einen 4stelligen Code eingeben...
Bitte schaut euch den Code mal an. Er ist bestimmt noch
optimierungswürdig...
Vielen Dank für eure Hilfe
@ Hannes Lux (hannes)
Vielen Dank für deine Mühe, jedoch habe ich keinerlei Erfahrung mit dem
Assembler und möchte das jetzt gerne in C realisieren. Habe mal ein
neues Thema geöffnet, da das alte zu undurchsichtig war.
THX
rudi
@Sonic
> _delay_ms(255); // 255ms/16MHz=16ms
Was soll das? _delay_ms() macht schon die richtige Zeit, wenn man mit
#define F_CPU 16000000UL
den Prozessoertakt angibt.
MFG
Falk
Ups, bischen schnell abgeschickt!
Bit 0..3 sind direkt an PORTA angeschlossen, bit 4..7 an die Zeilen eine
4x4-Matrix angeschlossen. Zum Auslesen der Spalten werden bit 4..7 auf
Ausgang '0' gesetzt, bit 0..3 auf Eingang mit Pullup.
Bei gedrückter Taste wird das entsprechende bit mit Pullup '0'.
Zum Auslesen der Zeilen wird der Portzustand umgedreht. Das Ergebnis
wird in eine Variable gespeichert und augewertet (in meinem Fall als
ASCII auf UART ausgegeben).
Es können auch mehrere gleichzeitig gedrückte Tasten ausgewertet werden.
@Falk:
hast du völlig Recht! Als ich das Programm geschrieben habe, hatte ich
den _delay-Befehl noch nicht verstanden. ;-)
Sollte ich mal Ändern, war halt nur ein Testprogramm ohne Nutzen.
...und v.a. geht _delay_ms(255) bei 16 MHz CPU-Frequenz garantiert in
die Hose, eben weil die maximale mit _delay_ms() machbare Verzögerung
262,14 ms / F_CPU[MHz] ist und somit in diesem Falle ca. 16,4 ms...
@Sonic
>Es können auch mehrere gleichzeitig gedrückte Tasten ausgewertet werden.
Bist du da sicher? Weder die Hardware noch das Programm deuten darauf
hin. Mehrere Tasten brauchen in der Matrix Dioden.
MfG
Falk
>Mehrere Tasten brauchen in der Matrix Dioden.
Nein braucht's nicht, weil ich Zeilen und Spalten nacheinander abfrage.
Hab's getestet, funktioniert.
Seid ihr damit einverstanden?
1
for(unsignedchari=0;i<=15;i++)// Pause 15 x 10ms = 150ms (entprellung)
@Sonic
>>Mehrere Tasten brauchen in der Matrix Dioden.>Nein braucht's nicht, weil ich Zeilen und Spalten nacheinander abfrage.>Hab's getestet, funktioniert.
Glaub ich aber nicht wenn ich deinen Code sehe. Wie werden denn zwei
(oder mehr) gedrückte Tasten an das Programm weitergegeben?
>Seid ihr damit einverstanden?>for(unsigned char i=0;i<=15;i++) // Pause 15 x 10ms = 150ms (entprellung)> {> _delay_ms(160); // 160/16MHz=10ms> }
Nöö, aus drei Gründen.
a) Bei 16 MHz sind max. 16,4 ms drin.
b) Das Delay hat in der Routine zur Matrixauswertung nix verloren, da
diese Routine sinnvollerweise periodisch im Timerinterrupt aufgerufen
wird.
c) Eine Verzögerung von 15 ms wird mit _delay_ms(15); generiert.
MfG
Falk
>da diese Routine sinnvollerweise periodisch im Timerinterrupt aufgerufen wird.
Meinst du die komplette Abfrage? Die habe ich per Polling abgefragt, das
reicht bei den langsamen Vorgängen dicke, da brauch' ich keinen INT
verbraten. Das _delay zwischen den Abfragen ist nötig, weil der Port
eine gewisse Zeit braucht um die Zustände sicher anzunehmen (von Aus-
auf Eingang umschalten, die Pullups Zu- und Abschalten)
ok..habt ihrs jetzt ? (spaß)...
wie sieht es denn mit meinem Code aus ? habt ihr euch den mal angeschaut
?
man hatte mir hier folgendes geraten um meine matrix auszuwerten...
Karl heinz Buchegger (kbuchegg) wrote...
"Du hast ein Array für alle Tasten in dem für jede
Taste ein Zähler realisiert ist.
In deiner Abfrage Funktion gehst du alle Tasten (nach dem
von dir beschriebenen Prinzip) durch und wenn eine Taste
gedrückt ist, erhöhst du den Zähler. Ist die Taste nicht
gedrückt, wird der entsprechende Zähler auf 0 gesetzt.
Erreicht der Zähler 3 oder 4 (such dir was aus), dann gilt
diese Taste als gedrückt und du vermerkst dir dieses in
einem anderen Array.
Diese Abfragefunktion hängst du an einen Timer und lässt sie
alle 10 ms aufrufen.
Damit hast du funktional was ähnliches gebaut wie die PeDa
Tastenabfrage und Entprellung, nur halt angepasst an deine
Matrix.
"
Danke für die Hilfe
Okay, hab' mir den Code mal angeguckt.
Zuerst muss ich sagen dass ich für eine Anwendung wie eine Tastenabfrage
(wenn's nicht gerade eine Stoppuhr ist) keinen Interrupt benutzen würde,
der unnötig Resourcen verbraucht. Und wenn mir in die Abfrage ein INT
'reinfunkt, dann geht halt mal eine Abfrage in die Hose. Macht nix,
meistens merkt man das beim Eingeben gar nicht.
Dein Code sollte eigentlich so funktionieren, ist aber etwas
unübersichtlich und braucht seine Zeit. Abfragen wie
@Sonic
>>da diese Routine sinnvollerweise periodisch im Timerinterrupt aufgerufen wird.>Meinst du die komplette Abfrage? Die habe ich per Polling abgefragt, das>reicht bei den langsamen Vorgängen dicke, da brauch' ich keinen INT
Naja, könnte man jetzt drübr streiten. Seis drum. Dennoch würde ich den
Delay dort rausnehemen und in die Polling-Schleife packen. Ist
übersichtlicher und die Funktion kann einfacher wiederverwendet werden
(auch im Interrupt wenns sein soll).
MfG
Falk
Kann ich machen. Die Zeit bis zur Gültigkeit der Portzustände kann man
auch mit einem oder mehreren NOPs machen, dürfte ausreichen. Ich
probier's nochmal.
Achso..
du meinst vermutlich die 150ms. Die Auswertung der Tasten (switch) und
die Entprellung habe ich dort testweise untergebracht. Ist natürlich
jedem selbst überlassen, wie er das macht. ;-)