www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit Delay und LCD Ausgabe.


Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das Programm soll eine Variable mit einem delay von 100ms hochzählen und 
den Wert in Zeile 2 ausgeben. In Zeile 1 soll 'Aktueller Wert' stehen.

Das Problem ist jedoch, das das Delay überhaupt nicht funktioniert. Es 
hat praktisch keinerlei Auswirkungen. Ich bekomme auch nicht den 
Schriftzug 'Aktueller Wert' in Zeile 1.

Hier das Hauptprogramm:
#include <avr/io.h>
#include "lcd-routines.h"
#include <stdlib.h>
#define  F_CPU 8000000
#include <util/delay.h>

 
 
int variable;
 
int main(void)
{
    lcd_init();
 
    while(1)
    {
      _delay_ms(100);

      variable ++;

      set_cursor(0,2);

       {
         char Buffer[20]; 
         itoa( variable, Buffer, 10 ); 
 
         lcd_string( Buffer );
       }
    }
 
    return 0;
}

Für die Ausgabe des Schriftzuges habe ich zu Beginn der While Schleife 
noch vor dem dealy folgendes geschrieben:
set_cursor(0,1);
lcd_string('Aktueller Wert');
Danach habe ich nur wirre Zeichen auf dem Display gesehen.

Gruß
Michael

