Forum: Mikrocontroller und Digitale Elektronik ulrichradig.de 's LCD Code und 16x2 LCD


von Pascal G. (pascalg)


Lesenswert?

Hallo again,

langsam bin ich am verzweifeln. Ich möchte endlich ein Erfolgserlebnis 
bezüglich LCD haben und bekomme es nicht (seit Monaten!)...

Ich habe auch schon bereits im Forum bei ulrichradig.de geschrieben 
leider aber noch keine Antwort erhalten und erhoffe mir daher hier 
eine...

Also:
Ich habe ein LCD 16x2 von Reichelt (HD44780 kompatibel), Best.nr. 
LCD162C LED. Dann habe ich einen ATmega32. Der ATmega32 wird ganz nach 
Vorlage mit Betriebsspannung versorgt usw.
Auf dem uC ist ein Programm für eine Uhr, das läuft auch soweit. Für das 
LCD nehme ich die Vorlage von ulrichradig.de (hier zu finden: 
http://www.ulrichradig.de/home/uploads/File/AVR_LCD/lcd_display.zip). 
Angeschlossen habe ich das Display an PortA und zwar so:

ATmega32       LCD
40 - PA0       11 - D4
39 - PA1       12 - D5
38 - PA2       13 - D6
37 - PA3       14 - D7
36 - PA4       4 - RS
35 - PA5       5 - RW
34 - PA6       6 - E

Das LCD bekommt noch Vcc, GND, Kontrast und Backlight.

Im Quellcode in der lcd.h habe ich u.a. das hier stehen:
1
...
2
//Prototypes
3
extern void lcd_write (char,char);
4
extern char lcd_read (char);
5
extern void lcd_init (void);
6
extern void lcd_clear (void);
7
extern void lcd_print_P (unsigned char,unsigned char,const char *Buffer,...);
8
extern void lcd_print_str (char *Buffer);
9
#define lcd_print(a,b,format, args...)  lcd_print_P(a,b,PSTR(format) , ## args)
10
11
//LCD_D0 - LCD_D3 connect to GND
12
//Im 4Bit Mode LCD_D4-->PORTx.0 ........ LCD_D7-->PORTx.3
13
//LCD_RS --> PORTx.4 | LCD_RW --> PORTx.5 | LCD_E --> PORTx.6 | PORTx.7-->NotConnect
14
15
//Anzahl der Zeilen 1,2 oder 4
16
//#define ONE_LINES          
17
#define TWO_LINES          
18
//#define THREE_LINES          
19
//#define FOUR_LINES          
20
21
#define LCD_Port_DDR      DDRA  //Port an dem das Display angeschlossen wurde
22
#define LCD_Port_Write      PORTA
23
#define LCD_Port_Read      PINA
24
25
#define LCD_RS          4     //Pin für RS
26
#define LCD_RW          5    //Pin für Read/Write
27
#define LCD_E          6     //Pin für Enable
28
#define LCD_LED          7     //Pin für Hintergrund LED
29
30
#define LCD_DataOutput      0x0f
31
#define LCD_DataInput      0x00
32
33
#define BUSYBIT          7
34
35
#define NOP()  asm("nop")
36
#define WAIT()   for (unsigned char b=0;b<200;b++){NOP();}
37
...

Sollte doch so richtig sein, oder? Programmiert habe ich den Atmega32 
mit dem STK500, JTAG ist aus, die Fuses sind richtig, auch die Uhrdaten 
kommen vom uC auf der RS232 raus, so dass der läuft. Auf meiner 
Streifenrasterplatine wo dann der uC drauf kommt und auch das LCD alle 
Signale und Pegel bekommt sollte auch alles stimmen (x-mal 
kontrolliert). Da kann ich mit dem Oszi auch die Seriellen Daten an TXD 
bzw. RXD sehen und auch aus den Pins von PortA kommen Bits die auch 
gleich an der Stiftleiste des LCD ankommen.
Trotzdem sehe ich nach dem Einschalten der Spannung nur in der ersten 
Zeile des LCD ################ und sonst tut sich nichts.

In meiner main.c sind natürlich auch u.a. drin
1
  lcd_init();
2
  lcd_clear();
so dass ja eigentlich die ### weggehen sollten, aber auch dann werden ja 
die Uhrzeitdaten aufs Display mit
1
      lcd_print(0,0,"%2i.%2i.%4i RX: %i",day,mon,year,flags.dcf_rx);
2
      lcd_print(1,0,"%2i:%2i:%2i SYNC: %i",hh,mm,ss,flags.dcf_sync);
geschrieben.

Was mache ich nur falsch? Und was hat in der lcd.h u.a. die Zeile 
#define LCD_DataOutput      0x0f mir zu sagen? Ist da evt. mein Fehler?

Bitte helft mir, das mit dem LCD kann doch nicht so verflixt schwer 
sein?

Danke!
Grüße Pascal

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Hast du mal versucht, irgendwas Einfaches auf dem LCD auszugeben?
Z.B. einen festen Text ("Hallo Welt")?

von Klaus W. (mfgkw)


Lesenswert?

Der Beschreibung nach ist das LCD bzgl. Versorgung etc. korrekt
angeschlossen.

Ich habe nur mal kurz in den Quelltext gesehen.
1. in lcd.c steht gleich am Anfang "Standart" statt "Standard"
2. Warteschleifen werden mit einer bestimmten Anzahl NOP
   realisiert.

Weiter habe ich nicht gelesen.
Vorschlag: nimm eine andere Vorlage; ich zumindest würde da gar
nicht erst nach Fehlern suchen.
Es gibt hier im Forum diverse funktionierende.

von Karl H. (kbuchegg)


Lesenswert?

Pascal G. schrieb:

> Also:
> Ich habe ein LCD 16x2 von Reichelt (HD44780 kompatibel), Best.nr.
> LCD162C LED. Dann habe ich einen ATmega32. Der ATmega32 wird ganz nach
> Vorlage mit Betriebsspannung versorgt usw.

Da du das LCD am Port A betreibst:
AVcc ist ebenfalls angeschlossen?

von Pascal G. (pascalg)


Lesenswert?

Karl heinz Buchegger schrieb:
> Pascal G. schrieb:
>
>> Also:
>> Ich habe ein LCD 16x2 von Reichelt (HD44780 kompatibel), Best.nr.
>> LCD162C LED. Dann habe ich einen ATmega32. Der ATmega32 wird ganz nach
>> Vorlage mit Betriebsspannung versorgt usw.
>
> Da du das LCD am Port A betreibst:
> AVcc ist ebenfalls angeschlossen?

Nein, AVCC ist nicht angeschlossen. Muss ich das für PortA?

Habe am Atmega32 dran:
Reset, 9 (mit Widerstand und so)
VCC, 10
GND, 11
PA0 ... PA6, 40 ... 34 (s.o.)
GND, 31

Sonst ist alles ohne Anschluß. Ist das mein Fehler?

Grüße

von Karl H. (kbuchegg)


Lesenswert?

Pascal G. schrieb:
> Karl heinz Buchegger schrieb:
>> Pascal G. schrieb:
>>
>>> Also:
>>> Ich habe ein LCD 16x2 von Reichelt (HD44780 kompatibel), Best.nr.
>>> LCD162C LED. Dann habe ich einen ATmega32. Der ATmega32 wird ganz nach
>>> Vorlage mit Betriebsspannung versorgt usw.
>>
>> Da du das LCD am Port A betreibst:
>> AVcc ist ebenfalls angeschlossen?
>
> Nein, AVCC ist nicht angeschlossen. Muss ich das für PortA?

Warum bloss hatte ich das im Urin?

Jaaaaaa

> Sonst ist alles ohne Anschluß. Ist das mein Fehler?
Am besten siehst du dir mal eine Standardbeschaltung an, wie sie 
wirklich aussehen soll

http://www.mikrocontroller.net/articles/AVR-Tutorial:_Equipment#Selbstbau

Die wendest du sinngemäss auf deinen Mega32 an.

Möglich, dass das dein Problem schon behebt.

von Klaus W. (mfgkw)


Lesenswert?

Karl heinz Buchegger schrieb:
> ...
> Warum bloss hatte ich das im Urin?

Weil du es selber dauernd vergisst?  :-)

