Forum: Compiler & IDEs Frage zu GCC Tutorial LCD


von Marco M. (marco1987)


Lesenswert?

// Ansteuerung eines HD44780 kompatiblen LCD im 4-Bit-Interfacemodus
// http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial
//
void lcd_data(unsigned char temp1);
void lcd_string(char *data);
void lcd_command(unsigned char temp1);
void lcd_enable(void);
void lcd_init(void);
void lcd_home(void);
void lcd_clear(void);
void set_cursor(uint8_t x, uint8_t y);

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

#define F_CPU 8000000

// LCD Befehle

#define CLEAR_DISPLAY 0x01
#define CURSOR_HOME   0x02

// Pinbelegung für das LCD, an verwendete Pins anpassen

#define LCD_PORT      PORTD
#define LCD_DDR       DDRD
#define LCD_RS        PD4
#define LCD_EN        PD5
// DB4 bis DB7 des LCD sind mit PD0 bis PD3 des AVR verbunden



Hi Leute,

hoffentlich könnt ihr mir weiterhelfen.

Es ist mir irgendwie nicht möglich den PORT des LCDs von D auf B zu 
legen ich habe die defines folgender maßen abgeändert aber es geht nicht 
egal ob ich es mit portb oder c mache.

#define LCD_PORT      PORTB
#define LCD_DDR       DDRB
#define LCD_RS        PB4
#define LCD_EN        PB5

stellt man die Datenleitungen vermutlich wo anders ein?
Im Tutorial ist auch noch eine andere .c datei gegeben da habe ich aber 
nichts gefunden.

Danke

von Christian R. (mrrotzi)


Lesenswert?

Welchen Controller nimmst du?
Was passiert denn oder was geht nicht?

von Marco M. (marco1987)


Angehängte Dateien:

Lesenswert?

Ich benutze den ATmega16,

naja auf dem LCD wird halt nichts angezeigt, prinzipiell muss es doch 
möglich sein ein LCD an jedem Port anzusteuern oder?

Vllt kann sich jmd die Datei im anhang mal ansehen die brauche ich noch 
um das lcd anzusteuern und in der letzten zeile steht auch was von "D7 
bis D4 an PD" aber ich sehe nicht wo man das ändern kann.....ihr vllt?

von Soman (Gast)


Lesenswert?

Hi!
bevor ich für eine kleinigkeit ein neues thema aufmache wollte ich hier 
einfach kurz fragen:
was muß ich beachten, wenn ich mein lcd wie im tutorial (4-bit-mode) 
ansteuern will, mit dem unterschied, daß ich nicht Px[0-3] für daten 
nehme sondern Px[4-7]? die defines für en und rs und rw hab ich schon 
angepasst. mein gefühl sagt mir, daß ich den port dann nur anders herum 
maskieren muß. kommt das hin?
danke und vg,
Soman

von Stefan B. (stefan) Benutzerseite


Lesenswert?

@ Soman

Grundsätzlich ja.

ABER die zu ändernden Stellen sind ziemlich im Sourcecode verstreut und 
für Einsteiger nicht auf den ersten Blick erkenntlich

   temp1 = temp1 >> 4;
   temp1 = temp1 & 0x0F;
   LCD_PORT &= 0xF0;
   LCD_PORT |= temp1;               // setzen

würde in deinem Fall zu sowas

   temp1 = temp1 >> 4;
   temp1 = temp1 & 0x0F;
   LCD_PORT &= 0x0F;
   LCD_PORT |= temp1<<4;            // setzen

Ich würde deshalb alles versuchen, um die Leitungen doch noch auf Pins 
0-3 zu legen, bevor ich daran gehen würde, die Source zu ändern.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Marco M. wrote:
> Ich benutze den ATmega16,
>
> naja auf dem LCD wird halt nichts angezeigt, prinzipiell muss es doch
> möglich sein ein LCD an jedem Port anzusteuern oder?
>
> Vllt kann sich jmd die Datei im anhang mal ansehen die brauche ich noch
> um das lcd anzusteuern und in der letzten zeile steht auch was von "D7
> bis D4 an PD" aber ich sehe nicht wo man das ändern kann.....ihr vllt?

Die Zuordnung der LCD-Leitungen D4 bis D7 an die PORT-Pins 0 bis 3 ist 
implizit in der Source verankert. Es ist derzeit nicht vorgesehen das zu 
ändern (s. Beitrag vorher).

Generell ist bei LCD Problemen gerne die manuelle Kontrasteinstellung 
ein Problemverursacher. Lief das LCD bereits an deinem AVR?

von Soman (Gast)


