mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD Ausgabe dauert zu lange


Autor: Patrick L. (crashdemon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich benutze die LCD Routine aus dem AVR-GCC Tutorial und gebe ein wenig 
Text und ein paar Variablen über das LCD aus.
Funktioniert soweit ganz gut, allerdings bastel ich gerade an einem 
Stopuhr-Projekt und hier dauert die ganze Ausgabe zu lange, was 
warscheinlich an meinem vorgehen beim ausgeben des/der Textes/Variablen 
zusammenhängt.

zurzeit gebe ich den text/variablen folgendermaßen aus:
lcd_string("minunten: ");
lcd_string(variable_für_Minuten);

lcd_string("sekunden: ");
lcd_string(variable_für_Sekunden);

....
.... usw

jetzt möchte ich um zeit zu sparen, erst den ganzen text und meine 
variablen die ich habe in einen string laden und dann alles in einem 
rutsch auf dem lcd ausgeben, was dann hoffentlich die durchlaufszeit 
senkt.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

lcd_string("minunten: ");
meine heißen noch minuten... ;-)

lcd_string(variable_für_Sekunden);
bei Umlauten in Variablennamen bekomme ich auch heutzutage immernoch 
Bauchweh. Naja, bin wohl schon zu alt...

Zu Deinem Problem:
Ohne Deine Routinen genauer zu kennen: was ist bei Dir langsam?
Wenn in Sekunden gezählt wird, wird das Display doch wohl ohne Probleme 
auch so zu aktualisieren gehen.

Ansonsten mußt Du ja nur an der richtigen Position die Zahlen ausgeben, 
Deine Texte scheinen sich ja nicht zu ändern, die vergisst das Display 
schon nicht.

Gruß aus Berlin
Michael