> ...

von Pascal G. (pascalg)


Lesenswert?

Also,

ich habe die Belegung des mega8 auf den 32 übertragen und nun noch 5V an 
AVCC gelegt und Aref mit 100n gegen GND.
An Reset liegen 5 V an, an VCC und AVCC auch 5 V. An den beiden GND 
liegen 0V (GND) an. Die 5V zum uC sind immer kurz vorm Sockel mit 100n 
gegen GND geblockt. Auf den Leitungen zum LCD kommen ja auch Bits, aber 
irgendwie initialisiert das scheinbar nicht. Auch ein anderes LCD zeigt 
dieses Bild. (habe auch einen weiteren mega32 schon probiert).

Muss ich wirklich eine andere lcd lib nehmen? Welche?

Grüße

von Pascal G. (pascalg)


Lesenswert?

Also ich habe jetzt mal die Radig lib durch die Fleury lib getauscht. 
Das selbe Bild. Da muss ich irgendein Fehler noch haben, nur ich weiß 
echt nicht mehr wo ich suchen soll.

von gast (Gast)


Lesenswert?

hi pascal,


wenn das display nur die erste zeile zeigt (sprich einen balken) ist es 
nicht initialisiert. das wird in nach dem call gemacht wo auf 4 bit 
umgestellt wird soweit ich mich erinner (ist schon ein wenig her als ich 
das das letzte mal gemacht hab).


vielleicht hast du ja ein timing problem. vielleicht lief der code vom 
radig auf einem lamgsameren prozessor. (ich kenn die avrs nicht. nur 
eine vermutung) kann ja auch schon durch andere optimiser einstellungen 
ggf veraendert werden.
die displays sind teilweise etwas empfindlich wenn du nicht das timing 
einhaelst. langsamer ist kein problem nur zu schnell machen sie dicke 
backen.

