AVR + LCD Problem

Gast #3385431
Lesenswert?

Hallo,
ich kämpte gerade mit einem LCD Display (HD44780), das im 4-Bit Modus an 
einen ATMEGA8 angeschlossen ist.

Verwendet wird die Lib von Peter Fleury.

Pinbelegung Display:
1 GND
2 +5 Volt
3 GND
4 PC4 (RS)
5 PC5 (RW)
6 PB0 (Enable)
11 PC0 (Data0)
12 PC1 (Data1)
13 PC2 (Data2)
14 PC3 (Data3)

Ausschnitt aus der lcd.h
1
#define XTAL 16000000              /**< clock frequency in Hz, used to calculate delay timer */
2

3

4
/**
5
 * @name  Definition for LCD controller type
6
 * Use 0 for HD44780 controller, change to 1 for displays with KS0073 controller.
7
 */
8
#define LCD_CONTROLLER_KS0073 0  /**< Use 0 for HD44780 controller, 1 for KS0073 controller */
9

10
/** 
11
 *  @name  Definitions for Display Size 
12
 *  Change these definitions to adapt setting to your display
13
 */
14
#define LCD_LINES           2     /**< number of visible lines of the display */
15
#define LCD_DISP_LENGTH    16     /**< visibles characters per line of the display */
16
#define LCD_LINE_LENGTH  0x40     /**< internal line length of the display    */
17
#define LCD_START_LINE1  0x00     /**< DDRAM address of first char of line 1 */
18
#define LCD_START_LINE2  0x40     /**< DDRAM address of first char of line 2 */
19
#define LCD_START_LINE3  0x14     /**< DDRAM address of first char of line 3 */
20
#define LCD_START_LINE4  0x54     /**< DDRAM address of first char of line 4 */
21
#define LCD_WRAP_LINES      0     /**< 0: no wrap, 1: wrap at end of visibile line */
22

23

24
#define LCD_IO_MODE      1         /**< 0: memory mapped mode, 1: IO port mode */
25
#if LCD_IO_MODE
26
/**
27
 *  @name Definitions for 4-bit IO mode
28
 *  Change LCD_PORT if you want to use a different port for the LCD pins.
29
 *
30
 *  The four LCD data lines and the three control lines RS, RW, E can be on the 
31
 *  same port or on different ports. 
32
 *  Change LCD_RS_PORT, LCD_RW_PORT, LCD_E_PORT if you want the control lines on
33
 *  different ports. 
34
 *
35
 *  Normally the four data lines should be mapped to bit 0..3 on one port, but it
36
 *  is possible to connect these data lines in different order or even on different
37
 *  ports by adapting the LCD_DATAx_PORT and LCD_DATAx_PIN definitions.
38
 *  
39
 */
40
#define LCD_PORT         PORTC        /**< port for the LCD lines   */
41
#define LCD_DATA0_PORT   LCD_PORT     /**< port for 4bit data bit 0 */
42
#define LCD_DATA1_PORT   LCD_PORT     /**< port for 4bit data bit 1 */
43
#define LCD_DATA2_PORT   LCD_PORT     /**< port for 4bit data bit 2 */
44
#define LCD_DATA3_PORT   LCD_PORT     /**< port for 4bit data bit 3 */
45
#define LCD_DATA0_PIN    0            /**< pin for 4bit data bit 0  */
46
#define LCD_DATA1_PIN    1            /**< pin for 4bit data bit 1  */
47
#define LCD_DATA2_PIN    2            /**< pin for 4bit data bit 2  */
48
#define LCD_DATA3_PIN    3            /**< pin for 4bit data bit 3  */
49
#define LCD_RS_PORT      LCD_PORT     /**< port for RS line         */
50
#define LCD_RS_PIN       4            /**< pin  for RS line         */
51
#define LCD_RW_PORT      LCD_PORT     /**< port for RW line         */
52
#define LCD_RW_PIN       5            /**< pin  for RW line         */
53
#define LCD_E_PORT       PORTB     /**< port for Enable line     */
54
#define LCD_E_PIN        0            /**< pin  for Enable line     */

main.c:
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif
4
#define UART_BAUD_RATE 2400 
5

6
#include <avr/interrupt.h>
7
#include <util/delay.h>
8
#include <stdlib.h>
9
#include "uart.h"
10
#include "lcd.h"
11

12
volatile unsigned int x = 0;
13

