Ausgabeprobleme LCD 4Bit

OP (Firma: privat) #4412784
Hallo in die Runde,
ich habe sicherlich ein Anfängerproblem.
Ich wollte einen Zähler rückwärts laufen lassen und den Wert auf einem 
LCD-Display darstellen.
Das initialisieren des Displays klappt,
die beiden Werte 'Timer' und '3 Min' erscheinen richtig,
nur die Ausgabe des Wertes leider nicht. Da stehen nur asiatische 
Zeichen.
Ich habe verschiedene Displays getestet HD44780 oder 1602.
Selbe Problematik.

Danke für eure Unterstützung.
aus dem Makefile:

MCU = attiny2313
F_CPU = 1000000


Meine Source:
1
#include <avr/io.h>
2
#include <stdlib.h>
3
#include "lcd-routines.h"
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6

7

8
volatile int zeit1 = 180;
9
volatile int zeit ;
10

11
void setup_global(void)
12
{
13
DDRD= 0xff;
14
}
15

16
void setup_timer(void)
17
{
18
// Timer1
19
    TCCR1A = (1<<COM1A0);  // CTC mode, toggle OC1A on compare match
20
    TCCR1B = (1<<CS12)         // Start Timer1 with prescaler 256
21
             |(1<<WGM12);
22
    OCR1A = 3906;  // F_Timer = F_clk/Prescaler
23
    // Compare Interrupt erlauben
24
    TIMSK |= (1<<OCIE1A);
25
}
26
void Displ_def(void)
27
{
28
  lcd_clear();
29
  lcd_string("Timer ");
30
  lcd_setcursor( 0, 2 );
31
  lcd_string("3 Min");
32
  return;
33
} 
34

35
void display_time(int x)
36
{
37
  lcd_setcursor( 15, 2 );
38
  char Buffer[5]; // in diesem {} lokal
39
  itoa( zeit, Buffer, 10 ); 
40
  lcd_string( Buffer );
41
}
42
 
43
int main(void)
44
{
45
  setup_global();
46
  lcd_init();
47
  Displ_def();
48
  setup_timer();
49
  sei();
50
  while(1)
51
  {
52
    display_time(zeit);
53
    _delay_ms(100);
54
  PORTD ^= ( 1 << PD1 );
55
  }
56

57
}
58
ISR (TIMER1_COMPA_vect)
59
{
60
  zeit1 --;
61
  zeit=zeit1;
62
}

--

Bitte die Formatierungstags verwenden, die das Forum bietet. So ist 
Dein Quelltext gleich lesbarer.

-rufus
Das beschriebene Verhalten passt wohl zu einer nicht korrekt gesetzten 
Variablen.

Auffälligkeiten:

1.) Die Variable zeit wird zu Beginn auf keinen vernünftigen Wert 
initialisiert.

2.) In dieser Funktion hier:
void display_time(int x)
wird der Parameter x nirgendwo verwendet. Wozu existiert er dann?

3.) Bist Du sicher, dass die Interrupt Service Routine korrekt 
konfiguriert ist und auch ausgeführt wird? Das ist die einzige Stelle im 
Code, an der die Variable zeit beschrieben wird.

4.) Die Variable zeit1 wird irgendwann negativ (so die ISR immer wieder 
ausgeführt wird). Dann hätte auch die Variable zeit einen negativen 
Wert. Das ist vermutlich nicht was Du willst.
Gast
>Dann hätte auch die Variable zeit einen negativen Wert.

Und passt dann nicht mehr in den Buffer.
Der müsste mit abschliessender Null schon
mal 7 Bytes aufnehmen können.
OP (Firma: privat)
Hallo und Danke.

1. verständlich, ich hatte die Variable zu Testzwecken noch im Source, 
das entschuldigt es nicht. Sie wird richtig gefüllt und 
weiterverarbeitet.
2. stimmt auch, wurde korrigiert.
3. Ja, wurde mit >>PORTD ^= ( 1 << PD2 );<< in der ISR getestet
4. im Moment stehe ich vor dem Problem das die Ausgabe im Display nicht 
funktioniert, der Rest wurde noch nicht implementiert.
(5.) ist richtig, erklärt 4.
Anbei das Bild vom Display.
Angehängte Dateien:
Ich kenne deine lcd-rotuines.h nicht, aber ich gehe stark davon aus, 
dass

  lcd_string

als Parameter einen String aus dem Progmem erwartet, du aber mit

  lcd_string( Buffer );

einen Array übergibst. Hier wundert es mich, dass der Compiler nicht 
meckert, denn normalerweise hätte zumindest ein Zeiger übergeben werden 
müssen ...

Du brauchst also fuer die Ausgabe eines Strings im Ram eine 
entstprechende Funktion !

Wenn es in lcd-routines.h etwas in der Art wie:

void lcd_putchar(char ch)

gibt (so in der Art halt), dann lässt sich eine Ausgaberoutine leicht 
selbst implementieren.


void lcd_ramstring(char *c)
{
  while (*c)
  {
    lcd_putchar(*c++);
  }
}

Der Aufruf in deinem Programm würde dann erfolgen mit:

lcd_ramstring(&Buffer[0]);

Im übrigen:

Du reservierst füf <Buffer> 5 Bytes. Ein Integer kann maximal den Wert 
65535 annehmen (und ist somit 5 stellig). Ein abschließendes Zero Byte 
(als Endekennung des Strings) wird bei <itoa> automatisch mit angehängt, 
sodass ein Ergebnis im schlimmen Fall 6 Bytes Speicher benötigt !

Gruß am Morgen,

Ralph
Hallo,

Ralph S. schrieb:
> Ich kenne deine lcd-rotuines.h nicht, aber ich gehe stark davon aus,
> dass
>
>   lcd_string
>
> als Parameter einen String aus dem Progmem erwartet, du aber mit
>
>   lcd_string( Buffer );
>
> einen Array übergibst. Hier wundert es mich, dass der Compiler nicht
> meckert, denn normalerweise hätte zumindest ein Zeiger übergeben werden
> müssen ...

ich bin nicht der sonderliche C-Spezi, aber wie ich es verstanden habe, 
wird in C in diesem Fall immer der Zeiger auf das Array übergeben.

Ich lasse mich da aber gern korrigieren.

Gruß aus Berlin
Michael
OP (Firma: privat)
Hallo und Danke,

ich habe erst hier im Forum gelesen wie so was angesteuert wird.
https://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung

dort findet sich auch folgendes Beispiel:

// Ausgabe der Variable als Text in dezimaler Schreibweise
  {
     // ... umwandeln siehe FAQ Artikel bei 
http://www.mikrocontroller.net/articles/FAQ
     // WinAVR hat eine itoa()-Funktion, das erfordert obiges #include 
<stdlib.h>
     char Buffer[20]; // in diesem {} lokal
     itoa( variable, Buffer, 10 );

     // ... ausgeben
     lcd_string( Buffer );
  }

Gruß Klaus.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.