Forum: Mikrocontroller und Digitale Elektronik PWM und UART Interrupt Problem


von Elolehrling (Gast)


Angehängte Dateien:

Lesenswert?

Guten Tag

Ich und andere Lehrlinge unserer Firma, haben den Auftrag bekommen eine 
Theater Bühnenbeleuchtung zu realisieren. Mir wurde der ganze Software 
teil zugewiesen.

(Zum besseren Verständniss des folgenden Textes habe ich für euch ein 
Bild gemacht, auf dem meine Frage evt. besser Verständlich ist. Hoffe 
ihr lest meinen Text trotzdem durch, da in diesem noch weitere Fragen 
auftauchen die auf dem Bild nicht erwähnt sind. Sorry für meine 
Schrift!!! ;-) )

Das ganze sieht folgendermassen aus:
Wir haben RGB LED's in Serie geschaltet auf einen LED Streifen gelötet. 
Hardwaremässig ist das ganze kein grosses Problem gewesen.

Die LED's sollen mithilfe von PWM eingestellt werden. Habe mir gedacht 
immer den Timer0 zu inkrementieren und sobald dieser an einer bestimmten 
Schwelle angelangt ist, mithilfe eines Interrupts den Ausgang an dem die 
LED hängt zu toggeln.

Diese Schwelle soll über RS485 einstellbar sein. Ich habe bisher nur 
kleinere Projekte mit UART realisiert, PWM habe ich noch nie wirklich 
benutzt, scheint aber nicht sonderlich schwierig zu sein.

Folgendes Problem liegt nun vor:
In der Schule haben wir gelernt, dass sobald bei einem PIC ein Interrupt 
aufgerufen wird das Global Interrupt Enable Flag auf 0 gesetzt wird. 
Bedeutet, sobald ein Interrupt aufgerufen wird, werden wietere 
Ignoriert. Nun, da der Timer0 ja nicht sonderlich lange brauchen wird um 
seine Schwelle zu erreichen und den Ausgang zu toggeln, wird dieses 
Interrupt in ziemlich kurven Abständen aufgerufen.
Was ist nun, wenn ich während diesem Interrupt in dem ich den Ausgang 
Toggle Daten über UART Empfangen will? So wie ich das verstanden habe, 
wird falls ich gerade im Interrupt zum toggeln bin, die ganzen UART 
Daten einfach Ingoriert.

Nun meine frage: ist es mit einem PIC möglich diese Daten auch während 
eines Interrupts von Timer0 einzulesen?

Alternativ hat mir ein älterer Elektronik-Lehrling zu einem AVR geraten. 
Habe noch nie mit diesesn gearbeitet, deshalb wäre mir PIC halt lieber. 
Aber trotzdem: Ist es bei einem AVR möglich ein "Interrupt in einem 
Interrupt" zu haben, oder wenigstens zu merken dass Daten über UART 
angekommen sind und diese nach dem toggeln einzulesen?

Ich hoffe, ich könnte das ganze gut genug beschreiben. Für weitere 
fragen stehe ich euch gerne zur Verfügung und ich würde mich über eure 
hilfe freuen.

Mit freundlichen Grüssen
Elolehrling

von Wusel D. (stefanfrings_de)


Lesenswert?

Bedenke, wie der Empfang von seriellen Zeichen funktioniert. Zunächst 
wird das Zeichen bitweise in ein Schiebereigister eingelesen. Wenn alle 
Bits des Zeichens empfangen wurden, wird der Inhalt des Schieberegisters 
in ein I/O Register kopiert.

Nun können schon die Bits des nächsten Zeichens in das Schieberegister 
eingelesen werden, während das I/O Register (noch) das zuvor empfangene 
Zeichen enthält. Werst wenn alle Bits des nächsten zeichens empfangen 
wurden, geht der Inhalt des I/O Registers verloren. Du hast also schon 
einige Zeit zum Auslesen (so lange die Übertragung eines Zeichens 
dauert).

Deine Interrupt Routinen (für PWM und UART) dürfen zusammen gerechnet 
nicht länger dauern, als die Übertragung eines Zeichens dauert. je 
geringert die Bitrate, desto einfacher wird es.

AVR (AtTiny und AtMega) kennen auch nur einen Interrupt Level.

Überlege, ob es überhaupt notwendig ist, die LED mit einer 
Interrupt-Routine zu toggeln. Du könntest dazu auch einen der PWM 
Ausgänge nutzen und diese Aufgabe komplett der Hardware überlassen.

von camikusch (Gast)


Lesenswert?

