Forum: Mikrocontroller und Digitale Elektronik Interrupt + UART + Mega8 + Anfänger = verwirrt, hilfe?!


von Elektrolyt (Gast)


Lesenswert?

Hallo lieben Mitleser,

kurz zu meinem Vorhaben:
Ich möchte mittels Handy-Mega8-Uart einen Interrupt auslösen.
Also wenn das Handy über die Tx-Leitung ein String mit "RING\c\r" sendet 
(sprich angerufen wird) soll der Controller mit dem Signal aus dem 
"Schlaf" geholt werden. Nun habe ich einiges über Interrupts gelesen 
(auch das Datenblatt dahingehend befragt) allerdings sind mir einige 
Dinge noch unklar. Wird ein Interrupt bei jedem Empfangen eines 
"RING"-Strings ausgelöst, oder wie habe ich mir das vorzustellen?
Welchen Interrupt-Vektor würdet ihr für so einen Fall verwenden? Wie 
würdet ihr das realisieren, dass der mega8 bei einer empfangenen 
"aktivität" auf der Rx-Leitung, nur ein einziges mal in die 
Interrupt-Routine springt, diese abarbeitet (Zeitunkritisch, kann länger 
dauern, wegen Anruf Eingabeaufforderung etc) und dann wieder schläft?
Muss die Interrupt-Routine eigentlich in einer bestimmten Zeit 
abgearbeitet werden, oder ist das dem Controller egal, solange es mir 
egal ist? :-)
Welcher "Schlaf"-Modus bietet sich hier an? (so, dass auf 
Uart-Aktivitäten der Controller geweckt wird und was könnten da die 
Energieeinsparungen sein gegenüber Dauerbetrieb und Polling?)

ich würd mich über jede Hilfe und für jeden Bruchteil einer Antwort auf 
meine ca1000 Fragen sehr freuen...
MFG Elko

von peter-neu-ulm (Gast)


Lesenswert?

Ein Interrupt wird durch ein >einzelnes< Ereignis ausgelöst, meist eine 
positive oder negative Flanke eines Signals oder ein komplett an der 
UART eingetroffenens Zeichen.

Wenn die UART eingesetzt wird, kann diese nach jedem Zeichen einen 
UART-Int
auslösen. In der Int-Routine wird die Folge der Zeichen kontrolliert 
(aufgesammelt), und wenn dann die richtige Zeichenfolge z. B nach dem 
zehnten Zeichen (bzw.Int)erkannt ist, kann der Kontroller zu weiteren 
Aktionen schreiten.

Ich hab' das Datenblatt nicht im Kopf, aber wahrscheinlich kann man nach 
der Interrupt-Routine den Kontroller jedesmal schlafen schicken und 
durch den nächsten UART-Int wieder aufwecken.

Eventuell muss man auch durch die erste Signalflanke den Kontroller 
aufwecken und ihn für einige Zeit, vom Timer-Int gesteuert, wach lassen. 
Wenn dann nicht der richtige String eingetroffen ist, 
rücksetzen,schlafen legen und auf neuen String warten.

von Slowflyer (Gast)


Lesenswert?

Was die UART-Geschichte angeht, so ist das AVR-Tutorial immer eines 
Blickes Wert:

http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ich bin da selbst Anfänger und habe mich selbst kürzlich mit Sleep Mode 
und Aufwecken beschäftigt. Daher hier eine Spekulation dazu:

Du könntest die RX Leitung (TTL vom Handy direkt oder TTL-Seite des 
RS232-TTL) zusätzlich auf den INT0 vom AVR geben und dadurch den AVR 
sogar aus dem Sleep Mode Power Down wecken.

Das Aufwachen per INT0 wird ausgelöst, wenn an INT0 ein LOW Pegel 
anliegt. Es ist also sicher zu stellen, dass im Ruhezustand (Spezialfall 
Handy ist aus beachten!) ein HIGH Pegel anliegt.

Der AVR wacht dann beim Startbit auf. Ob die Aufwachzeit noch ausreicht, 
um das erste "RING" teilweise zu detektieren, muss man testen (ich 
spekuliere: es reicht nicht). Beim zweiten RING sollte der AVR wach 
sein. Wesentlich schneller als der Power Down Mode ist der Stand By Mode 
wach.

Die mehrfache Abarbeitung des INT0 beim Empfangen kann man ignorieren 
oder du kannst den INT0 nach dem Aufwachen abschalten. Das Abschalten 
benutze ich im Beispiel Suppentimer [[Pollin 
Funk-AVR-Evaluationsboard]].

Beim externen Interrupt an sich muss man, habe ich gelesen, beachten, 
dass das sehr empfindlich gegen elektromagnetische Störungen sein kann 
und dass der AVR ggf. öfters durch Fehlalarme aufgeweckt wird. Also wäre 
die Software so zu schreiben, dass der AVR nach dem Aufwachen das RING 
prüft und bei Fehlalarm schnellstens wieder pennen geht.

von Elektrolyt (Gast)


Lesenswert?

Vielen vielen Dank für die Antworten...

@stefan: das hört sich schon sehr interessant an...
Meinst du die Rx Leitung vom Handy oder vom uC? Warscheinlich meinst du 
den Tx des Handys zusätzlich auf int0 legen?
allerdings stehe ich noch ein wenig auf dem schlauch was die 
implementierung der prüfung betrifft.
wie könnte ich das (am einfachsten) realisieren, dass nach dem RING 
geprüft wird? programmiere übrigens in C...
wäre für jede Hilfe dankbar...

