Forum: Mikrocontroller und Digitale Elektronik keine Ausgabe am LCD mit ATmega32


von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

hallo,

ich komm mal wieder nicht weiter, habe ein 4x20 Zeichen LCD von 
reichelt.
Datenblatt: Controller & LCD Driver ST7066U-0A-B & ST7065C
habe eine einfache kleine LCD bibliothek, habe die Port belegung schon 
überprüft, an der verdrahtung sollte es nicht liegen, habe auch grob den 
Kontrast verändert, aber außer das komplette schwarze blöcke auftreten 
ändert sich nichts.

hier mal der kurze code, vllt is da ja schon der fehler drin, bin für 
jede idee dankbar!

#define F_CPU 4000000
#include  <avr\io.h>
#include  <util\delay.h>
#include  <lcd-neu.h>



/*
// LCD AUSGABE
//lcd_write()  sendet eine Zeichenkette an das LCD

void lcd_write(char* pText)
{
  while(pText[0]!=0)
  {
    lcd_write(pText[0]);
    pText++;
  }
}
*/
// Programm

main ()
{
  DDRD = 0xff;

  _delay_ms(200);
  lcd_init();
  _delay_ms(20);
  //lcd_goto(1,1);
  _delay_ms(20);
  while(1);
  {
    lcd_string("HALLO");
    _delay_ms(200);
  }

}

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

als ergänzung, noch kurz aus der quelle, vllt liegt ja auch hier der 
fehler..

void lcd_string(char *data)
{
    while(*data) {
        lcd_data(*data);
        data++;
    }
}

von Hc Z. (mizch)


Lesenswert?

Es fehlt das Listing von lcd_init().  Da es sich (vermutlich) um ein 
Initialisierungsproblem handelt, ist das höchst unpraktisch.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

hier die initialisierung,

void lcd_init(void)
{
   // Ports auf Ausgang schalten
   LCD_DDR_4 |=(1<<LCD_D4);
   LCD_DDR_5 |=(1<<LCD_D5);
   LCD_DDR_6 |=(1<<LCD_D6);
   LCD_DDR_7 |=(1<<LCD_D7);

   LCD_EN1_DDR |= (1<<LCD_EN1);

   LCD_RS_DDR  |= (1<<LCD_RS);
   // muss 3mal hintereinander gesendet werden zur Initialisierung

   _delay_ms(15);

   LCD_PORT_4 |=  (1<<LCD_D4);
   LCD_PORT_5 |=  (1<<LCD_D5);
   LCD_PORT_6 &= ~(1<<LCD_D6);
   LCD_PORT_7 &= ~(1<<LCD_D7);

   LCD_RS_PORT &= ~(1<<LCD_RS);      // RS auf 0
   lcd_enable();

   _delay_ms(5);
   lcd_enable();

   _delay_ms(1);
   lcd_enable();
   _delay_ms(1);

   // 4 Bit Modus aktivieren



   LCD_PORT_4 &=  ~(1<<LCD_D4);
   LCD_PORT_5 |=   (1<<LCD_D5);
   LCD_PORT_6 &=  ~(1<<LCD_D6);
   LCD_PORT_7 &=  ~(1<<LCD_D7);

   lcd_enable();
   _delay_ms(1);

   // 4Bit  2 Zeilen  5x7
   lcd_command(0x28);

   // Display ein  Cursor aus  kein Blinken
   lcd_command(0x0C);

   // inkrement / kein Scrollen
   lcd_command(0x06);

   lcd_clear();
}

von Codeleser (Gast)


Lesenswert?

Dein Code nach   while(1);
wird nicht aufgerufen, das Semikolon hinter while(1) muss weg!

weitehin,
ist das ein Tipfehler ???
Du willst mit lcd_string was ausgeben,
zeigst aber die Funktion lcd_write und selbst diese
ruft sich lediglich selbst auf.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

jo, probier das grad mit dem entfernten semikolon aus, das lcd_write ist 
auskommentiert, sry das ich das aus dem  code nicht entfernt habe, melde 
mich gleich wieder:-)

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

funktioniert leider trotzdem nicht

von Codeleser (Gast)


Lesenswert?

nur mal als Anmerkung,
wenn der Kontrast zu stark ist, d.h. alles schwarz,
kann man auf dem Display keine Zeichen erkennen ;-)

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

Kontrast scheint ok zu sein ist bei etwa 1Volt, daran liegts wohl auch 
nicht, hab auch leider keine Idee mehr woran das liegen kann das keine 
reaktion kommt

von Codeleser (Gast)


Lesenswert?

