Guten Abend zusammen, ich Arbeite mich gerade mit dem Buch von Roland Walter in die AVR Microcontroller Technik ein. Ich habe eine Verständnis Frage zu dem "USART Receive Complete" Interrupt. Ich lebe in der Annahme das wenn ich zwei Zeichen zu meinem Microcontroller sende bei einer niedrigen Baudrate zwischen beiden Zeichen genug zeit sein sollte um das Hauptprogramm einige male durchlaufen zu können. So wie ich es verstanden habe wird das "USART Receive Complete" Interrupt ausgelöst wenn ein byte im UDR fertig zur abfrage ist. Im Interrupt sollte es dann nur ausgelesen werden und zum Hauptprogramm zurückkehren bis ein neues Zeichen komplett empfangen ist. Wenn ich nun aber auf einen Schlag mehrere Zeichen sende z.B. "Hallo Welt", bleibt mein Microcontroller den kompletten Zeitraum in der Interrupt Routine und führt das Hauptprogramm nicht ein einziges mal aus, bis das letzte Zeichen empfangen wurde. Könnte mir jemand erklären warum das so ist? Warum wird zwischen den Zeichen kein einziges mal das Hauptprogramm ausgeführt? Lg Geyer
Es liegt an deinem Programm. Das was du erwarest ist genau das wie es normalerweise gemacht wird.
> Könnte mir jemand erklären warum das so ist?
Designfehler im nicht hergezeigten Code. Behelfsweise ein Bug an der
selben Stelle.
dann hier nochmal der Basic Programm Code. Wenn ich nun mehr als 10 Zeichen sende wird das Hauptprogramm erst ausgeführt wenn alle Zeichen übertragen wurden.
1 | $Regfile = "m8def.dat" |
2 | $Crystal = 3686400 |
3 | $Baud = 9600 |
4 | |
5 | Dim s As String*10 |
6 | |
7 | On URXC OnRxD |
8 | Enable URXC |
9 | Enable Interrupts |
10 | |
11 | Main: |
12 | If Len(s)>9 Then |
13 | Print s |
14 | s="" |
15 | End if |
16 | Goto Main |
17 | |
18 | OnRxD: |
19 | s=s+Chr(UDR) |
20 | Return |
Geyer schrieb: > Wenn ich nun aber auf einen Schlag mehrere Zeichen sende z.B. "Hallo > Welt", bleibt mein Microcontroller den kompletten Zeitraum in der > Interrupt Routine und führt das Hauptprogramm nicht ein einziges mal > aus, bis das letzte Zeichen empfangen wurde. Nö, tut er nicht. Er ist sogar 99.999% der zeit im Hauptprogramm. Jedesmal wenn ein einzelnes zeichen empfangen wurde, springt er in den Interrupt-Handler, speichert das Zeichen, und kehrt wieder zurück, solange bis das nächste Zeichen empfangen wurde. Allerdings wartet dein Hauptprogramm und tut solange nichts, bis 10 zeichen empfangen wurden.
Geyer schrieb: > OnRxD: > s=s+Chr(UDR) > Return ups, das sieht aber irgendwie bösartig aus... Was passiert denn, wenn sich gerademal keiner um s kümmert? Frisst s den gesamten RAM? Die Lösung für dein eigentliches Problem steht ja bei Michael - also neue suchen :-)
Aber auch wenn ich 20 Zeichen sende, bekomme ich erst eine Rückmeldung wenn alle 20 Zeichen gesendet wurden. Er gibt mir keine 10 zurück wenn diese angekommen sind, sondern erst wenn alle 20 angekommen sind. Und dann eben auf einen Schlag die 20. Ergo hat er den Test ob der String länger als 9 ist wohl nicht ausgeführt. Ich habe aus neugier mal einen Buzzer im Hauptprogramm summen lassen, und während ich Zeichen an den Microcontroller gesendet habe war der Buzzer komplett aus. Der Microcontroller hat das Hauptprogramm also nicht ausgeführt. Auf jedenfall schon mal danke für die Hilfe :) Aber irgendwas arbeitet hier gegeneinander. Kann es vielleicht Probleme machen wenn während dem Empfangen von Daten schon zurück gesendet werden soll?
Ich glaub dir nicht. Zumindest solange nicht, bis du nicht den kompletten Quellcode (soweit reduziert dass der Fehler noch auftritt) hier postest. Kein uC bleibt freiwillig in der ISR. Außer du sagst ihm dass er soll. Merke: Das programm macht was du schreibst, nicht was du willst.
Das ist der komplette Quellcode eins zu eins aus dem oben genannten Buch abgetippt. Ich bin dabei mich in das Thema einzuarbeiten, warum sollte ich da lügen? :) Ich benutzen einen USB zu rs232 Konverter, kann dieser das Signal beeinflussen? eigentlich auch nicht oder? Ich teste auf jedenfall nochmal den Code, und melde mich gleich nochmal ob der obige Zustand reproduzierbar ist.
Gut, ich weis an welcher stelle das Problem verursacht wird. Ich habe diesen Code genommen und anhand eines Buzzers an Pin PB0 "erhöhrt" wann das Hauptprogramm durchlaufen wird (ton/stille) und wann nicht.
1 | $regfile = "m8def.dat" |
2 | $crystal = 3686400 |
3 | $baud = 9600 |
4 | |
5 | Dim S As String * 10 |
6 | |
7 | |
8 | Ddrb.0 = 1 |
9 | |
10 | On Urxc Onrxd |
11 | Enable Urxc |
12 | Enable Interrupts |
13 | |
14 | Main: |
15 | If Len(s) > 9 Then |
16 | Print S |
17 | S = "" |
18 | End If |
19 | Portb.0 = Not Portb.0 |
20 | Waitms 5 |
21 | Goto Main |
22 | |
23 | Onrxd: |
24 | S = S + Chr(udr) |
25 | Return |
Wenn der Code wie oben genannt durchläuft ist der Buzzer wenn ich ihm z.B. 300 Zeichen sende über einen eindeutigen Zeitraum komplett aus. Wenn ich den "Print S" befehl weg lasse, und sonst alles gleich ist, bleibt der Buzzer auch während 300 an, aber auf einer geringeren Frequenz. Ich habe mich nun auch etwas Informiert: Der Print befehl Pausiert das Programm bis sämtliche Zeichen welche gesendet werden sollen auch tatsächlich raus sind. Daraus meine Annahme: Da in dem Beispiel der Print befehl erst ausgelöst wird wenn mindesten 9 Zeichen zu schreiben sind und die Eingehenden Zeichen etwa in der Gleichen Frequenz eingehen wie ausgehende wird der String während er im Print Vorgang ist konstant verlängert bis keine Zeichen mehr eingehen und der Print befehl das String ende erreicht. Während also der Interrupt mehrere male ausgelöst wird bleibt das Hauptprogramm sobald es das erste mal den Print befehl erreicht immer an dieser Stelle und führt bis alle Zeichen eingegangen sind das Hauptprogramm kein einziges mal mehr komplett aus. Vielen Dank für diese Hilfe zur Selbsterkenntnis :) Ich hab den Fehler einfach an der Falschen stelle gesucht. Hoffentlich stößt irgendwer einmal auf das hier und erspart sich dadurch das elendigliche Fehlersuchen suchen :) und bitte unterstellt keinem Anfänger mehr das Lügen.
Geyer schrieb: > Während also der > Interrupt mehrere male ausgelöst wird bleibt das Hauptprogramm sobald es > das erste mal den Print befehl erreicht immer an dieser Stelle und führt > bis alle Zeichen eingegangen sind das Hauptprogramm kein einziges mal > mehr komplett aus. Klingt vernünftig! Leider hab ich das PRINT übersehen... Geyer schrieb: > und bitte unterstellt keinem Anfänger mehr das Lügen. Keine Angst, ich hab dir nicht "Lüge" unterstellt. Es ist nur leider so, dass hier dauernd (mehrmals täglich) eins von diesen (oder beides zusammen) passiert: a) Code wird nicht reinkopiert sondern abgeschrieben, beim Abschreiben passieren Fehler, und wir suchen dann Fehler wo keiner ist b) Code wird unvollständig gepostet. Es fehlen Deklarationen, ISR, ... oft stekt der Fehler in diesen weggelassenen Stellen, und dann müssen wir wieder raten.
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.