mikrocontroller.net

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


Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
LCD raus aus der ISR.

Autor: Andreas (Gast)
Datum:

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

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andreas (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?!

Autor: xyz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja!

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.