keine Ausgabe am LCD mit ATmega32

OP (Firma: student) #1677595
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);
  }

}
OP (Firma: student) #1677600
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();
}
Gast #1677601
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.
#1677613
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.
OP (Firma: student) #1677617
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);
}
#1677623
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).
#1677624
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.
OP (Firma: student) #1677625
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...
#1677631
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).
OP (Firma: student) #1677633
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
OP (Firma: student) #1677675
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);
  }
}
#1677939
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.
OP (Firma: student) #1678260
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?
OP (Firma: student) #1678295
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);



}
#1678406
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.
#1678410
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.
OP (Firma: student) #1678567
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??

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