ich wuerd einfach mal ueberall dort wo gewartet wird mal einen wert 
nehmen den du vorher als #define definierst. und einfach mal langsamer 
ansteuern...


ein anderes problem ist ggf... zu lange kabel... ich hatte es schon das 
durch ein kabel welches so um die 15 cm war das E signal so 
verschlechtert wurde das das display das nicht mehr richtig erkannt 
hat... einige sind da wohl nicht so tolerant.
eine moeglichkeit ist einfach das kabel zu kuerzen die andere durch z.b. 
einen bus-treiber das signal aufzufrischen... aber wenn wuerd ich 
natuerlich erst das mit dem kabel probieren sprich kuerzer machen...

vielleicht hilft das ja ...

viel glueck ;)

von gast (Gast)


Lesenswert?

nen tip :

prüfe die hardware
notfalls verdrahte neu und schreibe dir die pinbelegung auf


noch nen tip:

schreibe selbst die LCD routinen ebenso uart und sowanstwas
dann verstehst du ddas ganbze vieleicht auch



sry ^^
aber so ging es mir selbst vor nen halben jahr

alle libs zusammensuichen geht auch mal ...
aber gerade wenn man keinen plan hat ... einfach lernen und selbst 
schreiben

von MeinerEiner (Gast)


Lesenswert?

Was ist mit den Datenpins DB0-DB3 vom Display? Liegen die offen oder 
definiert auf Masse?

von gast (Gast)


Lesenswert?

hm d0-d3 auf masse.

ich lass die immer so im undefinierten zustand und hat noch nie probleme 
damit.

von gast1 (Gast)


Lesenswert?

hi pascal,

ich hab mal eben das experimentierboard von radig angesehen... so wie 
ich das sehe laeuft der proz mit 12 mhz... der atmega laeuft doch mit 16 
oder ?

dann hab ich nochmal den source ueberflogen... und allein das was du 
gepostet hast reicht schon:
/../
#define NOP()  asm("nop")
#define WAIT()   for (unsigned char b=0;b<200;b++){NOP();}
/../

sprich die warteschleife ist absolut abhaengig von dem quarz wenn du mit 
16 mhz laeuft steuerst du das display ggf. zu schnell an...
eigentlich ist es besser solch schleifen ueber einen timer zu machen und 
ggf. wenn man den quarz wechselt den den timer anpasst... so ist es auf 
jeden fall genauer als ne einfache warteschleife (z.b. wenn irq usw 
dazwischen kommen )... aber so genau muss es ja nicht sein... mach mal 
irgendwie sowas

#define WAIT()   for (unsigned char b=0;b<200*4;b++){NOP();}

und mit der 4 spielst du bisschen...

ja weiterhin viel glueck... und weitermachen!!!
bei mir hats auch ewig gedauert bis das display mal ging... hatte nur 
von programmieren ahnung aber nicht so von hardware...

gerade bei der fehlersuche lernt man enorm viel... man liest 
datenblaetter viel intensiver... was einem spaeter zugute kommt... und 
wenns dann endlich laeuft ist es zeit nen bier zu oeffnen und sich 
zurueckzulehnen ;) immer wieder schoen wenn was klappt...

alles selbst schreiben ist als anfaenger denke ich nicht so die gute 
idee... am anfang ist man froh wenn ueberhaupt mal was laeuft da wird 
man total erschlagen von sachen die man beachten muss... natuerlich muss 
man spaeter mal anfangen sachen selbst zu machen... klar sonst kommt man 
nicht weit...

lg ;)

von gast (Gast)


Lesenswert?

#define WAIT()   for (unsigned char b=0;b<200*4;b++){NOP();}

schick ^^
200*4 = 800 .. wenn char b mal über 255 kommt ... sag bescheid


wie gesagt

schreibe dir selbst LCD  routinen
ist vielciht anfangs  schwer aber man weiß danach definitiv mehr wie das 
ganze funktioniert

von gast1 (Gast)


Lesenswert?

hm hust stimmt auffallend ;)

#define WAIT()   for (short b=0;b<200*4;b++){NOP();}

oder NOP() mehrmals aufrufen

von Peter D. (peda)


Lesenswert?


von Pascal G. (pascalg)


Lesenswert?

Hallo Leute!

... und ersteinmal ganz vielen Dank für die tollen und zahlreichen 
Informationen zum Thema. Ich habe heute mal wieder ein wenig Zeit zum 
Basteln gefunden und einfach mal den PortC statt PortA genommen und 
siehe da:
selbst mit der Radig Lib läuft es sofort. Komisch ist aber nur, dass ich 
1:1 genauso verdrahtet habe, also einfach nur die Stiftleiste um die 
Pins nach unten versetzt und 180° gedreht habe, so dass wieder PA0 = PC0 
wird. Echt so seltsam das Ganze!? Muss man denn evt. doch noch irgendwas 
in den Fuses einstellen damit der PortA (A/D Wandler Port) die digitalen 
Daten richtig rausgibt? (also mal abgesehen von AVCC auf 5V und AGND auf 
GND).

Grüße Pascal

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.