Forum: Mikrocontroller und Digitale Elektronik LCD mit Interrupt möglich?


von Matze N. (hupe123)


Lesenswert?

Hi

ich möchte auf einem LCD-Display alle 10ms sieben Messwerte ausgeben 
lassen. Jeder Messwert hat die Länge von 5 Zeichen.
Nun hab ich aber das Problem, daß mein Display für anstatt 1s für 700 
Messwerte plötzlich ca. 10s braucht. Ich weiß, daß liegt an den vielen 
Pausen,die das Display sich gönnt.
Nun meine Frage: kann man diese ganzen Pausen auch irgendwie anders 
lösen. Ohne das mein µC in Warteposition steht - der hat nämlich 
eigentlich noch anderes zu tun. Zum Beispiel diese Messwerte über einen 
UART rauszupusten.

Ich bin für alle Lösungen offen!
Danke

von spess53 (Gast)


Lesenswert?

Hi

>ich möchte auf einem LCD-Display alle 10ms sieben Messwerte ausgeben
>lassen.

Und wer soll das lesen???

MfG Spess

von Michael U. (amiga)


Lesenswert?

Hallo,

ich erlaube mir mal die Fragem wer ein 100Hz Geflimmer von Meßwerten auf 
einem LCD lesen können soll?
Wenn sich die Werte so oft ändern, gibt es unlesbares Geflacker und wenn 
sich sich nicht so oft ändern, gibt es keinen Grund, sie so oft anzeigen 
zu wollen.

Gruß aus Berlin
Michael

von Walter (Gast)


Lesenswert?

und du liest die 700 Messwerte pro Sekunde?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> alle 10ms ... Messwerte ausgeben
Kann das Display seine Kristalle überhaupt so schnell umschalten?  :-o

von Matze N. (hupe123)


Lesenswert?

eigentlich lese ich sogar 800 messwerte/s, aber das ist egal.
Ich habs eben mal ausgerechnet: mein µC befindet sich für einmal 7 
Messwerte schreiben 89,124ms  in der Warteschleife.
Vielleicht kann man den Schreibtakt auf 1/s herabsetzen, aber dennoch is 
er dann ca. 90ms mit wärmeproduzieren beschäftigt...

Das muß doch besser gehen!

von spess53 (Gast)


Lesenswert?

Hi

>Ich habs eben mal ausgerechnet: mein µC befindet sich für einmal 7
>Messwerte schreiben 89,124s  in der Warteschleife.

In welcher Warteschleife??

MfG Spess

von Matze N. (hupe123)


Lesenswert?

Naja, diese doofe _delay_ms funktion

von spess53 (Gast)


Lesenswert?

Hi

Welcher halbwegs intelligente Mensch benutzt DELAYS?

MfG Spess

von Stefan M. (celmascant)


Lesenswert?

Die Frage hab ich mir auch schon gestellt.
Das LCD braucht nach jeder Datenübertragung eine Pause um die Daten zu 
verarbeiten.
Im Tutorial sind dazu Warteschleifen programmiert, wo der MC einfach 
sinnlos vor sich hin Zählt. Zum verdeutlichen der aktuellen Situation 
hier mal der Warteschleifen-Auszug aus meiner 8bit-Routine:
(Sollte eigendlich das gleiche wie im Tutorial sein)
1
;**********************************************************************
2
;
3
 ; Pause nach jeder Übertragung
4
delay50us:                              ; 50us Pause
5
           push temp1
6
       ldi  temp1, ( XTAL * 50 / 4 ) / 1000000
7
delay50us_:
8
       nop
9
           dec  temp1
10
           brne delay50us_
11
       pop temp1
12
           ret                          ; wieder zurück
13
14
 ; Längere Pause für manche Befehle
15
delay5ms:                                ; 5ms Pause
16
           push temp1
17
       push temp2
18
       ldi  temp1, ( XTAL * 5 / 607 ) / 1000
19
WGLOOP0:   ldi  temp2, $C9
20
WGLOOP1:   dec  temp2
21
           brne WGLOOP1
22
           dec  temp1
23
           brne WGLOOP0
24
       pop temp2
25
       pop temp1
26
           ret                          ; wieder zurück
27
28
29
;**********************************************************************

Kann man das irgendwie per Interupt regeln? Die Rechenzeit muss doch 
irgendwie sinnvoll zu nutzen sein...

Gruss Stefan

von micha (Gast)


Lesenswert?