Autor: Kai Franke (kai-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
um was für ein Display handelt es sich denn?
bei einem 2x16 kommst du mit set_cursor(0,2); nicht in die zweite, 
sondern in die dritte Zeile, die nicht existiert.
set_cursor(0,0); wäre die erste und
set_cursor(0,1); die zweite

versuch außerdem mal das display vor dem neuen Schreiben zu löschen, ein 
lcd_clear sehe ich nirgends bei dir

Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
das Display ist ein EA DIP 162-D 2x16.

Mit set_cursor(0,0); wird mir nichts angezeigt.
Mit set_cursor(0,1); komme ich in Zeile 1.
Mit set_cursor(0,2); komme ich in Zeile 2.

Das vorherige Löschen hat auch nichts gebracht.


Gruß
Michael

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gehs mal langsam an.

Welche Ausgabe bringt:
#include <avr/io.h>
#include "lcd-routines.h"
#include <stdlib.h>
#define  F_CPU 8000000
#include <util/delay.h>

int main(void)
{
  lcd_init();

  lcd_string( "Aktueller Wert" );

  while( 1 )
  {
  }
}

Bitte poste das nächste mal das Programm, welches dir Ärger macht,
und nicht ein Basisprogramm, bei dem der Leser dann noch irgendwelche
Zeilen wahlweise an irgendwelches Stellen einfügen soll um den Fehler
zu erzeugen.
Es gibt viele Möglichkeiten etwas zu verbocken, lass uns einige
davon ausschliessen, indem du das Programm postest, welches du
auch tatsächlich ins Rennen schickst. Nach Möglichkeit tippst du
das dann auch nicht ab, sondern holst es per Copy&Paste hier
herein.

Autor: Michael Justinger (juston)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl heinz Buchegger
Bei diesem Programm bekomme ich die Ausgabe: 'Aktueller Wert' in Zeile1.

Hier das Programm das die Funktion erfüllen soll:
#include <avr/io.h>
#include "lcd-routines.h"
#include <stdlib.h>
#define  F_CPU 8000000
#include <util/delay.h>

 
int variable;
 
int main(void)
{
    lcd_init();
 

    while(1)
    {
     set_cursor(0,1);

     lcd_string('Aktueller Wert');


     _delay_ms(100);

      variable ++;


      set_cursor(0,2);

     {
         char Buffer[20]; 
         itoa( variable, Buffer, 10 ); 
 
         lcd_string( Buffer );
      }
    }
 
    return 0;
}

Als Ausgabe bekomme ich nur Wirre Zeichen.
Das komplette Programm ist im Dateianhang.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Justinger wrote:
> @ Karl heinz Buchegger
> Bei diesem Programm bekomme ich die Ausgabe: 'Aktueller Wert' in Zeile1.

OK. Das ist schon mal was. Das heist, dass du nicht so sehr daneben sein
kannst.

In deinem Programm, hier
>      lcd_string('Aktueller Wert');
hat da der Compiler nichts dazu gesagt?

Ein ' markiert ein einzelnes Zeichen. Ein String hat immer ein "
Es muss also lauten

     lcd_string( "Aktueller Wert" );

Autor: Bernd das Brot (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und _delay_ms(100) kann bei 8MHz auch nur 32,7675ms Verzögerung
und nicht 100ms.
Gruß

Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe nun  ' durch " ersetzt und nun bekomme ich auch in Zeile 1 die 
Ausgabe Aktueller Wert.

In Zeile 2 wird die Variable immer noch mit enormer Geschwindigkeit 
hochgezählt.

Ich dachte wenn ich #define  F_CPU 8000000 schreibe ist die CPU 
Geschwindigkeit bekannt und somit wir die Delay Zeit richtig ausgeführt.

Testweile habe ich mal _delay_ms(9999999); getestet und ich muss sagen 
es gibt keinen Unterschied.

_delay_ms(9999999); von 0-500 in ca. 31sec.
_delay_ms(100); von 0-500 in ca. 31sec.

Gruß
Michael

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Justinger wrote:

> Testweile habe ich mal _delay_ms(9999999); getestet und ich muss sagen
> es gibt keinen Unterschied.

Das bringt nichts.
_delay_ms kann nicht beliebig lange warten.
Es gibt eine obere Grenze, welche von der Taktfrequenz abhängt.
Die Details dazu sind in delay.h beschrieben.

Wenn du einen maximale Delay Zeit von 20ms ansetzt, dann bist du auf
der sicheren Seite. Notfalls kann man ja in einer Schleife zb.
100 mal 20Millisekunden lang warten. Dann hat man in Summa auch
wieder 2 Sekunden gewartet.

Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich habe das Programm nun geändert und es scheint zu 
funktionieren.
#include <avr/io.h>
#include "lcd-routines.h"
#include <stdlib.h>
#define  F_CPU 8000000
#include <util/delay.h>

 
int variable;
int i;
 
int main(void)
{
    lcd_init();
   
    while(1)
    {
      set_cursor(0,1);

      lcd_string("Aktueller Wert");

        while(i<6)
        {
          _delay_ms(20);
 
          i++;
        }

      i = 0;
      variable ++;

      set_cursor(0,2);

       {
         char Buffer[20]; 
         itoa( variable, Buffer, 10 ); 
 
         lcd_string( Buffer );
       }
       
    }
 
    return 0;
}


Danke für die Hilfe!

Gruß
Michael

Autor: Pete (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jaja, die Delay Routinen sind immer ein Stolperstein. Gerade für 
Anfänger ist das keine gelungene Lösung.

Wäre schön, wenn das vom etwas "narrensicherer" programmiert werden 
könnte.

Was sagen die WinAVR Entwickler dazu ?

Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irgendwas stimmt glaube ich trotzdem nicht.
Wenn ich das Program 1 Minute laufen lasse, ist die Anzeige auf dem 
Display erst bei 57.

Ich habe bei dem Programm oben i auf 51 gesetzt.
Dann müsste doch die Schleife 50 mal laufen mit jeweils 20ms so kommt 
man doch auf eine Gesamtzeit von 1000ms also eine Minute.
while(i<51)
 {
   _delay_ms(20);
   
   i++;
 }
Warum funktioniert das nicht?
Habe ich irgendeinen Denkfehler in meiner Überlegeng?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael Justinger wrote:
> Irgendwas stimmt glaube ich trotzdem nicht.
> Wenn ich das Program 1 Minute laufen lasse, ist die Anzeige auf dem
> Display erst bei 57.
>
> Ich habe bei dem Programm oben i auf 51 gesetzt.
> Dann müsste doch die Schleife 50 mal laufen mit jeweils 20ms so kommt
> man doch auf eine Gesamtzeit von 1000ms also eine Minute.
>
> while(i<51)
>  {
>    _delay_ms(20);
> 
>    i++;
>  }
> 
> Warum funktioniert das nicht?
> Habe ich irgendeinen Denkfehler in meiner Überlegeng?

Punkt 1
Die 20 Millisekunden sind nicht 100% exakt. Bei kleinen Zeiträumen
spielt eine Differenz von ein paar Nanosekunden keine große Rolle.
Sie summiert sich aber bei großen Zeiträumen.

Punkt 2
Die Abfrage in der While Schleife, das Inkrementieren von i,
sowie der Sprung an den Anfang der Schleife kostet auch Zeit.
Zudem hast du da anscheinend auch noch eine Ausgabe drinnen, auch
die kostet Zeit. Auch wenn ein µC sehr schnell arbeitet, braucht
er doch Zeit für jede einzelne Aktion.

Wenn du also eine Uhr für längere Zeiträume bauen willst, dann
ist _delay_ms nicht das richtige Werkzeug.

Autor: Michael Justinger (juston)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
wollte nur sicher gehen, dass kein weiterer Fehler im Programm ist.
Das Programm war nur eine Übung also muss die Zeit nicht genau sein, 
aber trotzdem gut zu wissen warum  es so ist.

Michael

Autor: Sekoya A. (sekoya)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Juston,

kannst du komplet dein Projekt posten. Ich werde auch ein Programm an 
gleiches LCD versenden, ich weiss aber nicht,wie das geht,
wie man versendet und welche befehlen man nutzt soll. Oder wenn du deine 
e-mail adresse geben kannst,bitte, kann ich dir mein projekt senden und 
kannst du durchschauen?
habe schon mal hier beschriebt aber keine konnte helfen,
die moderatoren haben leider auch darum nicht gekümmert.

grüß,

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.