Lesenswert?

Hallo nochmal!
vielen dank für die antworten! dann überleg ich mal mal was neues ;) ...
gruß!

von Soman (Gast)


Angehängte Dateien:

Lesenswert?

Sooo, ich bin das nochmal...
leider ist es bei der Sache, die ich hier vorliegen habe, nicht möglich 
die vier datenleitungen auf die pins[0-3] am µC zu legen. sie liegen 
also im moment so:

DB4 - PC4
DB5 - PC5
DB6 - PC6
DB7 - PC7

im anhang hab ich die beiden dateien, die sich auf das lcd beziehen. ich 
hab in der lcd-routines.c alles soweit verändert, daß die nibble in 
richtiger reihenfolge auf das obere port-nibble gelegt werden.
aber wer hätte es gedacht: es funktioniert nicht. ich sitze da echt 
schon stunden vor aber finde keinen fehler! im anhang gibt es außerdem 
das datenblatt meines lcd.
das teil ziegt die ganze zeit in der 1. und 3. zeile die berühmten 
balken an (ja, hab schon am kontrast gespielt ;) ...) daher glaube ich, 
daß bereits in der initialisierung ein fehler vorliegt.

könnte vielleicht einer von euch so nett sein und sich einmal kurz die 
routinen angucken? ich weiß echt nicht mehr weiter...

danke!
vg!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Warum ist das Umschalten des PORTC auf Ausgang im lcd_init 
auskommentiert? Vom RESET her ist der PORT als Eingang geschaltet. Das 
kann so nicht mit dem LCD funktionieren.

Hast du schon die Anmerkung im lcd_enable() gelesen und mal die 1us 
Pause verlängert? Bei mir hat das schon geholfen.
1
// erzeugt den Enable-Puls
2
void lcd_enable(void)
3
{
4
    // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers einfügen
5
    // http://www.mikrocontroller.net/topic/81974#685882
6
    LCD_PORT |= (1<<LCD_EN);
7
#if 1
8
    _delay_us(4); // kurze Pause, Original aus dem Tutorial ist bei meinem Display zu kurz!
9
#else
10
    _delay_us(1); // kurze Pause
11
#endif
12
    // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers verlängern
13
    // http://www.mikrocontroller.net/topic/80900
14
    LCD_PORT &= ~(1<<LCD_EN);
15
}

Ein Vergleich wäre wesentlich einfacher, wenn du alten Code und neuen 
Code in einer Source halten würdest z.B. mit #if oder #ifdef, #else und 
äendif. Im Moment muss man zwei getrennte Sourcefiles zeilenweise 
vergleichen.

Wie sind die nicht benutzten D0 bis D3 am LCD angeschlossen? Offen 
(nicht gut) oder direkt auf GND gelegt (auch nicht gut) per Pulldown auf 
GND gelegt (besser).

von Frank L. (franklink)


Lesenswert?

Hallo,
ich habe vor einiger Zeit in der Artikelsammlung einen Artikel 
eingestellt, in dem ich ein LCD über einen 74HC595 ansteuere.
Ich habe hier eine freie Portwahl implementiert. Für das setzen, der 
Ports, habe ich einen Algorithmus von PeDa verwendet.
1
void com74hc595_lcd_nibble( unsigned char d )
2
{
3
  com74hc595_unsetBit( LCD_B4 );
4
  com74hc595_unsetBit( LCD_B5 );
5
  com74hc595_unsetBit( LCD_B6 );
6
  com74hc595_unsetBit( LCD_B7 );
7
  
8
  if ( d & 1<<4 ) com74hc595_setBit( LCD_B4 );
9
  if ( d & 1<<5 ) com74hc595_setBit( LCD_B5 );
10
  if ( d & 1<<6 ) com74hc595_setBit( LCD_B6 );
11
  if ( d & 1<<7 ) com74hc595_setBit( LCD_B7 );
12
 
13
  if ( BackLightState == ON ) com74hc595_unsetBit( LCD_LIGHT );
14
  if ( BackLightState == OFF ) com74hc595_setBit( LCD_LIGHT );
15
 
16
  com74hc595_out();
17
 
18
     com74hc595_lcd_enable();
19
}
20
 
21
void com74hc595_lcd_Byte( unsigned char d )
22
{
23
   com74hc595_lcd_nibble( d );
24
  com74hc595_lcd_nibble( d<<4 );
25
    _delay_us( 45 );
26
}

Anstelle von com74hc595_setBit kannst Du das setzten des jeweilgen 
Portbis einsetzen können. Damit bist Du dann flexible.

