Problem mit LCD an ATMega 644

#1184985
Lesenswert?

Hi, ich versuche grade ein LCD 
(http://www.pollin.de/shop/downloads/D120060D.PDF) an einem Atmega 644 
anzuschließen, der steckt auf so einem ABR-NET-IO Board 
(http://www.pollin.de/shop/downloads/D810058B.PDF)
Die anleitung aus dem 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial passte nicht 
ganz da auf dem Board andere Ports für die Kommunikation vorgesehen 
sind, daher habe ich Codes hoffentlich korrekt angepasst.
Leider bekomme ich immer noch kein bild, das der LCD an sich geht weis 
ich da er am LPT Port mit dem Proggi stlcd Funtzt.

Könnte mit einer bitte helfen das zum laufen zu bekommen.
Angehängte Dateien:
Gast #1185002
Lesenswert?

Der Schaltplan ist in meinem ersten post 
http://www.pollin.de/shop/downloads/D810058B.PDF irgendwo in der Mitte 
ist ein plan des Boards, und am ende eine Pinbelegung für ein LCD am EXT 
Stecker.

Doppel Belegung sollte nicht sein die LCD Daten pins DB4 bis DB7 sollten 
auf die pins PD4 bis PD7 am atmel gehen, RW auf PD2, RS PD3, und Enable 
auf PB0
Persönliche Seite #1185009
Lesenswert?

> Der Schaltplan ist in meinem ersten post
> http://www.pollin.de/shop/downloads/D810058B.PDF irgendwo in der Mitte
> ist ein plan des Boards, und am ende eine Pinbelegung für ein LCD am EXT
> Stecker.

Du musst es wissen, ob du deinen aktuellen Aufbau zeigst oder 
irgendwas in der Mitte in verschiedenen Hersteller-PDFs zweier 
Baugruppen.

Ich hätte die Frage anders gestellt bzw. nach einer Rückfrage 
schleunigst den Schaltplan beigeschafft ;-)

> Doppel Belegung sollte nicht sein die LCD Daten pins DB4 bis DB7 sollten
> auf die pins PD4 bis PD7 am atmel gehen, RW auf PD2, RS PD3, und Enable
> auf PB0

Der Kommentar im Code sagt was anderes.

Der Kommentar stammt aus der Originalsource aus dem AVR-GCC-Tutorial. Es 
könnte natürlich sein, dass du im eigentlichen LCD-Code umprogrammiert 
hast und nur den Kommentar unverändert übernommen hast. Ich habe im Code 
nachgesehen, ob dementsprechende Kommentare vorhanden sind. Das ist 
nicht der Fall. Eine weitere Analyse habe ich deshalb (und weil der 
Schaltplan nicht vorliegt) nicht gemacht.
Gast #1185012
Lesenswert?

Ich habe den code umgeschrieben um auf die höheren bits des Ports zu 
schreiben, ich habe nichts kommentiert und auch die alten Kommentare 
unverändert gelassen da das alles es eher schell und provisorisch war.

Ich hoffe das das so stimmt, weis aber nicht mit Sicherheit ob ich da 
alles richtig umgeändert habe.

Der Schaltplan entspricht zu 100% der Beschreibung im PDF damit das dann 
auch mit der originalen firmware kompatibel ist falls ich aus 
irgendeinem Grund wieder den kleineren Atmega 32 mit der Pollin Software 
reinsetzen möchte.
#1185853
Lesenswert?

habe das jetzt mit eigenem code am LPT port halbwegs zum laufen 
gebracht, leider funtzt die 2te zeile immer noch nicht, und wen ich am 
anfang 0011 auf die daten pins lege so wie im tutorial beschrieben kommt 
kein bild.

Hat wer ne idee wie man das ding zum laufen kebommen kan?
1
#define LCD_EN 0
2
#define LCD_RS 2
3

4
void EN(int x)
5
{
6
  UCHAR value = DlPortReadPortUchar(0x37A);
7
  if(!x)  // ACHTUNG INVERTIERT!
8
    value |= (1<<LCD_EN);
9
  else
10
    value &= ~(1<<LCD_EN);
11
  DlPortWritePortUchar(0x37A,value);
12
}
13

14
void RS(int x)
15
{
16
  UCHAR value = DlPortReadPortUchar(0x37A);
17
  if(x)
18
    value |= (1<<LCD_RS);
19
  else
20
    value &= ~(1<<LCD_RS);
21
  DlPortWritePortUchar(0x37A,value);
22
}
23

24
__inline void _delay_us(int c)
25
{
26
  for(int i=0;i<c*800;i++)
27
    __noop;
28
}
29

30
__inline void _delay_ms(int c)
31
{
32
  Sleep(c);
33
}
34

35
// erzeugt den Enable-Puls
36
void lcd_enable(void)
37
{
38
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
39
  // http://www.mikrocontroller.net/topic/81974#685882
40
  EN(1);
41
  _delay_us(1);
42
  // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
43
  // http://www.mikrocontroller.net/topic/80900
44
  EN(0);
45
}
46

47
void lcd_send(unsigned char temp1, unsigned char rs)
48
{
49
   unsigned char temp2 = temp1;
50

51
   RS(rs);                    // RS auf x setzen
52

53
   temp1 = temp1 >> 4;              // oberes Nibble holen
54
   temp1 = temp1 & 0x0F;            // maskieren
55

56
   UCHAR value = DlPortReadPortUchar(0x378);
57
   value &= 0x0F;
58
   value |= temp1 << 4;        // setzen
59
   DlPortWritePortUchar(0x378,value);
60
   lcd_enable();
61

62
   temp2 = temp2 & 0x0F;            // unteres Nibble holen und maskieren
63
   value &= 0x0F;
64
   value |= temp2 << 4;        // setzen
65
   DlPortWritePortUchar(0x378,value);
66
   lcd_enable();
67

68
   _delay_us(42);
69
}
70

71
void lcd_nibble(unsigned char temp1)
72
{
73
  UCHAR value = DlPortReadPortUchar(0x378);
74
  value &= 0x0F;
75
  value |= temp1 << 4;        // setzen
76
  DlPortWritePortUchar(0x378,value);
77
  lcd_enable();
78
}
79

80
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
81
{
82

83
#if 1
84
  EN(0);
85
  RS(0);
86

87
    // lcd_nibble(3); - wen das an ist gibts kein bild
88

89
    _delay_ms(5);
90
    lcd_enable();
91
    _delay_ms(5);
92
    lcd_enable();
93
    _delay_ms(5);
94

95

96
  lcd_nibble(2);  // Enable 4-bit mode
97

98
  Sleep(140);
99

100
  lcd_send(0x06,0); // inkrement / kein Scrollen
101
  lcd_send(0x0C,0); // Display ein / Cursor aus / kein Blinken
102
  //lcd_send(0x28,0); //4 Bit Operation,2 Line,5x7 Font  5  --  wen das an ist gibts kein bild
103
  
104

105
  lcd_send(0x01,0); // Clear Display
106

107
  Sleep(500);
108

109
  // Write Line 1
110
  lcd_send(0x80,0); // Line 1
111

112
  lcd_send('0',1);
113
  lcd_send('1',1);
114
  lcd_send('2',1);
115
  lcd_send('3',1);
116
  lcd_send('4',1);
117
  lcd_send('5',1);
118
  lcd_send('6',1);
119
  lcd_send('7',1);
120
  lcd_send('8',1);
121
  lcd_send('9',1);
122
  lcd_send('A',1);
123
  lcd_send('B',1);
124
  lcd_send('C',1);
125
  lcd_send('D',1);
126
  lcd_send('E',1);
127
  lcd_send('F',1);
128

129
  // Write Line 2
130
  lcd_send(0xC0,0); // Line 2 (does not work yet)
131

132
  lcd_send('f',1);
133
  lcd_send('e',1);
134
  lcd_send('d',1);
135
  lcd_send('c',1);
136
  lcd_send('b',1);
137
  lcd_send('a',1);
138
  lcd_send('9',1);
139
  lcd_send('8',1);
140
  lcd_send('7',1);
141
  lcd_send('6',1);
142
  lcd_send('5',1);
143
  lcd_send('4',1);
144
  lcd_send('3',1);
145
  lcd_send('2',1);
146
  lcd_send('1',1);
147
  lcd_send('0',1);
148

149
  Sleep(5000);
150

151
  // Clear Diaplay x2
152
  lcd_send(0x01,0);
153
  lcd_send(0x01,0);
Persönliche Seite #1185876
Lesenswert?

> leider funtzt die 2te zeile immer noch nicht

Das ist ein Indiz dafür, dass die Softwareresetsequenz des LCDs nicht 
funktioniert, bei dem die Anzahl der Zeilen eingestellt wird.

Der Kommentar
>   //lcd_send(0x28,0); //4 Bit Operation,2 Line,5x7 Font  5
>                         --  wen das an ist gibts kein bild
passt dazu.

Insgesamt kann das mehrere Ursachen haben:

1/ Die Hardwareresetsequenz des LCDs ist noch nicht angeschlossen, wenn 
versucht wird, per Sofware zu resetten und auf 2 Zeilen zu 
initialisieren. Hier könnte eine längere Wartezeit (mehrere 100 ms) vor 
dem lcd_init() helfen.

2/ Das Timing zwischen den einzelnen Befehlen an das LCD stimmt nicht. 
Wenn mit Warteschleifen gearbeitet wird, müssen diese auch 
funktionieren. D.h. bei _delay_us und _delay_ms muss Optimierung 
eingeschaltet sein usw. Die Zeiten an sich müssen mit dem Datenblatt 
übereinstimmen. Die LCD-Library aus dem AVR-GCC-Tutorial hat z.B. auch 
einen Kommentar zur Länge des EN-Pulses...

3/ Die Befehle an sich müssen stimmen. Es gibt unterschiedliche 
LCD-Controller, die unterschiedlich behandelt werden müssen.

4/ Die Verdrahtung muss passen. Die originale LCD-Library aus dem 
AVR-GCC-Tutorial berücksichtigt z.B. die R/W Leitung nicht, sondern 
arbeitet mit festen Warteschleifen. Umgekert heisst das diese Leitung 
muss auf "Dauerwrite" stehen, d.h. über einen Pulldown auf LOW gezogen 
werden.

Mit http://www.pollin.de/shop/downloads/D120060D.PDF kann man das Timing 
und die Befehle nicht kontrollieren, weil sie einfach darin nicht 
angegeben sind. Und für vergleichbare Datenblätter fehlt die Angabe 
welcher LCD-Controller verbaut ist.
Persönliche Seite #1185941
Lesenswert?

Richtig, der HD44780 ist es. Das ist eigentlich der Klassiker. Die 
LCD-Library im Tutorial ist darauf zugeschnitten.

Teste mal mit den drei Änderungen:

1/ Längere Wartezeit vor lcd_int()
2/ _delay_us(4); statt _delay_us(1); in lcd_enable()
3/ R/W Leitung über 10K Pulldown an GND gebunden

Wenn es geht, markiere die Zeilen im Code, die du geändert hast. Dann 
braucht man nicht zwei Dateien miteinander zu vergleichen.
1
void lcd_enable(void)
2
{
3
  LCD_PORT_EX |= (1<<LCD_EN);
4
  _delay_us(4);                   // kurze Pause (geändert)
5
  // _delay_us(1);                   // kurze Pause (Original)
6
  LCD_PORT_EX &= ~(1<<LCD_EN);
7
}

Man auch oben in der Datei ein Symvol definieren und das entsprechend 
wahr oder falsch setzen. Ich mache das normalerweise so, weil ich dann 
einfach zwischen Originalcode und geändertem Code umschalten kann:

#define NEUER_CODE 1
...
#if NEUER_CODE
  // hier neuer Code
  _delay_us(4);                   // kurze Pause (geändert)
#else
  // hier alter Code
  _delay_us(1);                   // kurze Pause (Original)
#endif /* NEUER_CODE */

Viel Arbeit? Denk mal so: Wenn dir diese Arbeit beim Schreiben des Codes 
bereits zuviel ist, wieviel Arbeit mag sich der potentielle Problemlöser 
beim Lesen des Codes machen?
#1187294
Lesenswert?

Also mit dem Code im Anhang funtzt die erste Zeile vom LCD, und der code
sollte jetzt lesbarer sein ;)
Die Wartezeiten haben nichts geändert, R/W ist auf GND, und ich habe
etwas die Pinbelegung geändert so das nur noch Port D benutzt wird, aber
wie vorher in Umgekehrte nibble folge.

Pin #-LCD  Bezeichnung-LCD  Pin-µC
1  Vss  GND
2  Vcc  5V
3  Vee  GND
4  RS  PD3 am AVR
5  RW  GND
6  E  PD2 am AVR
7  DB0  offen
8  DB1  offen
9  DB2  offen
10  DB3  offen
11  DB4  PD4 am AVR
12  DB5  PD5 am AVR
13  DB6  PD6 am AVR
14  DB7  PD7 am AVR

lcd_command(0x28); // 4Bit  2 Zeilen  5x7 wird nun akzeptiert jedoch
geht wie vorher nur eine Zeile

in der soft Reset Routine musste ich das 0x30 mit einem 0x20 wie bei auf
4-bit setzen tauschen sonst kein bild

laut der Seite da: http://www.geocities.com/dinceraydin/lcd/commands.htm
ist 0x20 4-bit 1 Zeile und 0x28 4-bit 2 Zeilen
kann es sein das da das LCD jetzt immer auf eine Zeile initialisiert und
sich danach nicht mehr auf 2 umstellen lässt?

Ich könnte mal versuchen DB3 auf +5v mit einem 10k zu setzen so das
solange das teil am initialisieren ist und noch im 8 bit Modus es sofort
auf 4 bit 2 Zeilen gesetzt wird also mit einem 0x28, glaubst Du das ist
ne gute Idee?
Angehängte Dateien:
Persönliche Seite #1191251
Lesenswert?

Trax Xavier wrote:

> bzw: wo gibt es ein sample welches das Busy evaluiert?

"R/W Leitung vom Text-LCD ist fix mit GND verbunden und die Ansteuerung 
mit der LCD/AVR-Library von Peter Fleury funktioniert nicht! Was ist 
los?
Die Fleury LCD Library erwartet, dass R/W nicht fix ist, sondern vom 
Programm gesteuert werden kann. Das muss auch so sein, denn Peter liest 
das Busy Flag aus, um Warteschleifen zu vermeiden."
http://www.mikrocontroller.net/articles/LCD#FAQ
#1192554
Lesenswert?

Naja, wie könnte es den anders sein auch mit dem auslesen des busy flag 
funtzt das kack teil nicht!!!

erst wen ich die Zeile:
LCD_DATA0_PORT |= _BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
mit der
LCD_DATA0_PORT &= ~_BV(LCD_DATA0_PIN);  // _BV(LCD_FUNCTION_8BIT)>>4;
Ersätze funtzt die 1te Zeile, das selbe wie bei dem lcd_drv code ohne 
busy flag.

Hat den niemand dieses model und könnte mir verraten wie man damit 
zurecht kommt?
Gast #1192575
Lesenswert?

>Hat den niemand dieses model und könnte mir verraten wie man damit
>zurecht kommt?

Folge dem Datenblatt und programmiere alles 1:1.
Wenn es kein vernünftiges Datenblatt gibt dann schmeiss
das Teil einfach weg. Besorg dir ein LCD
für das es ein ausreichendes Datenblatt gibt.

Vieleicht ist dein LCD bei deinen Versuchen
beschädigt worden oder war schon defekt.

Aber wer kann das schon wissen.

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