Forum: Mikrocontroller und Digitale Elektronik LCD an Atmega32--> zu langsam für Rotary


von Andreas (Gast)


Lesenswert?

Hallo,

ich habe an einem Atmega32 ein LCD-Display. 16 x 2! Über einen 
Rotary-Encoder (der auf einem Interrupt liegt) will ich am Display durch 
ein Menü scrollen.
Da ich die "LCD"-Funktion in der Interrupt-Routine drinnen hab und die 
bekanntlich sehr langsam ist, verliere ich Zählschritte beim Rotary und 
somit auch im Menü. (beim schnellen drehen)
Wie könnte ich dieses Problem lösen? "LCD" - Funktion in einen Timer ?

vielen dank.
lg

von Bernd O. (bitshifter)


Lesenswert?

LCD raus aus der ISR.

von Andreas (Gast)


Lesenswert?

und wohin ??? .gg.
Wenn ich das mit einer Sub mache, dauerts ja trotzdem gleich lang oder?

von Bernd O. (bitshifter)


Lesenswert?

Wie liest Du denn den Drehgeber aus? Löst der Drehgeber etwa den 
Interrupt aus?

Eine saubere Lösung wäre es, den Drehgeber in einer 1ms-Timer-ISR 
auszulesen, (also polling) und die Bearbeitung des Menüs und des LCDs in 
die main()-Endlosschleife zu verlagern.
Drehgeber -> ISR ist kritisch - insbesondere wenn der Geber prellt oder 
schlimmer noch mechanisch knapp zwischen Kontakt und kein Kontakt steht. 
Das führt dann zu heftigen ISR-Stürmen mit entsprechend negativen 
Auswirkungen auf das Restprogramm.

Gruß,
Bernd

von Bernd O. (bitshifter)


Lesenswert?

Andreas schrieb:
> und wohin ??? .gg.
> Wenn ich das mit einer Sub mache, dauerts ja trotzdem gleich lang oder?
Sicherlich, aber das Auslesen des Drehgebers und anderer ISRs wird nicht 
mehr behindert. Und in der Main brauchst Du ja nicht alle Menüeinträge 
einen nach dem anderen zeichnen. Wenn der Drehgeber vier Einträge 
weitergedreht wird während das Menü noch gezeichnet wird, brauchst Du ja 
nicht die drei Menüs die dazwischenliegen zeichnen, sondern zeichnest 
einfach die jeweils aktuellste Einstellung.

Wenn Drehgeber und LCD-Menü in der gleichen ISR liegen, dann wird das 
oft quälend langsam wenn der Benutzer zusehen muß wie das Programm 
mühsam die schon weggedrehten Menüs aufbaut nur um bei Fertigstellung 
gleich das nächste (nichtbenötigte) Menü aufzubauen. Wenn ich bei Menü 1 
bin und per Drehgeber schnell auf Menü 5 drehe, dann will ich dazwischen 
nicht Menü 2 bis Menü 4 sehen.

Gruß,
Bernd

von Andreas (Gast)


Lesenswert?

ok vielen dank für die antworten.

jetzt hab ich noch eine frage: wenn ich in der isr in eine sub springe, 
dann steht die isr ja genau gleich lange oder ?und zwar genau bis zum 
dem zeitpunkt wo ein return steht ?! oder liege ich da flasch? das läuft 
ja nicht parallel und die sub blockiert ja auch die isr bis sie fertig 
ist ?!

von xyz (Gast)


Lesenswert?

ja!

von Bernd O. (bitshifter)


Lesenswert?

Andreas schrieb:
> ok vielen dank für die antworten.
>
> jetzt hab ich noch eine frage: wenn ich in der isr in eine sub springe,
> dann steht die isr ja genau gleich lange oder ?und zwar genau bis zum
> dem zeitpunkt wo ein return steht ?! oder liege ich da flasch? das läuft
> ja nicht parallel und die sub blockiert ja auch die isr bis sie fertig
> ist ?!
So ist es. Die Funktion läuft im Kontext der ISR und die ISR läuft damit 
entsprechend länger.

ISR immer so kurz wie möglich halten und nur das nötigste in der ISR 
erledigen. Beim Beispiel Drehgeber nur schnell die beiden Pins und 
Taster abfragen, erkennen ob sich etwas geändert hat und eine (globale) 
Variable aktualisieren, an der man den Zustand des Drehgebers vom 
restlichen Programm aus abfragen kann und raus. Kein Menü, keine weitere 
Bearbeitung - das gehört alles in die Main-Endlosschleife.

Dadurch hast Du zwei getrennte "Ebenen". Die Main-Ebene, die beliebig 
langsam sein darf - für User-IO, Menü, Berechnungen, ... und die 
ISR-Ebene, die von der Main-Ebene getrennt ist und immer schnell auf 
Hardware-Ereignisse reagieren kann (PWM, Drehgeber, ADC, I2C, SPI, ...).

Natürlich gibt es auch Grenzfälle, bei denen die ISR aufgebohrt werden 
muß, aber das ist eher selten. Ich programmiere schon viele Jahre lang 
und es war nur einmal nötig (war ein schnelles Protokoll (ähnlich CAN, 
bei dem direkt in Abhängigkeit vom empfangenen Inhalt reagieren musste - 
hier war es unumgänglich einen großen Teil des Protokollstacks in die 
ISR zu verlagern.

Meist ist es aber einfach schlechtes Design, wenn viel Code in einer ISR 
steht.

Gruß,
Bernd

von Peter D. (peda)


Lesenswert?

Die ISR für den Encoder zählt einfach nur ne Variable rauf bzw. runter 
und das Main wertet dann die Variable aus und zeigt entsprechend an.


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
Noch kein Account? Hier anmelden.