Die meisten Dispalys haben auch ein Busy-Flag...

von spess53 (Gast)


Lesenswert?

Hi

>Das LCD braucht nach jeder Datenübertragung eine Pause um die Daten zu
>verarbeiten.

Welches?

MfG Spess

von Michael U. (amiga)


Lesenswert?

Hallo,

es wurde zwar kein Display-Typ genannt, aber bei allen mir bekannten 
Display-Controllern kann man dann doch einfach vor der nächsten Ausgabe 
das Busy-Flag des Display abfragen.

Man kann das natürlich auch in einen Timer-Interrupt legen und z.B. alle 
5ms o.ä. ein Zeichen aus aus einem Displaybuffer ausgeben. Wenn man die 
Zeit passen wählt, muß man garnicht warten, höchstens bei Befehlen mit 
langer interner Laufzeit (Clear o.ä.).

Gruß aus Berlin
Michael

von Matze N. (hupe123)


Lesenswert?

Ich arbeite noch nicht solange mit µC. Das ist das erste mal, daß ich 
delays doof finde. Und anstatt hier doof rumzumaulen

>Welcher halbwegs intelligente Mensch benutzt DELAYS?

würde ich mich freuen, wenn ein solcher Kommentar mit einem Tipp 
versehen ist.

Blöd rumkacken kann jeder...

von spess53 (Gast)


Lesenswert?

Hi

>Blöd rumkacken kann jeder...

Schon mal weiter gelesen?

MfG Spess

von Michael U. (amiga)


Lesenswert?

Hallo,

dann beantworte doch wenigstens die Frage wozu Du 700 Werte in einer 
Sekunde auf ein Display ausgeben willst!

Gruß aus Berlin
Michael

von kurz (Gast)


Lesenswert?

Na, na mal nicht so patzig.

Die Botschaft lautet: Delays sind hier eine schlechte Lösung (wie 
meistens, aber das geht in viele Hirne nicht rein)


So wie Du schreibst hast Du die Software selbst geschrieben und ab und 
an was abgeschaut.

Es kamen schon sehr vernünftige Vorschläge wie Timerinterrupt und 
Busy-Flag. War da nichts dabei? Kann fast nicht sein.

Also ran an den PC oder sonstwas Rechner und die Vorschläge in 
Programmzeilen gießen. Was hält Dich ab?

von Matze N. (hupe123)


Lesenswert?

Nichts, ich war nur grad eine Rauchen.

Wie das mit dem TimerInterrupt  funktionieren soll, weiß ich noch nicht. 
Was das is, allerdings schon - auch schon häufig benutzt.
Das mit der Busy-Flag is na klasse Idee - hätt ich selber drauf kommen 
können :)
Problem daran is bloß, daß mein µC mit 3,3V arbeitet und ich für das 5V 
Display nen 74HCT244-Pegelwandler benutze, der leider nur in eine 
Richtung Wandeln kann: 3,3 -> 5,0 V

Zu meinem Tonfall: Sorry, ich sitze schon 7 Std am PC... Kommt nicht 
wieder vor!

Gruß

von Sebastian (Gast)


Lesenswert?

Du kannst mit nem Spannungsteiler ganz einfach aus den 5V 3,3V machen. 
Sind nur 2 Widerstände.

von kurz (Gast)


Lesenswert?

Mit dem Timerinterrupt ist doch ganz einfach.

Im Hauptprogramm oder sonst wo bastelst Du Dir einen Ausgabestring 
zurecht, auf einem Array. Im Timerinterrupt gibst Du Byte für Byte an 
die Anzeige raus. Etwas Softwarehandshake zwischen Interrupt-Routine und 
Stringerstellung ist nötig.

- Stringlänge, Ausgabestelle in der Anzeige
- Flag für String fertiggestellt -> ausgeben im Interrupt
- Flag für String ausgegeben -> neuen erstellen im HP.

PC-Pause ist immer gut. Mach ich auch gleich wieder.

von Matze N. (hupe123)


Lesenswert?

Ja, stimmt. Die Idee kam mir auch grad. Aber ich habe ein neues Problem.

Selbst wenn ich auf die Busy-Flag warte, warte ich doch auch. Das übrige 
Programm hängt dann auch und die Werte, die in dieser Zeit bekomme, kann 
ich dann auch nicht abarbeiten. Ich müßte, und das is jetzt nur 
gesponnen, ein paralleles abarbeiten von zwei getrennten strängen... 
einen zweiten processor sozusagen.
Moment, kann ich mein eingangssignal (ein I²C) auch an zwei µCs 
einlesen? Dafür bräuchten sie dann aber eine synchronisierte SCL... auch 
doof!