MFG Elko

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Freie Auswahl TX vom Handy oder RX vom AVR. Die beiden sind ja irgendwo 
verbunden.

Dazwischen kann sich ein Pegelwandler RS232-TTL befinden. Aber: Handys 
haben eigentlich nie echte RS232-Pegel (ausser ein entsprechendes 
Handykabel für PC_Anschluss wird benutzt, dann ist der Pegelwandler im 
Kabel), so dass man einen Pegelwandler vergeblich sucht. Aufpassen mit 
welchen Pegeln das Handy arbeitet 0V/5V oder 0/3.3V oder...

Bei einem Pegelwandler ist es im Prinzip Geschmackssache, wo die TX/RX 
Kreuzung gemacht wird - auf der Handyseite oder auf der AVR-Seite.

Beim Programmieren gehe ich gerne schrittweise vor, anstatt alles auf 
einmal stemmen zu wollen.

Hier würde das bedeuten, zuerst ein UART Programm zu schreiben, das in 
einer Hauptschleife ein "RING" auswerten kann. Das würde ich auch 
erstmal mit einem PC und Terminalprogramm simulieren statt mit einem 
Handy.

Dann eine INT0-Funktion dazu zu packen. Dann ein Sleep dazu zu packen. 
Wie eine UART abgeprüft wird, wird im AVR GCC Tutorial beschrieben. Und 
der Rest auch ;-)

Vielleicht helfen dir auch meine Beispiele s. Link o. weiter. Beim 8-Bit 
Z#hler und der Uhr ist UART (Polling) drin und im Suppentimer ist 
INT0/Sleep drin.

von Elektrolyt (Gast)


Lesenswert?

Danke nochmal...
Das mit den Pegeln etc ist alles klar, auch jetzt die hardwaremäßige 
umsetzung und Uarts habe ich auch schon aufgebaut, allerdings habe ich 
konkrete probleme bei der Prüfung selbst, ob die Zeichenkette RING 
empfangen wurde oder nicht. Da der Controller ja wahrscheinlich die 
ersten paar zeichen wegen dem aufwachen verwerfen wird. Würdest du die 
empfangenen zeichen in ein Array übertragen und dann auf die 
Zeichenfolge "RING" prüfen (wenn ja wie gross sollte der array sein?) 
Wenn ich das volle RING erfassen möchte, bietet sich doch ein größeres 
array an, oder (vielleicht doppelt so lang wie das "RING\c\r"?)
Vielen Dank für die Mühe...

LG Elko

von Elektrolyt (Gast)


Lesenswert?

noch was, wäre es sinnvoll, dass in der Rx-Int-Routine das empfangene 
Zeichen überprüft wird und sobald ein "R" empfangen wird, das R in 
Array[0] übertragen wird... sobald ein "I" empfangen, das I in Array[1] 
übertragen wird etc. und in der Rx-Int-Routine wird dann geprüft ob das 
Array == "RING" entspricht.
Verstehe ich das richtig, dass ich den INT0-interrupt nur für das 
aufwachen benutze und danach ausschalte und dass das empfangen der 
zeichen über den Uart-Rx-INT läuft?

LG Elko

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Bei dem Puffer (Array ist OK) würde ich erstmal nicht geizen. 2*RING 
plus Nullbyte (!) hört sich zweckdienlich an.

Empfangene Zeichen unter Beachtung der Grösse reinschreiben dabei \r 
verwerfen. Jedesmal den Puffer hinter dem aktuellen Zeichen mit Nullbyte 
abschliesse. Bei einem \c auswerten und anschliessend die Füllposition 
auf den Pufferanfang zurücksetzen. Ebenso zurücksetzen beim Erreichen 
des Puffergrösse. Auswertung mit strncmpi ggf. mit Vorauswahl, ob die 
mitgezählte Zahl der Zeichen im Puffer genau 4 ist.

EDIT:

> noch was...

Das ist mir zu kompliziert gedacht.

Die Empfangsroutine würde ich universell gestalten. Sie soll eine Zeile 
per UART in einen Puffer schreiben. Wie gross der Puffer ist, kann 
konfiguriert werden. Danach kümmert sich der Rest des Programms um die 
Auswertung der Zeile.

Dadurch bekommt man eine universelle UART-Zeileneinleseroutine und nicht 
nur eine RING-Einleseroutine. BZW. gibt es bereits fertige Libraries für 
ersteres.

von John (Gast)


Lesenswert?

Ich habe vor ein paar Jahren eine Freisprecheinrichtung für ein 
Mobiltelefon entwickelt.
Ich hatte mich für zwei Interruptlevel (per Software, da AVR sowas nicht 
in Hardware unterstützt) entschieden.
USART-IRQs im hohen Level über Ringpuffer.
Den Parser im niedrigen Level per Timer-Interrupt. Das ganze habe ich 
per State-Machine gemacht. Einfach Zeichen aus dem Ringpuffer holen bis 
zum Zeilenende-Zeichen, danach dann Stringvergleich mit den erwarteten 
Strings - hier nur "RING". Flag setzen und die Arbeit wird in der 
Hauptroutine erledigt.

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.