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


von Michael J. (juston)


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:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdlib.h>
4
#define  F_CPU 8000000
5
#include <util/delay.h>
6
7
 
8
 
9
int variable;
10
 
11
int main(void)
12
{
13
    lcd_init();
14
 
15
    while(1)
16
    {
17
      _delay_ms(100);
18
19
      variable ++;
20
21
      set_cursor(0,2);
22
23
       {
24
         char Buffer[20]; 
25
         itoa( variable, Buffer, 10 ); 
26
 
27
         lcd_string( Buffer );
28
       }
29
    }
30
 
31
    return 0;
32
}

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

Gruß
Michael

von Kai F. (kai-) Benutzerseite


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

von Michael J. (juston)


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

von Karl H. (kbuchegg)


Lesenswert?

Gehs mal langsam an.

Welche Ausgabe bringt:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdlib.h>
4
#define  F_CPU 8000000
5
#include <util/delay.h>
6
7
int main(void)
8
{
9
  lcd_init();
10
11
  lcd_string( "Aktueller Wert" );
12
13
  while( 1 )
14
  {
15
  }
16
}

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.

von Michael J. (juston)


Angehängte Dateien:

Lesenswert?

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

Hier das Programm das die Funktion erfüllen soll:
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdlib.h>
4
#define  F_CPU 8000000
5
#include <util/delay.h>
6
7
 
8
int variable;
9
 
10
int main(void)
11
{
12
    lcd_init();
13
 
14
15
    while(1)
16
    {
17
     set_cursor(0,1);
18
19
     lcd_string('Aktueller Wert');
20
21
22
     _delay_ms(100);
23
24
      variable ++;
25
26
27
      set_cursor(0,2);
28
29
     {
30
         char Buffer[20]; 
31
         itoa( variable, Buffer, 10 ); 
32
 
33
         lcd_string( Buffer );
34
      }
35
    }
36
 
37
    return 0;
38
}

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

von Karl H. (kbuchegg)


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" );

von Bernd das Brot (Gast)


Lesenswert?

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

von Michael J. (juston)


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

von Karl H. (kbuchegg)


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.

von Michael J. (juston)


Lesenswert?

Hallo, ich habe das Programm nun geändert und es scheint zu 
funktionieren.
1
#include <avr/io.h>
2
#include "lcd-routines.h"
3
#include <stdlib.h>
4
#define  F_CPU 8000000
5
#include <util/delay.h>
6
7
 
8
int variable;
9
int i;
10
 
11
int main(void)
12
{
13
    lcd_init();
14
   
15
    while(1)
16
    {
17
      set_cursor(0,1);
18
19
      lcd_string("Aktueller Wert");
20
21
        while(i<6)
22
        {
23
          _delay_ms(20);
24
 
25
          i++;
26
        }
27
28
      i = 0;
29
      variable ++;
30
31
      set_cursor(0,2);
32
33
       {
34
         char Buffer[20]; 
35
         itoa( variable, Buffer, 10 ); 
36
 
37
         lcd_string( Buffer );
38
       }
39
       
40
    }
41
 
42
    return 0;
43
}

Danke für die Hilfe!

Gruß
Michael

von Pete (Gast)


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 ?

von Michael J. (juston)


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.
1
while(i<51)
2
 {
3
   _delay_ms(20);
4
   
5
   i++;
6
 }
Warum funktioniert das nicht?
Habe ich irgendeinen Denkfehler in meiner Überlegeng?

von Karl H. (kbuchegg)


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.
>
1
> while(i<51)
2
>  {
3
>    _delay_ms(20);
4
> 
5
>    i++;
6
>  }
7
>
> 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.

von Michael J. (juston)


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

von Sekoya A. (sekoya)


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üß,

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.