Tipps?

von Matze N. (hupe123)


Lesenswert?

Zu den Interrupts:

Du meinst, ich generiere ein Timer, der 1ms läuft. Dann greift er sich 
die volatile mit dem messwert und zwar nur das erste, halbe byte 
(4-Leitungs-Bus) überträgt es. danach den timer neu starten. dann das 
zweite, halbe byte. dann hat das hauptprogramm einen neuen Messwert 
errechnet, usw usw.
meinst du das so?

von Peter D. (peda)


Lesenswert?

spess53 schrieb:
> Welcher halbwegs intelligente Mensch benutzt DELAYS?

Ich z.B..

50µs Delay ist voll o.k., das machen 99% aller LCD-Routinen so und es 
ist überhaupt kein Rechenzeitproblem.

Er will ja nur 7 Werte a 5 Zeichen ausgeben, das sind dann also 1,8ms.

10ms Updaterate ist allerdings Schwachsinn.
Man sollte schon auf Ergonomie Wert legen, d.h. maximal 2..5 
Aktualisierungen pro Sekunde.

Bei 5 Aktualisierungen/s sind das also 1,8ms je 200ms, also riesige 
wahnsinns 0,9% CPU-Last!

Da ist es einfach nur lächerlich, auf den Delays rumzuhacken.
Das macht jede CPU mit links und 40 Fieber.


Peter

von Dietmar (Gast)


Lesenswert?

Nimm FreeRTOS, lass den LCD-Task mit niedriger Priorität laufen, benutze 
Multitasking-freundliche Wartefunktionen für ms-Delays (vTaskDelay
). Je komplexer das Projekt, desto eher lohnt sich FreeRTOS.

von kurz (Gast)


Lesenswert?

>Selbst wenn ich auf die Busy-Flag warte, warte ich doch auch. Das übrige
>Programm hängt dann auch und die Werte, die in dieser Zeit bekomme, ..


Nix Warten - Busy abfragen geht anders:

Das Anzeigenprogramm liegt in der Hauptprogrammschleife.

- das Hauptprogramm kommt beim Anzeigenprogramm vorbei
- das ANZ-Porg fragt das Busy-Flag ab
    - Anzeige ist noch busy -> zurück ins HP weiter Messen, rechnen
                                                    Uart bedienen usw.

    - Anzeige ist ready -> ein Byte ausgeben -> zurück ins HP


Schon hast Du 2 Prozesse quasi parallel laufend.

von Peter D. (peda)


Lesenswert?

Dietmar schrieb:
> Nimm FreeRTOS, lass den LCD-Task mit niedriger Priorität laufen,

Dann kommst Du vom Regen in die Traufe.
Die 50µs Wartezeit wird warscheinlich schon ein Taskwechsel komplett 
aufbrauchen.
Für solche kleinen Wartezeiten ist ein RTOS ungeeignet.


Peter

von Peter D. (peda)


Lesenswert?

Und hier mal eine Interruptlösung:

Beitrag "Formatierte Zahlenausgabe in C"

Ich setze sie aber bisher nicht praktisch ein, war mehr ne Designstudie, 
obs geht.

Ich nehme die standard 50µs warten 4-Bit LCD Ansteuerung. Und ein 
Scheduler in der Mainloop ruft sie alle 200ms auf.


Peter

von Matze N. (hupe123)


Lesenswert?

So, ich denke, ich habs:
- ich habe eben das Display an seine zeitlichen Grenzen gebracht - das 
hat ganzschön was gebracht.
- dann habe ich mir eben noch mal angeschaut, wie 3 Messwerte/s 
aussehen, und man sieht, daß 100 wirklich übertrieben waren.
- außerdem werde ich jetzt einen Timer entwerfen, der alle 50ms abläuft 
und werde dann einen messwert auf das LCD bannen (50ms * 7 = 350ms, also 
2,85 Aktuallsierungen / s)

Das mus reichen!

Danke für allen guten Ratschläge, ich bin wieder etwas schlauer!

von Dietmar (Gast)


Lesenswert?

> Die 50µs Wartezeit wird warscheinlich schon ein Taskwechsel komplett 
aufbrauchen. Für solche kleinen Wartezeiten ist ein RTOS ungeeignet.