14
int main(void)
15
{  
16
  lcd_init(LCD_DISP_ON);
17
  _delay_ms(300);
18
    lcd_clrscr();
19

20
  DDRB |= (1 << DDB2);
21
  DDRD |= (1 << DDD2);
22
  uart_init(UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU));
23
  sei();
24
  uart_puts("alles initialisiert...");
25
  char buffer[7];
26

27
  /*
28
  * Timer 1
29
  * 16-Bit
30
  * CTC-Mode
31
  * f = 1Hz
32
  */
33
  TCCR1B |= (1 << WGM12); // CTC-Mode
34
  TIMSK |= (1 << OCIE1A); // CTC-Interupt
35
  OCR1A = 15625-1; //CTC Vergleichswert setzen: 16000000 / 1024 = 15625
36
  TCCR1B |= ((1 << CS10) | (1 << CS12)); // Timer1 aktivieren, Prescaler 1024
37

38
  while(1)
39
  {  
40
    lcd_gotoxy(0,0);
41
       lcd_puts("xyz");
42
    lcd_gotoxy(0,1);
43
       lcd_puts("xyz");
44
    PORTD ^= (1<<PD2);
45
    itoa(x, buffer, 10);   // convert interger into string (decimal format)         
46
      uart_puts(buffer);
47
    uart_putc('\n');
48
    _delay_ms(1000);
49
  }
50
}
51

52
ISR (TIMER1_COMPA_vect)
53
{
54
  x++;
55
  PORTB ^= (1<<PB2);
56
}

Problem: Das Display zeigt undefiniertes Zeug an (Cursor blinkt meist).
Hat mir da jmd einen Tipp?  (Oszilloskop vorhanden.)
Gast #3385442
Lesenswert?

>ISR (TIMER1_COMPA_vect)
>{
>  x++;
>  PORTB ^= (1<<PB2);
>}
>
>Problem: Das Display zeigt undefiniertes Zeug an (Cursor blinkt meist).
>Hat mir da jmd einen Tipp?  (Oszilloskop vorhanden.)

Lass das wackeln am PORTB im Timer Interrupt mal sein.
Gast #3385691
Lesenswert?

wahrscheinlich hat er vergessen die nich verwendeten daten pins am 
display high oder low zu pullen (bin mir gerade nicht sicher was da hin 
muss). die floaten also immer schön durch die gegend und somit wär auch 
der müll erklärt.

kontrast/hintergrundbeleuchtung scheinen auch nicht angeschlossen zu 
sein, schätze ich mal.
Gast #3385715
Lesenswert?

ich, nicht du schrieb:
> wahrscheinlich hat er vergessen die nich verwendeten daten pins am
> display high oder low zu pullen (bin mir gerade nicht sicher was da hin
> muss). die floaten also immer schön durch die gegend und somit wär auch
> der müll erklärt.

Seit Jahren sind bei allen von mir verwendeten LCDs Pulldown-Widerstände 
verbaut, offene Eingänge D0 bis D3 sind somit wohl nicht das Problem.
#3385745
Lesenswert?

Du hast einen 16 MHz Quartz dran, hast du auch das Fuse-Bit für den 
Clock-Teiler drin? Wenn ja dann musst du F_CPU durch 8 teilen…oder du 
nimmst das Fuse-Bit raus. Hast du schon das Toggeln versucht und die 
Zeit ausgemessen? Was kam dabei rum? Wie sind die anderen Fuse-Bits? Den 
Watchdog auch ausgemacht? Immerhin setzt du ihn nicht zurück wenn ich 
das richtig gesehen hab.
(Firma: matzetronics) #3385746
Lesenswert?

Lass dir doch mal direkt nach der LCD Init was auf dem Display anzeigen 
und starte dann erst die andere Peripherie. Dann weisst du sofort, ob es 
an der Verkabelung liegt oder an einem Konflikt auf den I/O Pins.
Eigentlich ist Peter Fleurys Bibliothek nämlich ziemlich narrensicher. 
Falls übrigens der Takt nicht stimmt, ist das hier nicht so schlimm, 
denn wir haben ja 16MHz angegeben, bei z.B. 8Mhz müsste es trotzdem 
gehen, wenn auch langsamer.
Gast #3385850
Lesenswert?

ich, nicht du schrieb:
> wahrscheinlich hat er vergessen die nich verwendeten daten pins am
> display high oder low zu pullen (bin mir gerade nicht sicher was da hin
> muss). die floaten also immer schön durch die gegend und somit wär auch
> der müll erklärt.

