Hallo,
ich bin gerade dabei, eine Abfrage für eine Tastatur zu schreiben. Die
Funktion read_keypad_if soll dabei die Wertigkeit der Taste zurückgeben.
Funktion funktioniert, wenn man sie nur für zwei Tasten verwendet, also:
if-Schleife schrieb:> http://www.if-schleife.de/
Das wollte ich auch schreiben :(
statt
>(debounce_if (&PIND, 5) == 1){
und
>if ((*debounce_if_port & (1 << debounce_if_pin)) == 0){
schreibst du besser
(debounce_if (&PIND, (1<<5)) == 1){
und
if ((*debounce_if_port & debounce_if_pin) == 0){
Das kann der Compiler schon beim Kompilieren ausrechnen und der µC muss
nichtmehr um n schieben, wofür es keine spezielle Instruktion gibt ->
langsam
mcb schrieb:> Liegt das Problem bei den vielen if-Schleifen?
Daß das keine Schleifen sind, wurde schon gesagt...
Nein, es liegt daran, daß du für jede if-Abfrage die debounce-Funktion
ein weiteres mal aufrufst und die wartet, bis einen weiteres mal eine
Taste gedrückt wurde.
Einmal abgesehen davon, dass die Funktion debounce_if entgegen ihrem
Namen die Taster nicht entrpellt, fällt mir an dem Programmstück nichts
Verdächtiges auf. Die paar if-Anweisungen hintereinander bringen den
Compiler nicht zum Verzweifeln.
Bist du sicher, dass während des Tests nicht die ganze Zeit Taster 1
geschlossen oder irgendwie überbrückt ist?
Die Taster schalten doch alle gegen GND und sind jeweils mit einem
Pullup-Widerstand (im Controller oder extern) versehen?
mcb schrieb:> Die wartet doch nur, wenn eine Taste gedrückt wird, bis sie losgelassen> wird.
Stimmt. Aber debouncen tut die Funktion auch nicht.
Zudem fragst du denselben Pin für verschiedene Tasten ab, z.B. 2 und 5.
Klärt mal einen Oberdau in Programmieren auf. Muss nicht nach jeder If
Then else Abfrage ein End If folgen?
Zumindest kenne ich das von meinen HP-Instrumentbasic so.
Ralph Berres
wenn man jetzt sukzessive die einzelnen Tasten abfragt, bleibt
man bei der ersten "gefangen" .. ganz unabhängig davon ob
die anderen gedrückt sind. Das ganze stellt doch eine Art
priorisierte Tastenabfrage dar. Ich verstehe ausserdem nicht
ganz warum dieselben Tasten mehrfach abgefragt werden.
Da die zweite Version von read_keypad_if sich von der ersten nur durch
das unterscheidet, was nach der Abfrage der Taste 2 kommt, müssen beide
Programme auf einen Druck der Taste 2 gleich reagieren.
Also funktionieren für die 2 entweder beide Versionen, oder keine.
Zur allgemeinen Schaltinformation. Alle Taster der Tastatur sind mit den
COM-Anschluss gegen GND geschalten. Die einzelnen PINs sind dann an die
I/Os des Controllers angeschlossen. In der Software werden dann für
diese PINs die internen Pull-Ups aktiviert. Bei der Funktion debounce_if
wird abgefragt, ob die Taste gedückt ist. Wenn ja, wird gewartet, bis
die Taste losgelassen wurde und dann 1 zurückgegeben, wenn nein, wird 0
zurückgegeben.
soso, wenn das so ist, dann stimmt meine Argumentation von oben nicht.
Denn ich habe positive Logik angenommen .. 1=gedrückt
while (1){
if (read_keypad_if () == 2){
PORTA &= ~(1 << 5);
_delay_ms (1000);
PORTA |= (1 << 5);
}
}
Du erwartest nicht zufällig ein Blinken zur Bestättigung hier?
Doch. Wenn die Taste 2 gedrückt wird, soll die LED kurz (1s) aufblinken.
Das funktioniert ja auch beim 1.Fall (also nur mit den Tasten 1 und 2 in
der Funktion). Beim 2.Fall aber nicht.
Ich habe von C nun nicht gerade viel Ahnung, aber in den meisten
richtigen Programmiersprachen gibt es die Case-Abfrage.
Wenn man nun die Taster einmal einliest und dann mit Case die
Möglichkeiten abfragt dürfte das zumindest um einiges übersichtlicher
sein.
Frank
mcb schrieb:> Doch. Wenn die Taste 2 gedrückt wird, soll die LED kurz (1s) aufblinken.> Das funktioniert ja auch beim 1.Fall (also nur mit den Tasten 1 und 2 in> der Funktion). Beim 2.Fall aber nicht.
eine 0 bzw Löschen des Pines am PORT lässt die LED leuchten?
(kann gut sein, ohne schematic lässt sich das nicht ersehen)
hmm, was könnte noch als Ursache in Betracht kommen ...
eine Taste, die dauernd "an" (0) ist und die Abfragekette blockiert?
Dennoch, wenn das nicht gerade die erste Taste ist, sollten die
am Kopf der Abfragekette stehenden Tasten funkionieren.
mir ist übrigens die Übergabeform &PIND als Zeiger nicht bekannt.
ich glaube zwar, dass es so richtig ist, und volatile ist dein
Zeiger ja auch. Wenn ich gar nicht weiterwusste würde ich die Funktion
umschreiben .. ohne Zeiger und den Code einfach duplizieren, je
nach Port
Schmeiß erst mal diese komische debounce_if raus - die funktioniert doch
sowieso nicht.
Wenn du dann die Tasten bekommst, baust du eine Funktion, die wirklich
entprellt.
Ich hab jetz mal die Funktion wait (Nachfolger von debounce) durch
das Aufblinken einer weiteren LED anzeigen lassen, dass die Taste
gedrückt und wieder losgelassen wurde:
Lässt man nun beim Aufruf im Hauptprogramm (vorerst ohne Auswertung) die
letzte Spalte der Tastatur (also Tasten 3, 6, 9, #) weg, und drückt dann
irgendeine andere Taste, blinkt die LED auf:
1
intmain(void){
2
//DDRs definieren
3
DDRA=0b11111111;
4
DDRB=0b11111111;
5
DDRC=0b11000000;
6
DDRD=0b00000011;
7
//PORTs definieren
8
PORTA=0b00000000;
9
PORTB=0b00000000;
10
PORTC=0b00111111;//interne Pull-ups für Tasten aktivieren
11
PORTD=0b11111100;//interne Pull-ups für Tasten aktivieren
12
while(1){
13
wait(&PIND,5);
14
wait(&PINC,1);
15
//wait (&PINC, 5);
16
wait(&PIND,4);
17
wait(&PINC,0);
18
//wait (&PINC, 4);
19
wait(&PIND,3);
20
wait(&PIND,7);
21
//wait (&PINC, 3);
22
wait(&PIND,2);
23
wait(&PIND,6);
24
//wait (&PINC, 2);
25
}
26
return0;
27
}
Ich kann mir nicht erklären, warum das nicht funktionieren sollte, die
anderen Tasten auch abzufragen.
Erstmal Fusseln vom Mund wisch.
- Deine CPU stoppt komplett, solange eine Taste gedrückt ist
- Beim Loslassen macht sie dann noch nen Hickup von elendig langen 200ms
(4 Millionen CPU-Zyklen).
- Die Reaktion erfolgt erst beim Loslassen. Ergonomisch wäre aber eine
Reaktion beim Betätigen.
Falls Deine Programmnutzer mit diesen Nachteilen leben können und ein
laienhaftes Feeling tolerieren, meinetwegen.
Peter