ich benutze die Lib von P.Fleury , auch im 4bit-Mode.
Ist das Display kompatibel zum HD44780-Standard ?
Hast Du die Lib selber geschrieben oder aus dem Internet ?

von Codeleser (Gast)


Lesenswert?


von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

also, ich hab die lib aus dem netz, wenn du mir die lib von p.fleury mal 
geben könntest wäre das nett, vllt funkts ja.
der controller wurde mir von reichelt als kompatibel verkauft, ich 
verlass mich da mal drauf!

von Hc Z. (mizch)


Lesenswert?

Wenn es ein 44780-kompatibles Display ist (und die meisten Kommandos 
deuten darauf hin), werden während der ersten 2 E-Pulse falsche Daten 
gesendet (0x3 statt 0x2).

EDIT: Es fehlt auch der Code für lcd_command.  Auch dort kann man 
durchaus was falsch machen.

von Codeleser (Gast)


Lesenswert?


von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

void lcd_command(unsigned char temp1)
{
   unsigned char temp2 = temp1;

   LCD_RS_PORT &= ~(1<<LCD_RS);        // RS auf 0 setzen

   temp1 = temp1 >> 4;              // oberes Nibble holen
   temp1 = temp1 & 0x0F;

   LCD_PORT_4 &= ~(1<<LCD_D4);
   LCD_PORT_5 &= ~(1<<LCD_D5);
   LCD_PORT_6 &= ~(1<<LCD_D6);
   LCD_PORT_7 &= ~(1<<LCD_D7);            // maskieren

   if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
   if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
   if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
   if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
   lcd_enable();

   temp2 = temp2 & 0x0F;

   LCD_PORT_4 &= ~(1<<LCD_D4);
   LCD_PORT_5 &= ~(1<<LCD_D5);
   LCD_PORT_6 &= ~(1<<LCD_D6);
   LCD_PORT_7 &= ~(1<<LCD_D7);        // unteres Nibble holen und 
maskieren

   if(temp2 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
   if(temp2 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
   if(temp2 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
   if(temp2 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
   lcd_enable();

   _delay_us(42);
}

von Codeleser (Gast)


Lesenswert?

@ Hc Zimmerer:

hast Du Deinen Beitrag nachträglich noch mal geändert,
siehe EDIT.
wie geht das ?

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

Zitat   während der ersten 2 E-Pulse falsche Daten
        gesendet (0x3 statt 0x2).


versteh leider nicht was du damit meinst, was muss ich ändern, und was 
ist der fehler?


danke für die lib!!!, werde es auch damit testen!

von Hc Z. (mizch)


Lesenswert?

Also die Bitmanipulation, die üben wir nochmal.  Es scheint bei Dir 
systematisch zu sein, dass Du die Bits einzeln löschst und danach 
einzeln reinklopfst anstelle ein einfaches
1
LCD_PORT = (LCD_PORT & 0xf) | (temp1 << 4);
zu machen.  Führ Dir mal zu Gemüte, warum das dasselbe wie
1
   LCD_PORT_4 &= ~(1<<LCD_D4);
2
   LCD_PORT_5 &= ~(1<<LCD_D5);
3
   LCD_PORT_6 &= ~(1<<LCD_D6);
4
   LCD_PORT_7 &= ~(1<<LCD_D7);            // maskieren
5
6
   if(temp1 & 0x01) LCD_PORT_4 |=(1<<LCD_D4) ;// setzen
7
   if(temp1 & 0x02) LCD_PORT_5 |=(1<<LCD_D5) ;
8
   if(temp1 & 0x04) LCD_PORT_6 |=(1<<LCD_D6) ;
9
   if(temp1 & 0x08) LCD_PORT_7 |=(1<<LCD_D7) ;
ist.

Aber bring' erst mal die Initilisierung in Ordnung (indem Du 3 statt 2 
reinschreibst, wird auf 8 Bit statt 4 Bit gestellt).

von Hc Z. (mizch)


Lesenswert?

Dirk A. schrieb:
> während der ersten 2 E-Pulse falsche Daten
>         gesendet (0x3 statt 0x2).

Dieser Teil:
1
   LCD_PORT_4 |=  (1<<LCD_D4);
2
   LCD_PORT_5 |=  (1<<LCD_D5);
3
   LCD_PORT_6 &= ~(1<<LCD_D6);
4
   LCD_PORT_7 &= ~(1<<LCD_D7);
5
6
   LCD_RS_PORT &= ~(1<<LCD_RS);      // RS auf 0
7
   lcd_enable();
8
9
   _delay_ms(5);
10
   lcd_enable();
der Initialisierung legt die Zahl 3 an Deinen 4-Bit-Bus und toggelt dann 
zweimal Enable.  Damit stellst Du jeden 44780-kompatiblen Controller auf 
8-Bit-Daten, hast aber nur 4.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

also, danke fürs erklären, aber, hoffe habs nicht falsch verstanden, ich 
möchte das LCD im 4 bit modus betreiben, und die libary is wie 
geschrieben aus dem netz, außerdem is die so angelegt das ich die 
benutzten ports ganz einfach ändern kann, deshalb wird denke ich jedes 
bit einzeln maskiert!

so, und jetzt du, liege ich falsch? ich hoffe nicht, sonst sind meine 
c-probleme größer als ich dachte...

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

also muss ich diese zeile ändern?

LCD_PORT_4 |=  (1<<LCD_D4);
in
LCD_PORT_4 &= ~(1<<LCD_D6);

ist das richtig?

von Codeleser (Gast)


Lesenswert?

LCD_PORT_4 |=  (1<<LCD_D4);
LCD_PORT_5 |=  (1<<LCD_D5);
LCD_PORT_6 &= ~(1<<LCD_D6);
LCD_PORT_7 &= ~(1<<LCD_D7);

ergibt 0011 d.h. 3

von Hc Z. (mizch)


Lesenswert?

Nein, Du liegst nicht falsch.  Wenn benachbarte Bits des LCD-Datenbusses 
nicht auf benachbarten Pins eines Ports liegen, ergibt die Bitklopferei 
Sinn.  Wenn's im Layout wirklich sehr knapp zugeht, kann das mal ganz 
ausnahmsweise sogar angehen.

Das mit dem 4-Bit-Modus habe ich schon verstanden.  Dein Problem ist: 
Du initialisierst auf 8 Bit (besagte und von mir oben zitierte 3).

von Hc Z. (mizch)


Lesenswert?

Dirk A. schrieb:
> LCD_PORT_4 |=  (1<<LCD_D4);
> in
> LCD_PORT_4 &= ~(1<<LCD_D6);
>
> ist das richtig?

Ja.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

wahnsinn, da funtioniert was! ich dank dir dafür vielmals, schön das die 
lib als 4-bit modus beschrieben ist...
so, muss dann nur noch testen ob ich alle 4 zeilen angesprochen bekomme, 
und meine ursprünglichen ports auch funktionieren.
vielen dank nochmals für die gute und schnelle hilfe

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

so, langsam ist es zum verzweifeln, habe etwas rumprobiert, nichts hat 
funktioniert, und bin nun zum ausgangspunkt zurückgekehrt, und es 
funktioniert trotzdem nix, vorhin gings aber noch, hab in der bibliothek 
nichts weiter geändert, nur den code, wo is der fehler?

#define F_CPU 4000000
#include  <avr\io.h>
#include  <util\delay.h>
#include  <lcd-neu.h>


// Programm

int main (void)
{
  _delay_ms(200);
  lcd_init();
  _delay_ms(200);
  while(1)
  {
    lcd_string("HALLO");
    _delay_ms(200);
  }
}

von Karl H. (kbuchegg)


Lesenswert?

Dirk A. schrieb:
> so, langsam ist es zum verzweifeln, habe etwas rumprobiert, nichts hat
> funktioniert, und bin nun zum ausgangspunkt zurückgekehrt, und es
> funktioniert trotzdem nix, vorhin gings aber noch, hab in der bibliothek
> nichts weiter geändert, nur den code, wo is der fehler?

Wahrschinlich immer noch in der lcd-init Funktion

Noch ein Hinweis: 'funktioniert nix' ist so ziemlich die nichtssagende 
Fehlermeldung, die man sich vorstellen kann.

Bei einem LCD ist interessant:
Sind in der 1ten bzw. 3ten Zeile schwarze Balken?
  Wenn ja, dann ist die Initialisierung fehlerhaft.

Verschwinden die Balken, dann klappt zumindest mal höchst wahrscheinlich 
die Initialisierung.

D.h. aber auch. Wenn du Probleme mit einem LCD hast, dann gib zumindest 
an, ob du die Balken noch siehst oder nicht. Das gibt den Helfern einen 
Anhaltspunkt, in welche Richtung gesucht werden muss.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

also, das lcd zuckt nicht nach dem einschalten, auch nicht nach einer 
gewissen zeit!
die erste und dritte zeile sehen gleich aus, und unterscheiden sich nur 
ganz gering, also kaum wahrnehmbar von zeile 2 und 4. schwarze balken 
sind für mich zu keinem zeitpunkt deutlich sichtbar, wenn man ganz genau 
hinschaut erkannt man unterschiedliche helligkeiten. und mit der 
Initialisierung, es funktionierte ja, und dann funkt es mit dem gleichen 
code aufeinmal nicht mehr... warum?

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

ich hab das programm mal debuggt, und der debugger bleibt in dieser 
zeile hängen:
   LCD_EN1_PORT &= ~(1<<LCD_EN1);
ich versteh leider nicht was in dieser Zeile passieren soll.
Hier noch der komplette code in dem die Zeile steckt, er wird in der 
lcd-init aufgerufen!

void lcd_enable(void)
{
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
einfügen

   // Beitrag "Re: Bitte helft mir. Schon wieder AtMega16"
   LCD_EN1_PORT |= (1<<LCD_EN1);


    _delay_us(1);                   // kurze Pause
   // Bei Problemen ggf. Pause gemäß Datenblatt des LCD Controllers 
verlängern
   // Beitrag "LCD -> Probleme mit Optimierungsgrad"
   LCD_EN1_PORT &= ~(1<<LCD_EN1);



}

von Karl H. (kbuchegg)


Lesenswert?

Dirk A. schrieb:
> also, das lcd zuckt nicht nach dem einschalten, auch nicht nach einer
> gewissen zeit!
> die erste und dritte zeile sehen gleich aus, und unterscheiden sich nur
> ganz gering, also kaum wahrnehmbar von zeile 2 und 4. schwarze balken
> sind für mich zu keinem zeitpunkt deutlich sichtbar, wenn man ganz genau
> hinschaut erkannt man unterschiedliche helligkeiten. und mit der
> Initialisierung, es funktionierte ja, und dann funkt es mit dem gleichen
> code aufeinmal nicht mehr... warum?

Die Beschreibung ist für mich nicht wirklich klar.
Was ist, wenn du das LCD ohne µC einschaltest. Dann müssen die Balken 
klar und deutlich sichtbar sein (damit du einen Anhaltspunkt hast, wie 
das aussehen muss). Der 2te Teil deiner Beschreibung lässt in mir den 
verdacht aufkommen, dass deine Kontrasteinstellung nicht stimmt. Das 
kann man ganz gut kontrollieren, wenn man das LCD alleine einschaltet.

von Karl H. (kbuchegg)


Lesenswert?

Dirk A. schrieb:
> ich hab das programm mal debuggt, und der debugger bleibt in dieser
> zeile hängen:
>    LCD_EN1_PORT &= ~(1<<LCD_EN1);
> ich versteh leider nicht was in dieser Zeile passieren soll.

Das ist jetzt aber nicht dein Ernst.
Wenn du dich selber an einem LCD Treiber Code versuchst, dann darf das 
keine Schwierigkeiten machen. Das ist eine Standardversion von: Das Bit 
LCD_EN1 am Port LCD_EN1_PORT auf 0 setzen. So was musst du auf Anhieb 
erkennen, wenn du kopfüber von einem Baum hängst, mit Honig 
eingeschmiert und Ameisen auf dir krabbeln. Ein Blick muss genügen.

> void lcd_enable(void)
> {
>    LCD_EN1_PORT |= (1<<LCD_EN1);

Bit auf 1

>     _delay_us(1);                   // kurze Pause

Bischen warten

>    LCD_EN1_PORT &= ~(1<<LCD_EN1);

und Bit wieder auf 0

In Summe wird ein 1-Puls mit einer Länge von 1µs erzeugt.

von Dirk A. (Firma: student) (spike_ipp)


Lesenswert?

also, hab den kontrast jetzt so, das anfangs schwarze balken sind. die 
gehen aber nicht weg, wenn ich manuel den µC nochmal resete 
funktionierts...manchmal! das ist für mich nicht durchschaubar. klingt 
für mich, als ob bei der initialisierung manchmal was schief geht!

habt ihr dazu nochmal eine idee??

von Karl H. (kbuchegg)


Lesenswert?

am Anfang des Programms eine kleine Wartezeit einlegen. Gib dem µC auf 
dem LCD Zeit, sein eigenes Programm hochzufahren ehe du ihn das erste 
mal ansprichst.

von Max (Gast)


Lesenswert?

Display an PORTC des ATMega32 und JTAG per Fuse enabled?

von Dirk A. (Gast)


Lesenswert?

ich habs auch schon mit ner warteroutine versucht:

for(x=0;x<50;x++)
{
_delay_ms(16);
}

problem ist trotzdem das gleiche!

von Dirk A. (Gast)


Lesenswert?

Display ist im Moment an PORTD, soll später mal an PORTC, aber erst 
wenns hier richtig funktioniert

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.