Forum: Mikrocontroller und Digitale Elektronik LCD funktioniert nicht


von astroscout (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe die Schaltung in Anhang aufgebaut.
Leider bekomme ich das LCD 
(http://www.electronic-software-shop.com/product_info.php?pName=lcd-modul-4x20-zeichen-beleuchtet-blau-p-46) 
nicht ans laufen.
Das Display zeigt immer nur die zwei weißen Balken an, sonst passiert 
garnichts.

Habt Ihr eine Idee woran das liegen könnte.
Ich habe auch schon diverse Bibliotheken verwendet, allerdings leider 
ohne Erfolg.



Hier mal mein Code:
1
/*Initialisiert das LCD*/
2
void init_lcd(void){
3
    
4
    
5
    
6
    /*Interface auf 8-Bit setzen*/
7
    PORTA = 0x0C;
8
    _delay_ms(100);
9
    lcd_enable();
10
    
11
    /*Interface auf 8-Bit setzen*/
12
    PORTA = 0x0C;
13
    _delay_ms(100);
14
    lcd_enable();
15
    
16
    /*Interface auf 8-Bit setzen*/
17
    PORTA = 0x0C;
18
    _delay_ms(100);
19
    lcd_enable();
20
    
21
    
22
    /*Zeilen (4) und Matrix (5x7) setzen*/
23
    _delay_ms(100);
24
    PORTA = 0x14;
25
    lcd_enable();
26
    
27
    /*Display löschen*/
28
    _delay_ms(100);
29
    PORTA = 0x80;
30
    lcd_enable();
31
    
32
    
33
    
34
35
36
}
37
38
39
/*Erzeugt einen Enable-Puls*/
40
static void lcd_enable(void)
41
{
42
    PORTC |= (1<<PC7);         // Enable auf 1 setzen
43
    _delay_us(100);                  // kurze Pause
44
    PORTC &= ~(1<<PC7);        // Enable auf 0 setzen
45
    _delay_ms(100);
46
}


Im Vorraus vielen Dank für Eure Hilfe!

von Karl H. (kbuchegg)


Lesenswert?

astroscout schrieb:

> ich habe die Schaltung in Anhang aufgebaut.

Welcher Teufel hat dich bloss geritten, die Datenleitungen 
spiegelsymetrisch anzuschliessen?

Natürlich kann man das in Software wieder ausbügeln. Aber sowas macht 
man nicht, wenn es nicht ansolut sein muss.

> Ich habe auch schon diverse Bibliotheken verwendet, allerdings leider
> ohne Erfolg.

Die Fleury Lib kann man so konfigurieren, dass man auch die 
Datenleitungen beliebig umverteilen kann.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

>> # HD44780 kompatibel
>> http://www.abacom-online.de/div/LCD20x4.pdf

> Das Display zeigt immer nur die zwei weißen Balken an, sonst passiert
> garnichts.

Welche Funktion hat R3?

>    /*Interface auf 8-Bit setzen*/
>    PORTA = 0x0C;

Wie stellst du DDRA ein?
Wie stellst du PC6 (=> R/W) ein?

> Hintergrundbeleuchtung

Bist du sicher, dass du keine Strombegrenzung einbauen musst?

von Karl H. (kbuchegg)


Lesenswert?

astroscout schrieb:

> Habt Ihr eine Idee woran das liegen könnte.

    /*Interface auf 8-Bit setzen*/
    PORTA = 0x0C;

Wenn du das unbedingt selbst schreiben mußt, dann schreib dir als erstes 
eine Funktion, die dir das Bitspiegeln bei der Ausgabe übernimmt. 
Ansonsten wirst du ständig durcheinander kommen und dir durch 
manuelles/gedankliches Umstellen mehr Fehler reinhauen als dir lieb 
sind. Und spätestens bei der Zeichenausgabe brauchst du die Funktion 
sowieso.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> Hintergrundbeleuchtung

BC547 und 240 mA max. - Das passt IMHO nicht.

von astroscout (Gast)


Lesenswert?

Danke für Eure schnellen Antworten.

R3 ist für die Kontrastspannung, das macht aber keine Probleme.
Die Hintergrundbeeuchtung funktioniert auch ohne Probleme.

Karl heinz Buchegger schrieb:

>>
> Welcher Teufel hat dich bloss geritten, die Datenleitungen
> spiegelsymetrisch anzuschliessen?

Das war vom Platinenlayout nur schwierig anders möglichlich.


Hier mal meine Prozedur um die Ports zu initialisieren:
1
/*Initialisiert die I/O-Ports*/
2
void init_io_ports(void){
3
4
    /*Port A*/
5
    DDRA = 0xff;                 //Ausgang: Datenport für LCD
6
    PORTA = 0x00;
7
    
8
    
9
    /*Port B*/
10
    DDRB &= ~(1 << DDB1);         //Eingang: USB-Meldung
11
    DDRB &= ~(1 << DDB2);         //Eingang: on/off-Schalter
12
    DDRB |=  (1 << DDB3);         //Ausgang: LCD-Helligkeit (PWM)
13
    DDRB |=  (1 << DDB4);         //Ausgang: Power Control
14
    PORTB = 0x00;
15
    PORTB |= (1 << PB2);         //Pull-Up-Widerstand für on/off-Schalter aktivieren
16
    
17
    
18
    
19
    /*Port C*/
20
    DDRC |=  (1 << DDC2);         //Ausgang: Matrix (nicht verwendet)
21
    DDRC |=  (1 << DDC3);         //Ausgang: Power-Switch Extern 1 (Subwoofer)
22
    DDRC |=  (1 << DDC4);         //Ausgang: Power-Switch Extern 2 (Verstärker)
23
    DDRC |=  (1 << DDC5);         //Ausgang: LCD (RS)
24
    DDRC |=  (1 << DDC6);         //Ausgang: LCD (R/W)
25
    DDRC |=  (1 << DDC7);         //Ausgang: LCD (E)
26
    DDRC = 0xff;
27
    PORTC = 0x00;
28
    
29
    
30
    /*Port D*/
31
    DDRD &= ~(1 << DDD0);         //Eingang: Taster "back"
32
    DDRD &= ~(1 << DDD1);         //Eingang: Taster "up"
33
    DDRD &= ~(1 << DDD2);         //Eingang: Taster "down"
34
    DDRD &= ~(1 << DDD3);         //Eingang: Taster "okay"
35
    DDRD |=  (1 << DDD4);         //Ausgang: Power-Switch 4 (AMPs)
36
    DDRD |=  (1 << DDD5);         //Ausgang: Power-Switch 3 (Mischpult)
37
    DDRD |=  (1 << DDD6);         //Ausgang: Power-Switch 2 (MP3)
38
    DDRD |=  (1 << DDD7);         //Ausgang: Power-Switch 1 (HDD)
39
    PORTD = 0x00;

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Sorry wenn ich dich mit dauerndem Nachfragen nerve. Mit einem 
vollständigen Minimalprogramm im Anhang, wäre es einfacher... Sei es 
drum

Und, wird im Programm init_io_ports() vor init_lcd() aufgerufen?

Wieviel Zeit gibst du dem LCD bis nach dem Power-Up der Schaltung die 
Funktion init_lcd() aufgerufen wird?

Stimmen deine Delays, ist F_CPU im Programm so definiert, wie am AVR per 
AVR Fuses eingestellt? Delays ausgetestet?

> R3 ist für die Kontrastspannung, das macht aber keine Probleme.

Wenn dieses R3 verändert wird - verschwinden dann die weissen Balken?

Gibst du im Programm Zeichen aus? Wie? Erscheinen diese (oder wilde) 
Zeichen, wenn du an R3 so gedreht hast, dass die weissen Balken gerade 
verschwunden sind?

KH:
> Wenn du das unbedingt selbst schreiben mußt, dann schreib dir als erstes
> eine Funktion, die dir das Bitspiegeln bei der Ausgabe übernimmt.

Hast du das schon gemacht? Mit dieser Funktion könnte man direkt die 
Bitangaben aus dem Datenblatt im Quellcode verwenden und bräuchte nicht 
nachzusehen, ob deine Angaben z.B. /*Zeilen (4) und Matrix (5x7) 
setzen*/ => PORTA = 0x14; korrekt sind.

von Karl H. (kbuchegg)


Lesenswert?

Stefan B. schrieb:

> Hast du das schon gemacht? Mit dieser Funktion könnte man direkt die
> Bitangaben aus dem Datenblatt im Quellcode verwenden und bräuchte nicht
> nachzusehen, ob deine Angaben z.B. /*Zeilen (4) und Matrix (5x7)
> setzen*/ => PORTA = 0x14; korrekt sind.

@TO
Nachsehen müsste man sicherlich ebenfalls.
Aber man muss dann keinen gedanklichen Spaghat mehr machen bzw. sich 
jede einzelne Ausgabe bitweise aufschreiben und neu in umgekehrter 
Reihenfolge zusammensetzen.
Das sind nämlich so klassische Falltüren und daher auch: Das Umdrehen 
soll eine Funktion machen. Als Programmierer will ich mich nicht darum 
kümmern, dass die Bits am Port anders angeordnet sind. Ich will

   output_lcd_data( 0x30 );

aufrufen und an den Pins vom LCD liegt dann auch 0x30 an, egal über 
welche Portpins das läuft. Das ist Sache dieser Funktion das wieder 
hinzubiegen.

von astroscout (Gast)


Lesenswert?

@Stefan:

Hier noch den Rest des Programms:
1
/*--------------Includes--------------*/
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include "lcd.c"
6
7
8
 
9
 
10
 /*-----------Deklarationen-----------*/
11
12
 #define TAKT 8000000UL            //8MHz Controllertakt
13
14
15
 
16
 
17
 
18
 
19
 /*------------Funktionen------------*/
20
 
21
 void init_io_ports(void);        //Initialisiert die I/O-Ports
22
 void init_lcd(void);            //Initialisiert das LCD
23
 int reverseBits(int input);
24
 
25
 
26
 
27
 
28
/*-----------Main-Funktion-----------*/
29
int main (void) { 
30
    init_io_ports();
31
    PORTB |= (1<<PB4);    //Netzteil an
32
    PORTB |= (1<<PB3);    //Licht LCD an
33
    
34
    
35
    _delay_ms(1000);
36
    init_lcd();
37
    PORTB &= ~(1<<PB3);    //Licht LCD aus
38
    _delay_ms(100);
39
    PORTB |= (1<<PB3);    //Licht LCD an
40
41
    
42
    while(1) {};    
43
    
44
}

Mein Delays sind komischerweise etwaslänger, zumindestens kommt es mir 
so vor. ich werde mich darum auch noch kümmern, aber selbst mit längeren 
Delays müsste es doch klappen.

Zeichen gebe ich noch keine aus, ich will ja erstmal das LCD löschen, 
also diese beiden weißen Balken verschwinden lassen.

Der Kontrast lässt sich mit R3 ohne Probleme regeln.

zu der Reverse-Funktione: Ja ich muss mir diese noch schreiben, wollte 
eber erstmal gucken, dass ich das LCD initialisiert bekommen.

Nochmal danke für Eure schnelle Hilfe

von Axel Rühl (Gast)


Lesenswert?

Offensichtlich hat astroscout aber genau mit der Erstellung einer 
solchen Bit-Umdreh-Funktion Probleme, wie es aussieht...

von Axel Rühl (Gast)


Lesenswert?

ups - überschnitten, sorry

von astroscout (Gast)


Lesenswert?

ich jetzt mal auf der Platine gemessen ob alle Leitungen okay sind und 
dabei festgestellt, dass der Mikrokontroller die RS-Leitung nicht auf 
Low ziehen kann. DIe Verbindung hier ist jedoch einwandfrei.
Habt Ihr eine Erklärung dafür?

Danke!

von spess53 (Gast)


Lesenswert?

Hi

>Habt Ihr eine Erklärung dafür?

Ja. JTAG abschalten.

MfG Spess

von astroscout (Gast)


Lesenswert?

Danke für deine Antwort, ich werde das dann die Tage mal ausprobieren 
mit dem JTAG abschalten.

von astroscout (Gast)


Lesenswert?

so, ich hab den JATG jetzt mal abgeschaltet, scheint das problem gewesen 
zu sein.
Das Display wird jetzt auf jeden fall richtig gelöscht :-)

von Michael R. (mexman) Benutzerseite


Lesenswert?

> ich jetzt mal auf der Platine gemessen ob alle Leitungen okay sind und
> dabei festgestellt, dass der Mikrokontroller die RS-Leitung nicht auf
> Low ziehen kann.


WOW!
Dieses Statement sollten wir hier einrahmen und allen 37.492 
Fragestellern schicken, die Ihre LCDs nicht initialisiert bekommen:

Messen, messen, messen.
Statt uC Emulator anschliessen und im Single-Step Betrieb die Pegel 
direkt am LCD messen.


Gruss


Michael

von spess53 (Gast)


Lesenswert?

Hi

>Statt uC Emulator anschliessen und im Single-Step Betrieb die Pegel
>direkt am LCD messen.

Klar. Das hat ja auch jeder zu Hause. Aber bei neuen Mietverträgen kann 
man darauf bestehen. Gehört ja zu Grundausstattung einer Wohnung.

MfG Spess

von astroscout (Gast)


Lesenswert?

so, mein LCD funktioniert jetzt einwandfrei!

Nochmal Danke für eure Hilfe!!

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.