Forum: Mikrocontroller und Digitale Elektronik LCD Taktproblem


von Felix (Gast)


Lesenswert?

Hallo zusammen,

habe folgendes Problem. Ich hoffe ihr könnt mir helfen es zu lösen:

Ich habe ein LCD am Port C eines Atmega 8-16 angeschlossen. Das LCD 
läuft jedoch nur bis zu einer Taktfrequenz des Controllers von 4,0 MHZ. 
Bei höheren Frequenzen werden nur dunkle Balken angezeigt.

Interessant ist, dass dabei die Frequenzeinstellung im Compiler (s.u.) 
keinen Einfluss zu haben scheint. So kann der Controller mit einem 4 
MHZ-Quarz betrieben werden bei einer Compilereinstellung mit 1,8,16, 
oder egal wie viel MHZ. Sobald der Controller jedoch mit 8 MHZ betrieben 
wird, wird das LCD nicht korrekt angesteuert, auch wenn im Compiler 8 
MHZ eingestelt werden.

Ich würde den Controller gerne mit 8 Mhz betreiben und dabei das LCD 
verwenden. Wö konnte der Fehler liegen?


Zur Ansteuerung es LCD verwende ich die Routinen aus dem Tutorial. Die 
.h-Datei habe ich folgendermaßen angepasst.

// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung
//

#ifndef LCD_ROUTINES_H
#define LCD_ROUTINES_H

//////////////////////////////////////////////////////////////////////// 
////////
// Hier die verwendete Taktfrequenz in Hz eintragen, wichtig!

#ifndef F_CPU
#define F_CPU 8000000 UL
#endif

//////////////////////////////////////////////////////////////////////// 
////////
// Pinbelegung für das LCD, an verwendete Pins anpassen
// Alle LCD Pins müssen an einem Port angeschlossen sein und die 4
// Datenleitungen müssen auf aufeinanderfolgenden Pins liegen

//  LCD DB4-DB7 <-->  PORTA Bit PC0-PC3
#define LCD_PORT      PORTC
#define LCD_DDR       DDRC
#define LCD_DB        PC0

//  LCD RS      <-->  PORTC Bit PC4     (RS: 0=Data, 1=Command)
#define LCD_RS        PC4

//  LCD EN      <-->  PORTC Bit PC5     (EN: 1-Impuls für Daten)
#define LCD_EN        PC5

//////////////////////////////////////////////////////////////////////// 
////////
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)

#define LCD_BOOTUP_MS           15
#define LCD_ENABLE_US           1
#define LCD_WRITEDATA_US        46
#define LCD_COMMAND_US          42

#define LCD_SOFT_RESET_MS1      5
#define LCD_SOFT_RESET_MS2      1
#define LCD_SOFT_RESET_MS3      1
#define LCD_SET_4BITMODE_MS     5

#define LCD_CLEAR_DISPLAY_MS    2
#define LCD_CURSOR_HOME_MS      2

//////////////////////////////////////////////////////////////////////// 
////////
...

Vielen Dank, Felix

von Michael P. (mipo)


Lesenswert?

Das hört sich so an, als ob das Timing (z.B. für Initalisierung) nicht 
mehr hin haut. D.h. Du schreibst Datan an das Display obwohl es mit den 
vorherigen noch nicht fertig ist. Werte endwerder das RS-Signal des 
Displays aus (sollte unabhängig von µC Takt sein) oder ändere die 
Wartezeiten (die Werten in  "LCD Ausführungszeiten" einfach mal 
verdoppeln)

von Michael P. (mipo)


Lesenswert?

Ergänzung: Compiler-Optimierung an?

von Felix (Gast)


Lesenswert?

Hallo Michael,

danke für Deine schnelle Antwort. Habe die Wartezeiten erhöht und bei es 
8 Mhz (Quarz und Compiler) versucht. Leider ohne Erfolg. Die Optimierung 
ist an auf -0s. Habe die anderen Optimierungsstufen auch schom 
ausprobiert.

Wie werte ich das RS-Signal am Besten aus? mit einem Oszi?


//////////////////////////////////////////////////////////////////////// 
////////
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)

#define LCD_BOOTUP_MS           30
#define LCD_ENABLE_US           2
#define LCD_WRITEDATA_US        92
#define LCD_COMMAND_US          84

#define LCD_SOFT_RESET_MS1      10
#define LCD_SOFT_RESET_MS2      2
#define LCD_SOFT_RESET_MS3      2
#define LCD_SET_4BITMODE_MS     10

#define LCD_CLEAR_DISPLAY_MS    4
#define LCD_CURSOR_HOME_MS      4

Viele Grüße, Felix

von Felix (Gast)


Lesenswert?

Habe gerade mit dem Oszi den RS-Pegel ausgemessen. Es gibt zwei kurz 
aufeinanderfolgende High-Pegel. Deren Längen sind in [us] angegeben:

   Einstellung                  Messergebnis
Quarz     Compiler     Pegellängen         Ergebnis
4 MHZ     4 MHZ        250us / 620us       LCD funktioniert
4 MHZ     8 MHZ        500us / 1250us      LCD funktioniert
4 MHZ    16 MHZ        1000us / 2500us     LCD funktioniert

8 MHZ     4 MHZ        High-Pegel          LCD funktioniert nicht
8 MHZ     8 MHZ        High-Pegel          LCD funktioniert nicht
8 MHZ    16 MHZ        High-Pegel          LCD funktioniert nicht

