www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LCD funktioniert nicht


Autor: astroscout (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe die Schaltung in Anhang aufgebaut.
Leider bekomme ich das LCD 
(http://www.electronic-software-shop.com/product_in...) 
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:
/*Initialisiert das LCD*/
void init_lcd(void){
    
    
    
    /*Interface auf 8-Bit setzen*/
    PORTA = 0x0C;
    _delay_ms(100);
    lcd_enable();
    
    /*Interface auf 8-Bit setzen*/
    PORTA = 0x0C;
    _delay_ms(100);
    lcd_enable();
    
    /*Interface auf 8-Bit setzen*/
    PORTA = 0x0C;
    _delay_ms(100);
    lcd_enable();
    
    
    /*Zeilen (4) und Matrix (5x7) setzen*/
    _delay_ms(100);
    PORTA = 0x14;
    lcd_enable();
    
    /*Display löschen*/
    _delay_ms(100);
    PORTA = 0x80;
    lcd_enable();
    
    
    


}


/*Erzeugt einen Enable-Puls*/
static void lcd_enable(void)
{
    PORTC |= (1<<PC7);         // Enable auf 1 setzen
    _delay_us(100);                  // kurze Pause
    PORTC &= ~(1<<PC7);        // Enable auf 0 setzen
    _delay_ms(100);
}


Im Vorraus vielen Dank für Eure Hilfe!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hintergrundbeleuchtung

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

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
/*Initialisiert die I/O-Ports*/
void init_io_ports(void){

    /*Port A*/
    DDRA = 0xff;                 //Ausgang: Datenport für LCD
    PORTA = 0x00;
    
    
    /*Port B*/
    DDRB &= ~(1 << DDB1);         //Eingang: USB-Meldung
    DDRB &= ~(1 << DDB2);         //Eingang: on/off-Schalter
    DDRB |=  (1 << DDB3);         //Ausgang: LCD-Helligkeit (PWM)
    DDRB |=  (1 << DDB4);         //Ausgang: Power Control
    PORTB = 0x00;
    PORTB |= (1 << PB2);         //Pull-Up-Widerstand für on/off-Schalter aktivieren
    
    
    
    /*Port C*/
    DDRC |=  (1 << DDC2);         //Ausgang: Matrix (nicht verwendet)
    DDRC |=  (1 << DDC3);         //Ausgang: Power-Switch Extern 1 (Subwoofer)
    DDRC |=  (1 << DDC4);         //Ausgang: Power-Switch Extern 2 (Verstärker)
    DDRC |=  (1 << DDC5);         //Ausgang: LCD (RS)
    DDRC |=  (1 << DDC6);         //Ausgang: LCD (R/W)
    DDRC |=  (1 << DDC7);         //Ausgang: LCD (E)
    DDRC = 0xff;
    PORTC = 0x00;
    
    
    /*Port D*/
    DDRD &= ~(1 << DDD0);         //Eingang: Taster "back"
    DDRD &= ~(1 << DDD1);         //Eingang: Taster "up"
    DDRD &= ~(1 << DDD2);         //Eingang: Taster "down"
    DDRD &= ~(1 << DDD3);         //Eingang: Taster "okay"
    DDRD |=  (1 << DDD4);         //Ausgang: Power-Switch 4 (AMPs)
    DDRD |=  (1 << DDD5);         //Ausgang: Power-Switch 3 (Mischpult)
    DDRD |=  (1 << DDD6);         //Ausgang: Power-Switch 2 (MP3)
    DDRD |=  (1 << DDD7);         //Ausgang: Power-Switch 1 (HDD)
    PORTD = 0x00;

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Stefan:

Hier noch den Rest des Programms:
/*--------------Includes--------------*/

#include <avr/io.h>
#include <util/delay.h>
#include "lcd.c"


 
 
 /*-----------Deklarationen-----------*/

 #define TAKT 8000000UL            //8MHz Controllertakt


 
 
 
 
 /*------------Funktionen------------*/
 
 void init_io_ports(void);        //Initialisiert die I/O-Ports
 void init_lcd(void);            //Initialisiert das LCD
 int reverseBits(int input);
 
 
 
 
/*-----------Main-Funktion-----------*/
int main (void) { 
    init_io_ports();
    PORTB |= (1<<PB4);    //Netzteil an
    PORTB |= (1<<PB3);    //Licht LCD an
    
    
    _delay_ms(1000);
    init_lcd();
    PORTB &= ~(1<<PB3);    //Licht LCD aus
    _delay_ms(100);
    PORTB |= (1<<PB3);    //Licht LCD an

    
    while(1) {};    
    
}

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

Autor: Axel Rühl (Gast)
Datum:

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

Autor: Axel Rühl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups - überschnitten, sorry

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Habt Ihr eine Erklärung dafür?

Ja. JTAG abschalten.

MfG Spess

Autor: astroscout (Gast)
Datum:

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

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Michael Roek (mexman) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: astroscout (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so, mein LCD funktioniert jetzt einwandfrei!

Nochmal Danke für eure Hilfe!!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.