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
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.
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
@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!
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.
> 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.