--> sobald ein schnellerer Quarz verwendet wird, ist auf der RS-Leitung 
keine Aktivität mehr.

sagt das jemandem was???

Grüße, Felix

von Bernd (Gast)


Lesenswert?

Kann mich nicht zu den Tutorial-Routinen, bzw. deren
Anpassbarkeit auf die CPU-Frequenz äußern,
aber das RS-Signal ist kein Puls, wie z.B.
das EN-Signal.

RS ist ein zusätzliches Bit zu den jeweils übermittelten
4 oder 8 Datenbits, dass dem LCD sagt:
(1) Dies sind Daten zur Anzeige auf dem Display
(0) Dies ist ein Kommando für die Displaysteuerung

Bei der Übermittlung von Kommandos sieht man auf
der RS-Leitung eigentlich GARNIX.
(Im 4-Bit-Modus 2 mal NIX)

von HildeK (Gast)


Lesenswert?

Felix schrieb:
> --> sobald ein schnellerer Quarz verwendet wird, ist auf der RS-Leitung
> keine Aktivität mehr.

Ist denn überhaupt sicher, dass dein schnellerer Quarz auch schwingt?
Kannst du aus irgend welchen anderen Signalen ableiten, dass der 
Prozessor überhaupt etwas tut?
Vielleicht solltest du einfach mal den Oszillatorteil überprüfen.

von Bernd (Gast)


Lesenswert?

Hab mal Kurz (!) ins Tutorial geschaut.

Dort gibt es den Hinweis, z.B. XTAL zu definieren,
um Zeitschleifen vom Compiler an den Takt anpassen zu
lassen.

Für deine DEFINE-Tabelle
// LCD Ausführungszeiten (MS=Millisekunden, US=Mikrosekunden)
... kann ich nicht erkennen, wie die jetzt vom Compiler
ausgewertet und in wirksame Zeitschleifen umgesetzt werden.

Liegt da der Fehler?

Oder vielleicht doch bei der Code-Optimierung vom
Compiler...

Außerdem ist die Tabelle viel zu aufwändig!

Man braucht
ca. 0,5 µs für EN,
ca. 50 µs für den Abstand zwischen 2 Datenübermittlungen
und (um es einfach zu machen) 10 ms (oder mehrere davon)
bei größeren (und seltenen) Aktionen, wie Initialisierung,
oder Display-CLEAR.

von Felix (Gast)


Lesenswert?

Danke für eure Antworten soweit.

@ Hilde:
Die Quarze habe ich mit dem Oszi überprüft, sie schwingen. Alternativ 
hatte ich auch mal die internen Schwingkreise ausprobiert. Bei 4 MHZ 
CPU-Frequenz funktioniert das LCD, bei 8 MHZ und mehr nicht.

@ Bernd:
Die Zeiten in der define-Tabelle sind Parameter, die in den 
Unterprogrammen (z.B. für lcd_init) in _delay_ms(Parameter) und 
_delay_us(Parameter) verwendet werden. Hier ist das gut zu sehen: 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/LCD-Ansteuerung.

Sowohl in delay.h als auch lcd-routines.h hab ich F_CPU auf 8000000 Hz 
definiert. Zudem ist die Frequenz in den Compilation Options eingestellt 
-DF_CPU=8000000UL. Nur leider funktioniert's nicht.


Die Routinen für das LCD habe ich an anderen Controllern bereits 
erfolgreich in Betrieb genommen. Z.B. mit dem Atmega32 bei 8Mhz, 
AT90CAN128 bei 8MHZ sowie bei 16MHZ.

Kann das Problem auch vom jetzt verwendeten Atmega8-16AU kommen?

von Anja (Gast)


Lesenswert?

Felix schrieb:
> Kann das Problem auch vom jetzt verwendeten Atmega8-16AU kommen?

Felix schrieb:
> #define LCD_BOOTUP_MS           30

Die Boot-Zeit gilt beim LCD ab erreichen der Betriebsspannung von 4,75V.
Wahrscheinlich ist dein Atmega viel schneller.
-> Brown out detection auf höchste Spannungsstufe stellen oder 
zusätzliches Delay vor Aufruf der Initialisierungsroutine setzen. 
Vorsicht: manche Delay-Routinen haben je nach Quarzfrequenz einen 
Überlauf bei knapp über 20 ms. -> ggf aufteilen in mehrere Aufrufe.

Gruß Anja

von Felix (Gast)


Lesenswert?

Hallo Anja,

mit der Brown-Out detection und dem #define LCD_BOOTUP_MS habe ich auch 
schon unterschiedliche Varianten ausprobiert. Ohne Erfolg.

Habe eine gute Nachricht: das Problem habe ich soeben gelöst.
Wie?: Ich habe eine neue Platine ausgebaut. Es wird ein 16Mhz-Quarz 
verwendet. Andere CPU-Geschwindigkeiten (4MHZ, 8MHZ, sowohl intern als 
auch per Quarz) habe ich auch ausprobiert, sie funktionieren auch.
Der Fehler: Wahrscheinlich war ein Kondensator defekt oder sogar der 
Controller. Wenn ich den Fehler einwandfrei benennen kann schreibe ich 
nochmal.

An alle, die mich mit guten Tipps unterstützt haben vielen Dank.


Viele Grüße,

Felix

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.