Autor: ... (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt Oerationen im LCD, die dauern lange, und andere, die sind 
schneller. Der Standardansatz ist ein Zeichen pro Timertick 
rauszulassen. Das ist vielleich hier weniger passend. Kein problem. Dann 
muss man eben diese Routine neu schreiben.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Patrick Langosch schrieb:
> Funktioniert soweit ganz gut, allerdings bastel ich gerade an einem
> Stopuhr-Projekt und hier dauert die ganze Ausgabe zu lange, was
> warscheinlich an meinem vorgehen beim ausgeben des/der Textes/Variablen
> zusammenhängt.

Das wirds sein, Du mußt Stopuhr und Anzeige trennen.
Die Stopuhr machst Du im Timerinterrupt, anders kriegst Du die eh nicht 
genau.
Und dann machst Du die Anzeige in der Mainloop etwa alle 200ms. 
Schneller ist Unsinn, da ein Mensch nicht schneller ablesen kann. Es 
wird dann nur ein Geflimmer, also unergonomisch.


Peter

Autor: Patrick L. (crashdemon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. schrieb:
> lcd_string(variable_für_Sekunden);
> bei Umlauten in Variablennamen bekomme ich auch heutzutage immernoch
> Bauchweh. Naja, bin wohl schon zu alt...
>
> Zu Deinem Problem:
> Ohne Deine Routinen genauer zu kennen: was ist bei Dir langsam?
> Wenn in Sekunden gezählt wird, wird das Display doch wohl ohne Probleme
> auch so zu aktualisieren gehen.
>

Ja, ist jetzt ein wenig blöd gelaufen, ich will natürlich auf 
millisekunden genau zählen, benutzte dazu den Output Compare Match von 
Timer2 des Atmega8 (4Mhz Quarz) mit einem Vergleichswert vom 25536, das 
sollte für eine Genauigkeit von 10ms sein. Immer wenn der Vergleichswert 
mit dem Register TCNT1 übereinstimmt löse ich einen Interrupt aus der 
die Variable act_msec um eins erhöht.
Problem ist jetzt das im Debbuging modus die ausgabe der Zahlen auf dem 
LCD display solange dauert, das miten in der Ausgabe der Interupt 
ausgelöst wird, was denke ich für ein ungleichmäßiges hochzählen meiner 
variable sorgt.

Angezeigt auf dem LCD werden folgende Sachen:
AKT: act_min : act_sec . act_msec

Will aber in zukunft das ganze nicht über Compare Match machen, sondern 
über einen externen interrupt des ICP Pins.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Patrick Langosch (crashdemon)

>Ja, ist jetzt ein wenig blöd gelaufen, ich will natürlich auf
>millisekunden genau zählen, benutzte dazu den Output Compare Match von
>Timer2 des Atmega8 (4Mhz Quarz) mit einem Vergleichswert vom 25536, das
>sollte für eine Genauigkeit von 10ms sein.

???
10 ms bei 4 MHz sind bei mir eher 40000 Takte.

> Immer wenn der Vergleichswert
>mit dem Register TCNT1 übereinstimmt löse ich einen Interrupt aus der
>die Variable act_msec um eins erhöht.

Rede nicht um den heissen Brei herum, poste VOLLSTÄNDIGEN Quelltext als 
ANHANG!

>Problem ist jetzt das im Debbuging modus die ausgabe der Zahlen auf dem
>LCD display solange dauert, das miten in der Ausgabe der Interupt
>ausgelöst wird, was denke ich für ein ungleichmäßiges hochzählen meiner
>variable sorgt.

Ja, das macht man nicht so. Siehe Interrupt.

>Will aber in zukunft das ganze nicht über Compare Match machen, sondern
>über einen externen interrupt des ICP Pins.

Warum? Der Quarz it als Zeitbasis mehr als genau genung.

MFG
Falk

Autor: Patrick L. (crashdemon)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier der Quellcode

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Als erstes entfernst du mal das SREG- und cli-Zeug aus der ISR. Das ist 
völlig ohne Effekt.

Das eigentliche Problem ist, dass du im Interrupt nur die Millisekunden 
hochzählst, und in Main dann den Übertrag zur Sekunde (und auch Minute) 
machst. Wenn der restliche Code in Main zu lange braucht, verpasst du 
dort schnell mal den "act_msec == 100"-Moment (der ja nur 10 ms lang 
ist).

Entweder machst du auch die Überträge im Interrupt, oder du lässt die 
Überträge ganz weg und machst act_msec deutlich größer (z.B. uint32_t).

PS: Auch für mich ist es ein Rätsel, wie du auf 25536 kommst.
Für 10 ms bei 4 MHz wäre 39999 korrekt.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wichtigste: Arbeit und Anzeige trennen.
Wenn die Anzeige 100 ms zu spät kommt, merkt das keiner. Wenn die Zeit 
um 100 ms nicht stimmt, merkt das jeder.

Die Abhandlung der Millisekunden könnte so aussehen:
    if(act_msec >= 100) // Wenn eine Sekunde erreicht
    {
      cli(); // Semaphore Beginn
      act_msec -= 100; // Millisekunden zur�cksetzen
      sei(); // Semaphore Ende   

      act_sec++; // Sekunden um eins erh�hen
    }


BTW:
> if (act_msec == 100)
Wieviele Millisekunden hat bei dir eine Sekunde :-o
Der Variablenname act_msec ist schlicht falsch.

Autor: Patrick L. (crashdemon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So hab das mal wie beschrieben geändert und in die ISR gepackt.
volatile uint8_t act_min = 0; // Aktuelle Zeit - Minuten
volatile uint8_t act_sec = 0; // Aktuelle Zeit - Sekunden
volatile uint8_t act_msec = 0; // Aktuelle Zeit - Millisekunden

/******** ISR des Laptimers ********/
ISR(TIMER1_COMPA_vect) // Aufruf bei Compare Match von Timer2 (8 Bit)
{
  act_msec++; // Millisekunden um eins erhöhen

    if(act_msec >= 100) // Wenn eine Sekunde erreicht
    {
       act_msec -= 100; // Millisekunden zurücksetzen
    act_sec++; // Sekunden um eins erhöhen
    }

  if(act_sec >= 60) // Wenn eine Minute erreicht
  {
    act_sec -= 60; // Sekunden zurücksetzen
    act_min++; // Minuten um eins erhöhen
  }
}


Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
    if(act_msec >= 100) // Wenn eine Sekunde erreicht
    {
       act_msec -= 100; // Millisekunden zurücksetzen
       :
Innerhalb der ISR ist das nicht mehr nötig. Denn die kann ja nicht 
unterbrochen werden, du hast also kein Semaphorenproblem mehr.
Du könntest also wieder schreiben:
    if(act_msec >= 100) // Wenn eine Sekunde erreicht
    {
       act_msec = 0; // Millisekunden zurücksetzen
       :
Das spart Rechenzeit.


Nenn deine Variable doch act_msec10 oder act_csec (centi-Sekunden), 
damit nicht irgendwann mal einer meint, das wären Millisekunden. In 
einem halben Jahr schüttelst du über diesen Variablennamen selber den 
Kopf, wetten?  ;-)

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.