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
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