Er soll für die ms-Wartezeiten (5ms == 5000us), die bei bestimmten 
Befehlen anfalle, z.B. beim Clear-Befehl, das Multitasking-freundliche 
Delay nehmen. Der Task-Switching-Overhead spielt dabei keine 
erwähnenswerte Rolle. Das sind einige Dutzend us.

Die us-Wartezeiten programmiert er natürlich wie bisher als 
Busy-Waiting. Das wird durch das Multitasking entschärft: Der LCD-Task 
blockiert die CPU unter FreeRTOS nur bis zum nächsten Taskwechsel - der 
kommt z.B. in 1ms (oder wenn ein Interrupt einen höher prioritisierten 
Task aufweckt).

Insgesamt nimmt der LCD-Task so kaum Rechenleistung der CPU in Anspruch 
- ohne dass man grossartig nachdenken muss. Voraussetzung ist, dass das 
Display es nicht übel nimmt, wenn us-Pausen plötzlich länger dauern. 
Sollte bei 4bit so sein (ist bei meinem so - das blaue 16x2 von Pollin). 
Notfalls müsste man um bestimmte us-Delays herum das Task-Switching 
abstellen.

Ich verwende in meinem Programm so einen LCD-Task (und eine Mess-Task 
und einen InputHandler-Task usw.) und halte das für eine sehr angenehme 
Lösung. Die Tasks schicken sich über Queues Nachrichten zu - z.B. was 
anzuzeigen ist - und sind stark von voneinander entkoppelt. So kann man 
auch sehr komplexe Programme schreiben, ohne sich im Interrupt-Kleinkram 
zu vertüddeln.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also ich würde es so machen, leg dir einen puffer für dieser 5 Zeichen 
an. Starte einen Timer der alle 50ms eines der Zeichen auf das Display 
schreibt.
Dann brauchst du keine Wartezeit und über das Display brauchst du dir 
auch keine Gedanken machen sooo lange braucht kein Befehl.
Vorteil ist halt auch das du jederzeit und belibig oft/schnell auf 
diesen Buffer schreiben kanns von überall aus deinem Programm heraus.
Kann man natürlich auch auf das ganze LCD ausweiten .

von Hannes Lux (Gast)


Lesenswert?

Ich nutze seit einiger Zeit einen "Bildschirmspeicher" im AVR, in dem 
jede Byteposition einer Ausgabeposition entspricht. Das Hauptprogramm 
darf da dann jederzeit neue Texte reinschreiben.

Ein vom Timer-Interrupt über Flag synchronisierter Job der Mainloop 
schaufelt jede Millisekunde (neben anderen Aufgaben wie z.B. 
Drehgeberauswertung) ein Byte davon an das LCD und entwirrt dabei den 
Zeilenverschachtelungssalat.

Der Bildschirmspeicher hat also durchgehende Adressen und kann auch mit 
Fließtext beschrieben werden.

Achja, in einem 1ms-Takt werden beide Nibbles des Bytes geschrieben, 
eine Wartezeit zwischen beiden Nibbles ist nicht nötig.


In einem anderen Projekt (Bedienteil zum Parametrieren von 
Feuerwerks-Zündgeräten) mit Tiny2313 und LCD 4x40 (wo der SRAM nicht für 
einen Bildschirmspeicher reicht), habe ich das "Hauptprogramm" (Tasten 
abfragen, UART bedienen) in die Wartepausen des LCDs verlegt.

Ein Timer setzt alle 1ms ein Flag. Die Hauptschleife gibt in diesem Takt 
byteweise reihum eine Überschrift, 20 Parameter und einen 
kontextabhängigen Menütext aus, wobei der zu ändernde Parameter blinkend 
dargestellt wird. Statt Busywait oder Warteschleife werden hier die 
anderen Jobs des Programms ausgeführt, wie jedes 16. mal (alle 16 ms) 
Tasten entprellen, UART auf Empfang prüfen und Byte wegräumen, UART 
Senden, falls erforderlich und UDR leer ist.


Der optimale Lösungsweg ist immer auch etwas von der zu lösenden Aufgabe 
abhängig, eine Superlösung, die immer und überall optimal ist, wird es 
nicht geben.

...

von Stefan M. (celmascant)


Lesenswert?

Danke für eure Antworten!

Da sind einige gute Anregungen dabei. Im nächsen Projekt werd ich die 
Interupt-LCD-Ansteuerung mal ausprobieren.

