Hallo Forum, Im angehängten Problembeispiel möchte ich einen ADC-Kanal auslesen und das Ergebnis auf einem LCD anzeigen. Mein Problem ist, dass ich neben meiner Ausgabe viele falsche Zeichen auf unterschiedlichen Positionen durch das LCD springen habe. Dies kann ich dadurch umgehen, dass ich während dem Ausgabestringzusammenbau die Interrupts ausschalte - was aber in einem wirklichen Projekt dazu führt, dass meine LCD-Ausgabe und die ganzen Interrupt-disable das Timing zerstören. Daher das Beispiel: Ich möchte im Timerinterrupt millisekündlich ein Zeichen an ein LCD-Display senden. Hierzu habe ich 2 Puffervariablen, welche den LCD-Inhalt als String aufnehmen. In Main befülle ich die Variable lcd_puffer2 und kopiere sie einmal pro Durchlauf in die Variable lcd_puffer. Da die Variable lcd_puffer im Timerinterrupt byteweise an das Display gesendet wird, werden während dem kopieren die Interrupts unterdrückt. Um nun etwas zum Anzeigen zu haben, lese ich einen ADC-Kanal aus und lege im ADC-Interrupt das Ergebnis in die Variable Adc_wert. In Main kopiere ich bei unterdrückten Interrupts die Variable Adc_wert in eine Hilfsvariable, wandle diese in einen String um, setze Namen und Einheit dazu und möchte sie ausgeben. Wieso sind für eine fehlerfreie Ausgabe die zusätzlichen Interrupt-Disable notwendig, obwohl ich dabei auf keine in Interrupts zu bearbeitende Variablen zugreife? Was kann/muss ich besser machen? Vielen Dank im Voraus LCD-Ausgabe
> LCD-Ausgabe im Timerinterrupt (BASCOM)
Was hat eine LCD-Ausgabe in einer ISR zu suchen? Die goldene Regel für
Interrupts: "So kurz wie möglich, so lang wie nötig".
Hallo, Die LCD-Ausgabe ist in diesem Fall ja nur ein wenig Bitschubserei und paar mal Wackeln am PortB. Hiermit umgehe ich die Warterei bis das LCD wieder bereit für was neues ist, wie ich es in der Main hätte. Spätestens nach 1 ms, also im neuen Timer-Interrupt ist das LCD wieder bereit für neue Daten Desweiteren wäre es auch nicht notwendig das LCD so häufig pro Sekunde zu beschreiben - aber das ändert ja nichts am beschrieben Problem - es tritt nur seltener auf. Und mit starrem Text - ohne Ausgabe des ADC-Wertes tritt auch kein derartiges Geflacker auf. Gruß LCD-Ausgabe
Und wenn man mehrere Aufgaben zu erledigen und kein Multitasking hat, dann sind delays im Hauptprogramm der Falsche weg um Timings zu erzeugen. Der Timerinterrupt bietet sich in deinem Fall perfekt an um Jobs in der Hauptschleife anzutriggern. Gruß Skriptkiddy
Hallo, der delay im Hauptprogramm ist hier nur Füllstoff um Timerinterrupt und Main-Durchläufe unsynchron zu bekommen, im richtigen Code läuft hier das Statemachine-Menü, die Drehgeberweiterrechnerei, die eigentliche Ablaufsteuerung und Regelung und mein Problemfall: das Zusammenbasteln der LCD-Ausgabe. Alles ohne delays, aber je nach Betriebsmode in unterschiedlichen Durchlaufzeiten. Mein Problem seh ich weniger in der Beschickung des Displays mit Daten, als mehr in der Tatsache, dass der String, den ich aus Interrupt-unangetasteten Werten zusammensetze durch die möglicherweise währenddessen stattfindenden Interrupte verfälscht wird. Gruß LCD-Ausgabe
Mach die LCD-Ausgabe auch ins Hauptprogramm, dann sollte alles schön synchron laufen.
Hallo, ich denke etwas gefunden zu haben. Führe ich die Datenübertragung zum LCD direkt in der ISR aus, ohne den Umweg in die Sub, erhalte ich eine saubere, fehlerfreie Ausgabe, ohne die Interrupte im Main auszusperren. Im Anhang das geänderte Programm. Möglicherweise ist dann das Cursor at home nach jeder LCD-Beschreibung auch nicht mehr vonnöten Gruß LCD-Ausgabe
LCD-Ausgabe schrieb: > ich denke etwas gefunden zu haben. > Führe ich die Datenübertragung zum LCD direkt in der ISR aus, ohne den > Umweg in die Sub, erhalte ich eine saubere, fehlerfreie Ausgabe, ohne > die Interrupte im Main auszusperren. kopfschüttel
Skript Kiddy schrieb: > > > Mach die LCD-Ausgabe auch ins Hauptprogramm, dann sollte alles schön > synchron laufen. Auch das werde ich morgen oder Montag am eigentlichen Projekt versuchen. Danke LCD-Ausgabe
Das An- und Abschalten von Interrupts ist aber dennoch eine gängige Praxis, um Daten größer einer Wortbreite im präemptiven Betrieb konsistent zu halten. Gruß Skriptkiddy
Hallo, hier mal als Rückmeldung. Es ist wohl tatsächlich so, dass es bei Subs mit Parameterübergabe welche aus einer ISR aufgerufen werden Unzuverlässigkeiten bei den übergebenen und ankommenden Parametern gibt. Das direkte Einfügen des selben Codes in die ISR funktioniert zuverlässig - damit klappt meine Dispayausgabe wie gewünscht. Mit dem vorgeschlagenen Beispiel, in der ISR nur ein Flag zu setzen und dann in der Main ein Zeichen an das Display zu senden ist mir die LCD-Ausgabe zu langsam. Ein Main-Durchlauf dauerte im richtigen Projekt 4,5 ms - das Display (4*80 Zeichen) wurde damit zu selten aktualisiert - ein Anwählen bestimmter Werte mit Drehgeber wurde deutlich langsamer erreicht. mfG LCD-Ausgabe
Wird ein LCD für viele verschiedene Daten verwendet, ist es in der Tat sinnvoll, die Ausgabe per Timerinterrupt zu machen. Dann braucht nicht jede Ausgabe umständlich zu positionieren und das Busy-Waiting entfällt auch. Man legt dazu nur einen Puffer im SRAM an und jede Anwendung schreibt blitzschnell da hinein. Der Timerinterrupt kümmert sich um die Darstellung. In Bascom müßte man für solche Spezialfälle, die von den fertigen Modulen abweichen, dann die LCD-Routine selber schreiben, sonst wird doch noch im Interrupt unnütz gewartet. Hier ein Beispiel in C: Beitrag "Formatierte Zahlenausgabe in C" Peter
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.