Elolehrling schrieb:
> (Zum besseren Verständniss des folgenden Textes habe ich für euch ein
> Bild gemacht,

da hättest du kein bild machen müssen, das hättest du auch hier 
reinschreiben können - wäre vielleicht 300zeichen groß gewesen, so sinds 
2.1 mb.
und wenn schon ein scan dann nicht so hoch aufgelöst, und nicht in 24 
bit. umwandeln in s/w und als gif hier einstellen. 
http://www.mikrocontroller.net/articles/Bildformate

von Elolehrling (Gast)


Lesenswert?

@camikusch
Das mit den Bildformaten habe ich nur flüchtig überlesen, sorry!

@Stefan
Direkt über die PWM Ausgänge habe ich mir am Anfang auch gedacht, nur 
bisher keinen PIC gefunden der extrem klein ist und 3 PWM Ausgänge hat. 
Da die LED Streifen ja möglichst Simpel sein sollen darf da kein 40 PIN 
Riesen uC drauf. Haben da welche mit 8 / 14 Pins in aussicht, allerdings 
bisher noch keinen gefunden der 3 PWM Pins hat.

Falls jemand einen kennt, wäre ich dankbar wenn ihr ihn hier erwähnen 
würdet.

Zu den Schieberegistern: Bedeutet, wenn etwas Empfangen wird gehen diese 
Zeichen zuerst in ein Schieberegister im Controller. Angenommen ich 
befinde mich zu dem Zeitpunkt im Interrupt des Timer0 zum Toggeln der 
LED, wird dann also nach dem beenden dieses Interrupts erst der UART 
interrupt ausgeführt, da die Zeichen sich ja noch im Schieberegister 
befinden?

Also Vom Ablauf:

1. Interrupt LED aufrufen
2. Während des Interrupts können nun UART Daten in das Schieberegister 
eingelesen werden?
3. LED toggeln Interrupt
4. Aus LED toggeln Interrupt raus
5. UART Interrupt wird ausgelösst, da sich etwas im Schieberegister 
befindet.

Habe das ich soweit richtig verstanden?

Danke für eure Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

Elolehrling schrieb:

> Zu den Schieberegistern: Bedeutet, wenn etwas Empfangen wird gehen diese
> Zeichen zuerst in ein Schieberegister im Controller. Angenommen ich
> befinde mich zu dem Zeitpunkt im Interrupt des Timer0 zum Toggeln der
> LED, wird dann also nach dem beenden dieses Interrupts erst der UART
> interrupt ausgeführt, da die Zeichen sich ja noch im Schieberegister
> befinden?

Vergiss das Schieberegister wieder.
Das ist der interne Aufbau im MSP. Den kannst du nicht beeinflussen und 
auch nicht verändern.
Worauf es ankommt, und worauf Stefan auch hinaus wollte:
Du hast Zeit!
Auch wenn du ein Zeichen von der UART nicht quasi sofort abholst, hast 
du ein wenig Zeit, in der der MSP ruhig noch eine andere Aufgabe fertig 
machen kann. Und zwar hast du Zeit, bis das nächste Byte vollständig 
empfangen wurde. Bis zu diesem Zeitpunkt musst du ein Byte von der UART 
abgeholt haben. Und diese Zeit ist in MSP-Einheiten gemessen, ziemlich 
lang. Solange dein Code in der Zwischenzeit nicht 200-tausend 
quadratische Gleichungen löst, wird es dir kaum passieren, dass du auf 
die Art ein Byte von der UART verlierst. Selbst dann nicht, wenn gerade 
eine andere Interrupt-Bearbeitung im Gange ist, während sich die UART 
mit einem Interrupt meldet und verkündet, dass ein Zeichen empfangen 
wurde. Du machst dir bei diesem Detailproblem Sorgen, wo es keine Sorgen 
zu machen gibt.

Die Interrupt-Anforderung von der UART wird dann einfach ein wenig 
verzögert, solange bis die Interrupt-Bearbeitung deiner Timer-PWM fertig 
ist. Das bischen Wartezeit ist überhaupt kein Problem und dann kommt der 
UART-Interrupt eben danach an die Reihe. Und da du dir eine gewisse 
zeitliche Verzögerung leisten kannst, ist das alles kein Problem.

von Karl H. (kbuchegg)


Lesenswert?

> In der Schule haben wir gelernt, dass sobald bei einem PIC ein
> Interrupt aufgerufen wird das Global Interrupt Enable Flag auf
> 0 gesetzt wird. Bedeutet, sobald ein Interrupt aufgerufen wird,
> werden wietere Ignoriert.

Nein, das bedeutet nicht, dass sie IGNORIERT werden.
Es bedeutet, dass sie im Moment nicht zu einem Aufruf der Interrupt 
Service Routine führen. Aber registriert werden sie nach wie vor! Sobald 
die Interrupts global wieder freigegeben werden, wird dann der Aufruf 
dieser nächsten Interrupt Service Routine nachgeholt.

Das wäre ein ziemlich dämliches System, bei dem Interrupts generell 
verloren gehen würden, nur weil gerade eine andere Interrupt-Behandlung 
im Gange ist.

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.