Forum: Mikrocontroller und Digitale Elektronik Portabfrage über Whileschleife


von heiko_h (Gast)


Lesenswert?

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.

von Ben j. (scarab)


Lesenswert?

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))
{}

von Stefan W. (swessels)


Lesenswert?

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

von heiko_h (Gast)


Lesenswert?

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.

von oldmax (Gast)


Lesenswert?

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

von ??? (Gast)


Lesenswert?

Generell sollte so eine Abfrage via Interupt auf fallende Flanke gelöst 
werden. Wenn es möglich ist.

von oldmax (Gast)


Lesenswert?

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

von heiko_h (Gast)


Lesenswert?

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?

von Peter (Gast)


Lesenswert?

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

von oldmax (Gast)


Lesenswert?

Hi
Einfach meine Beiträge lesen...
Gruß oldmax

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
Noch kein Account? Hier anmelden.