Vielleicht habe ich in den nächsten Tagen mal Zeit, dann werde ich das 
LCD Tutorial um diese Möglichkeiten als ein Alternative ergänzen. Wobei 
das bestehende natürlich nicht verändert wird.

Gruß
Frank

von Soman (Gast)


Lesenswert?

@Stefan:
danke für die Antwort!
das umschalten auf ausgang habe ich rauskommentiert, weil das an anderer 
stelle im code bei mir passiert. aber drauf geachtet hab ich :)...
die anderen pins vom db hab ich offen gelassen. ich hab an mehreren 
stellen im netz gelesen, daß es da verschiedene meinungen drüber gibt. 
da hab ich eben die offene variante genommen. die pause hab ich auch 
schon vergrößert (auf 10µs) aber das brachte auch nüscht...
wie gesagt, sitze da jetzt schon recht lange dran und grübel. kann 
vielleicht jemand nen blick in das datenblatt werfen, ob die timings der 
steuerleitungen überhaupt richtig sind? ich hab schon selbst geguckt, 
aber ich konnt nichts gravierend falsches feststellen...

ist mein grundgedanke denn richtig, daß schon bei der ini was falsch 
läuft, wenn das lcd nix weiter als zwei balken anzeigt?

vg!

von Soman (Gast)


Angehängte Dateien:

Lesenswert?

ups, hier das datenblatt nochmalm damit sich keiner durch die rar-datei 
oben wühlen muß...

von Matt (Gast)


Lesenswert?

@Soman:

Verwendest Du auch einen ATmega16? Wenn ja, hast Du das JTAG-Interface 
deaktiviert? Wenn nicht, kannst Du PC4 und PC5 nicht als I/O verwenden.

von Soman (Gast)


Lesenswert?

hi Matt:
guter tipp, aber neun, das ist es auch nicht. ich hab nen atmega32 am 
laufen und verwende auch kein jtag... aber ich seh grad, daß die pins 
wohl genau so sind... gucke mal was da los ist. hab das jtag-ding nicht 
explizit deaktiviert...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dass die Init-Sequenz hakt, sehe ich auch so.

In deinem Datenblatt steht, dass der LCD Controller ein NT3881 ist. 
Das per Google zu findende Datenblatt für den NT3881 gibt leider nicht 
viel her zum Thema Initialisierung.

Es kann sein, dass die frei herumbambelnden D0-D3 Leitungen des LCDs die 
Initsequenz stören. Es ist sicherer, die auf GND zu legen. Dies macht 
man günstigerweise aber nicht direkt im Kurzschluss sondern über 
Pulldown-widerstände. Falls nach Murphys Law D0-D3 mal Ausgang wären, 
ist über die Pulldowns immer eine Strombegrenzung garantiert.

Weitere Tips zu einem sicheren Init z.B. hier:
http://sci.tech-archive.net/Archive/sci.electronics.design/2008-05/msg00443.html

Ich würde an deiner Stelle auch nach anderen Beiträgen mit diesem 
Controllertyp forschen.

von Soman (Gast)


Lesenswert?

soooo,
jetzt zeigt es was an. zwar nur unfug (wilde kombinationen aus "o" und 
"<-" und "0" und "?") aber es wird scheinbar initialisiert :) ! danke 
erstmal an alle, die sich gedanken gemacht haben!

@Stefan:
woher hast du das mit dem controller? ist ja nicht so, daß ich nicht ins 
db geguckt hätte :)... aber bei mir werden auch manche seiten 
nicht/fehlerhaft angezeigt...

gruß!

von Soman (Gast)


Angehängte Dateien:

Lesenswert?

also ich hab mal nen datenblatt zu dem NT3881 aufgetrieben. da steht zur 
init wirklich nicht viel drin. aber die registeraufteilung ist scheinbar 
gleich. außerdem hab ich auf dieser seite

http://www.stlcd.de/index.php?site=tutorials

folgendes gefunden: "Der bekannteste Controller ist der HD44780 
(eventuell nachfolgende Ziffern können ignoriert werden). Kompatibel 
dazu sind KS0066, LC7985, NT3881, SED1278 und ST7066."

müßte also passen. jetzt muß ich nurnoch rausfinden, wie ich das teil 
dazu bringe was sinnvolles an zu zeigen...

p.s.: es lag übrigens allem anschein nach an der sache mit den 
jtag-pins... das hätt ich nie selbst raus gefunden...

von Soman (Gast)


Lesenswert?

Das ufert ja langsam aus hier... ;)
ich mache mal lieber doch nen eigenes Threat auf...

Danke nochmal an alle!

Soman

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.