Zeig mir mal die Application-Note oder das Datenblatt in dem drin steht, 
dass man die nicht offen lassen kann.

Ich lasse DB0...DB3 immer offen und habe damit noch nie Probleme gehabt.
Wie auch, wenn die unteren vier Bits garnicht gebraucht werden.

Hmm:
http://www.mikrocontroller.net/articles/HD44780

Da steht auch offen lassen drin.

Und im Datenblatt vom HD444780U von Hitachi sind im Schaltungs-Beispiel 
für 4 Bit die DB0...DB3 Leitungen nicht zu sehen, was auch wieder 
andeutet, dass man die ignorieren kann.
Gast #3385852
Lesenswert?

Rudolph schrieb:
> Und im Datenblatt vom HD444780U von Hitachi sind im Schaltungs-Beispiel
> für 4 Bit die DB0...DB3 Leitungen nicht zu sehen, was auch wieder
> andeutet, dass man die ignorieren kann.

Da braucht man nicht irgendwie rumzudeuteln.
Bei der Pin-Beschreibung zu DB0..DB3 im Datenblatt steht "These pins are 
not used during 4-bit operation.". Ist das nicht klar genug?
Gast #3385864
Lesenswert?

Guten Morgen,
ich habe nun mit mal einen Pin Togglen lassen, dazu wurde folgender Code 
geladen:
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif 
4

5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
#include "uart.h"
8
#include "lcd.h"
9

10
int main(void)
11
{
12
    //lcd_init(LCD_DISP_ON);
13
    //lcd_clrscr();
14
  DDRB |= (1 << DDB2);
15
  
16
  while(1)
17
  {  
18
            //lcd_puts("LCD Test Line 1\n");
19
            //_delay_ms(1000);
20
      PORTB ^= (1<<PB2);
21
  }
22
}

Die Ausgabe am Oszi findet ihr im Anhang. Ich lese da 1,6 Mhz, hm.

Ich hab noch einen 2ten Screenshot von der l-und hfuse aus avrdude 
angehängt.
Angehängte Dateien:
Gast #3385874
Lesenswert?

Kurzer Einwurf mit Halbwissen:

Wenn die serielle Übertragung funktioniert, also im Terminal seriell das
uart_puts("alles initialisiert..."); ankommt, dann sollte doch mit dem 
CPU-Takt alles richtg sein!?
#3385886
Lesenswert?

Mit Pin3 des LCD auf GND wirst du nicht viel sehen. Ein Poti wie im 
Datenblatt erhöht den Kontrast enorm.
Hast du schon die UART-Ausgabe angeschaut?
Also auf meinem Testboard funktioniert LCD und UART einwandfrei.
Die laufende Zahl gibst du allerdings auf den LCD nicht aus, nur über 
UART.
Gast #3385889
Lesenswert?

willy schrieb:
> Die Ausgabe am Oszi findet ihr im Anhang. Ich lese da 1,6 Mhz, hm.

Was auch immer der ganze eingeblendete Zahlensalat soll - mit den 1.6MHz 
liegst du richtig.

Um damit etwas anfangen zu können, solltest du verraten, wie du die 
Compileroptimierung eingestellt hast.
Besser wäre noch, die Optimierung mit '-O1' auf '1' zu stellen und ein 
aussagekräftiges Delay (z.B. 1000µs) in die Schleife zu setzen.
Gast #3385892
Lesenswert?

Da hat Hubert G. Recht, Pin3 an GND := nicht gut!
Besser Poti zwischen +5V und GND, Mittelabzweig auf Pin3.
Solange dran drehen bis die schwarzen Balken im Display so gerade eben 
verschwinden.
Gast #3385896
Lesenswert?

Hallo,
mit dem Kontrast hab ich meines Erachtens weniger Probleme.
Nur mal so zwischen rein geworden, wenn ich folgenden Code ausführe:
1
#ifndef F_CPU
2
#define F_CPU 16000000UL
3
#endif 
4

5
#include <avr/interrupt.h>
6
#include <util/delay.h>
7
#include "uart.h"
8
#include "lcd.h"
9

10
int main(void)
11
{
12
    lcd_init(LCD_DISP_ON);
13
    lcd_clrscr();
14
  
15
  while(1)
16
  {  
17
        lcd_puts("LCD Test Line 1");
18
        _delay_ms(1000);
19
  }
20
}

Wird zeigt das Display folgendes an (Foto, Anhang)
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren