PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD: Funzt nur wenn 2*INIT am Anfang?!?



-schumi-
05.09.2010, 15:59
Hallo Community

Folgendes:
Ich hab mir mal ein minimalistisches Programm für den AVR geschrieben um ein 16*2 Zeichen Display anzusteuern. Funktioniert inzwischen auch schon gut (dank Vorlage^^)

Aber eins kommt mir komisch vor: Ich muss am Anfang LCD_INIT 2x Ausführen, sonst gehts nicht.
Komisch, komisch... - Aber warum?? Das würd ich jetz gern von euch wissen :-)

Der Code (Die beiden Zeilen sind mit "Zeile1" und "Zeile2" gekennzeichnet, in main zu finden):

#include <avr/io.h>
#include <avr/delay.h>

/*
Anschlussbelegung:
LCD - AVR
DB4 - PA0
DB5 - PA1
DB6 - PA2
DB7 - PA3
RS - PA4
E - PA6
*/

void LCD_SETBYTE (char data)
{
PORTA = PINA & 0b11110000;
if( data & 1<<0 ) PORTA = PINA | 0b00000001;
if( data & 1<<1 ) PORTA = PINA | 0b00000010;
if( data & 1<<2 ) PORTA = PINA | 0b00000100;
if( data & 1<<3 ) PORTA = PINA | 0b00001000;
}

void LCD_ENABLE (void)
{
PORTA = (PINA | 0b01000000);
_delay_us(1);
PORTA = (PINA & 0b10111111);
}

void LCD_DATA (char command)
{
char command2 = command;
command = (command>>4);
command = (command & 0b00001111);
PORTA = 0b00010000;
LCD_SETBYTE (command);
LCD_ENABLE();
_delay_us(45);

command2 = (command2 & 0b00001111);
PORTA = 0b00010000;
LCD_SETBYTE (command2);
LCD_ENABLE();
_delay_ms(2);
}

void LCD_COMMAND (char command)
{
char command2 = command;
command = (command>>4);
command = (command & 0b00001111);
PORTA = 0b00000000;
LCD_SETBYTE (command);
LCD_ENABLE();
_delay_us(45);

command2 = (command2 & 0b00001111);
PORTA = 0b00000000;
LCD_SETBYTE (command2);
LCD_ENABLE();
_delay_ms(2);
}

void LCD_INIT (void)
{
PORTA = 0b01011111;
PORTA = 0b00001111;
_delay_ms(15);
LCD_SETBYTE (0x30);
LCD_ENABLE();
_delay_ms(5);
LCD_ENABLE();
_delay_us(100);
LCD_ENABLE();
_delay_us(100);
LCD_SETBYTE (0x20);
LCD_ENABLE();
_delay_us(100);
LCD_COMMAND(0x28);
LCD_COMMAND(0x08);
LCD_COMMAND(0x01);
LCD_COMMAND(0x06);
LCD_COMMAND(0x0C);
}

int main(void)
{
DDRA = 0b11111111;
LCD_INIT();
LCD_COMMAND(0b00000001); // Zeile1
LCD_INIT(); // Zeile2
LCD_DATA( 'H' );
LCD_DATA( 'a' );
LCD_DATA( 'l' );
LCD_DATA( 'l' );
LCD_DATA( 'o' );
LCD_DATA( ' ' );
LCD_DATA( 'W' );
LCD_DATA( 'e' );
LCD_DATA( 'l' );
LCD_DATA( 't' );
LCD_DATA( '!' );

while(1)
;

return 0;
}


Hier mal ne Tabelle was passiert (0 = auskommentiert):


Zeile1 | Zeile2 | Auswirkung
-------+--------+------------
0 | 0 | Zeile1: 1. Zelle schwarz Zeile2: leer
0 | 1 | Zeile1: "Hallo Welt!" Zeile2: leer
1 | 0 | Zeile1: 1. Zelle schwarz Zeile2: 11 kryptische Zeichen, danach blinkender Cursor auf "_"
1 | 1 | Zeile1: "Hallo Welt!" Zeile2: leer

Man sieht: Wenn LCD_INIT (Zeile2) nicht auskommentiert ist funktioniets wies soll.

Schon mal danke für Antworten
-schumi-

TobiKa
05.09.2010, 16:17
Ich gehe mal davon aus das es um ein Display mit nem HD447xx Controller geht.

Es ist normal das es mehrfach initialisiert werden muss/sollte, ich würde es sogar dreimal machen (zur Sicherheit).

PICture
05.09.2010, 16:33
Hallo!

@ -schumi-

Wahrscheinlich dauert die interne Initialisierung des Displaycontrollers ziemlich lange, und erst danach könnte das Display von µC initialisiert werden. Ich kenne die AVR's nur gering und C gar nicht, aber bei PIC's gibt es eine Option, dass die CPU erst nach ca. 72 ms nach dem Einschalten mit dem Programm beginnt. Deshalb hatte ich bisher keine Probleme mit Initialisierung eines Diaplays.

Versuche, bitte, das Starten des Programms zu verzögern, es sollte helfen ... :)

MfG

-schumi-
05.09.2010, 16:35
Ah, so ist das. (War nur verwirrt, weil es bei meinem Abguck-Beispiel mit 1 mal immer problemlos ging)
Den Controller hast du richig erraten :-)

Vielen dank für die Hilfe!
-schumi-

[EDIT]
@PICture
Sorry, hatte deine Antwort erst nach dem Absenden meiner Antwort gelesen.
Ich hab mal als ersten Befehl in der main "_delay_ms(80);" gesetzt. Hilft leider nicht...
Aber danke für die Info :)