Eigendlich hätte ich da mit ein bisschen mehr Überlegung selbst drauf 
kommen können, auch auf das Busy-Flag...

Nochmal Danke^^

Gruss Stefan

von TheMason (Gast)


Lesenswert?

wo wir gerade schonmal bei interrupts und lcd sind :

mir ist da vor einiger zeit (ca nem jahr oder so) eine idee gekommen.
wenn man im timerinterrupt die 4-6 userdefinierbaren zeichen mit einem 
teil aus einem frame-buffer füllt, diese 4-6 zeichen auf einem display 
darstellt, im nächsten interrupt dann wieder 4-6 zeichen füllen und auf 
dem display ausgibt (also 4-6 zeichen weiter) und so weiter ... damit 
müssten sich doch auf einem text-display schon fast grafiken darstellen 
lassen können oder ? abgesehen von den zwischenräumen zwischen den 
zeichen und dadurch das immer nur teile der grafiken angezeigt werden 
dürfte die darstellung auch nicht allzu rosig aussehen, aber denkbar 
wäre es oder ? hat jemand sowas schonmal ausprobiert ?

von Matze N. (hupe123)


Lesenswert?

Hi,

ich auch wenn ich ein bißchen die euphorie nehme, aber ich habe heute 
versucht, das troggeln der e-Leitung per Busy-Flag zu lösen und ich habs 
nich geschafft, die einmal 10us und die 20us zu ersetzen - aber 
vielleicht war ich auch einfach nur zu blöd... auch die interruptroutine 
mußte deswegen bei mir je zeichen 60us warten... doofe sache.

Falls jemand die Zeiten beim KS0066U lösen kann, bitte ich um quelltext 
:)

Gruß und danke dennoch für alle klugen köpfe!

von Philipp B. (philipp_burch)


Lesenswert?

TheMason schrieb:
> wo wir gerade schonmal bei interrupts und lcd sind :
>
> mir ist da vor einiger zeit (ca nem jahr oder so) eine idee gekommen.
> wenn man im timerinterrupt die 4-6 userdefinierbaren zeichen mit einem
> teil aus einem frame-buffer füllt, diese 4-6 zeichen auf einem display
> darstellt, im nächsten interrupt dann wieder 4-6 zeichen füllen und auf
> dem display ausgibt (also 4-6 zeichen weiter) und so weiter ... damit
> müssten sich doch auf einem text-display schon fast grafiken darstellen
> lassen können oder ? abgesehen von den zwischenräumen zwischen den
> zeichen und dadurch das immer nur teile der grafiken angezeigt werden
> dürfte die darstellung auch nicht allzu rosig aussehen, aber denkbar
> wäre es oder ? hat jemand sowas schonmal ausprobiert ?

Wenn ich mich recht entsinne, wirken sich geänderte Zeichen auch auf den 
bereits dargestellten Text aus. Es sind also nie mehr als acht 
verschiedene, zusätzliche Zeichen vorhanden.
Das Oszi auf dem Text-LCD (Siehe youtube) nutzt dieses "Feature", die 
Wellenform wird dabei nur über die anpassbaren Zeichen verändert, die 
aneinandergereiht den vollen "Bildschirm" von umwerfenden 8x40 Pixeln 
darstellen ;)

Bezieht sich jetzt alles auf HD44780-Displays.

von TheMason (Gast)


Lesenswert?

>wirken sich geänderte Zeichen auch auf den
>bereits dargestellten Text aus.

das ist mir bewusst ;-) deswegen dachte ich auch daran (ok ich hatte es 
nicht dabei geschrieben) die nicht in dem aktiven "segment" 
darzustellenden zeichen einfach durch spaces ersetzen. das heißt zwar 
das man bei allen 4 partiellen-grafik-zeichen die dargestellt werden 
immer das komplette display leer schreiben muß und das dürfte sich auf 
die helligkeit bzw darstellung eben auswirken ... aber denkbar wäre es 
doch oder ?

ich pinsel das mal schematisch für ein 8x2 display auf

1.
"1111    "
"        "

2.
"    2222"
"        "

3.
"        "
"3333    "

4.
"        "
"    4444"

die zahlen 1-4 beziehen sich auf die zeichen im cg-ram die immer in 
vierer-gruppen aus dem frame-buffer kopiert werden.

ok. der nachteil an der lösung wäre das die helligkeit der einzelnen 
pixel auf 1/4 schrumpft da so oft umgeschaltet wird, aber das müsste man 
einfach mal austesten ...

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.