Habe ein Problem mit folgender Portabfrage: //Auf fallende Flanke an PD2 warten While (!(PIND & (1<<PD2))) {} Das Signal (fallende Flanke) liegt an PD2 an, springt aber nicht aus der Schleife raus. Gibt es noch eine andere Möglichkeit das zu definieren, oder ist der Fehler in der Whileabfrage? Habe einen ATMEGA16.
Was meinst du mit Flanke? Wenn du eine Flanke erkennen willst musst du den alten zustand ja irgendwo zwischenspeichern und dann vergleichen. Du fragst lediglich ab ob PD2 == 0 ist. edit: wenn du solange warten (nix machen) willst bis PD2 == 0 ist dann versuch mal: // solange PD2==1 nix machen While (PIND & (1<<PD2)) {}
Damit erkennst Du nur den Zustand des Pins im Momnent der Abfrage. Das ist keine Flankenerkennung! Außerdem wartest Du gerade in Deinem Code so lange, bis der PORT "high" ist! Sinngemäß hast Du geschrieben: warte, solange der PORT nicht high ist. Laß mal die Negation (das '!') weg, dann sollte es funktionieren. Gruß, Stefan
Stefan Weßels schrieb: > Damit erkennst Du nur den Zustand des Pins im Momnent der Abfrage. Das > ist keine Flankenerkennung! > > Außerdem wartest Du gerade in Deinem Code so lange, bis der PORT "high" > ist! > > Sinngemäß hast Du geschrieben: > > warte, solange der PORT nicht high ist. Laß mal die Negation (das '!') > weg, dann sollte es funktionieren. > > Gruß, > Stefan Alles klar dann probiere ich das mal so, danke euch.
Hi Nun, in C kann ich dir nicht helfen, aber prinzipiell ist es nicht geschickt, in einer While-Schleife auf ein Ereignis zu warten. Dein Programm kann dann ja nichts anderes ausführen. In Assembler gehe ich folgenden Weg: Ich habe eine Variable, die dan zuletzt gelesenen Portzustand hat, eine zweite, die in einer Leseroutine den neuen gelesenen Wert bekommt. Etwa so:
1 | Read_IO: |
2 | In Reg_A, Port_x |
3 | STS New_In, Reg_A |
4 | ... |
5 | Ret |
Diese Routine wird am Anfang der Schleife ständig durchlaufen. Natürlich kann New_In eventuell auch andere Bits aufnehmen, hier kann ich sie alle einsammeln. Reicht ein Byte nicht, wird ein zweites hinzugenommen. In einer weiteren Routine erfasse ich die Flanken der Signale. Zuerst wird Old_In mit New_In EOR-Verknüpft. Die gesetzten Bits im Ergebnis zeigen auf geänderte Bits hin. Nun wird mit New_IN und dem Ergebnis aus der XOR Verknüpfung über eine Und-Verknüpfung der Wechsel von 0 nach 1 detektiert und in einem FlankenByte eingetragen. Gleiche Vorgehensweise mit Old_In und dem Ergebnis der XOR ergibt die Flanke von 1 nach 0 Etwa so:
1 | Set_Flag: |
2 | LDS Reg_A, New_In |
3 | LDS Reg_B, Old_In |
4 | EOR Reg_A, Reg_B ; Ergebnis u rgeänderte Bits |
5 | Push Reg_A ; merken |
6 | LDS Reg_B, New_IN |
7 | AND Reg_A, Reg_B ; Ergebnis sind die Flanken von 0 nach 1 |
8 | STS Low_to_High, Reg_A |
9 | POP Reg_A |
10 | LDS Reg_B, Old_In |
11 | AND Reg_A, Reg_B ; Ergebnis sind Flanken von 1 nach 0 |
12 | STS High_to_Low,Reg_A |
13 | LDS Reg_A, New_In |
14 | STS Old_In, Reg_A ; zum Schluß noch Neu nach Alt schieben |
15 | ret |
Im Programm schaust du nur nach den Flankenbits, bearbeitest die Ereignisse und setzt das Flankenbit zurück oder machst mit der nächsten Aufgabe weiter. Nix mehr mit irgendeiner Wait oder While-Anweisung. Ach ja, berechtigter Einwand: ist nicht entprellt. Aber natürlich kannst du auch erst nach dem Entprellen die Variable New_In beschreiben, das verändert an den Flanken nix. Gruß oldmax
Generell sollte so eine Abfrage via Interupt auf fallende Flanke gelöst werden. Wenn es möglich ist.
Hi Generell solle ein Interrupt nur für schnelle Signale benutzt werden. Normalerweise reicht pollen völlig aus, speziell, wenn es sich um Taster uder Kontakte handelt. Schnelle Signale sind Impulse, deren Signalzeit kürzer wie die Programmzykluszeit ist. Gruß oldmax
oldmax schrieb: > Hi > Generell solle ein Interrupt nur für schnelle Signale benutzt werden. > Normalerweise reicht pollen völlig aus, speziell, wenn es sich um Taster > uder Kontakte handelt. Schnelle Signale sind Impulse, deren Signalzeit > kürzer wie die Programmzykluszeit ist. > Gruß oldmax Wie kann ich eine Portabfrage auf Flanke mit Polling machen?
heiko_h schrieb: > Wie kann ich eine Portabfrage auf Flanke mit Polling machen? alten status merken, neuen status einlesen wenn von 0->1 dann positive flanke, neuen status als alten status übernehmen
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.