PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : LCD tut einfach nicht



clerian
24.07.2005, 13:55
Hallo, das is mein erster Post in diesem Forum, ich such schon seit ungefähr einer Woche nach einer Lösung für mein Problem:

ich hab einen Attiny26 Controler an den ein 1 Zeiliges LCD mit 16 Zeichen angeschlossen is, wenn ich nun einschalte seh ich, dass die ersten 8 Zeichen als schwarzer Balken zu sehn sind, die 2ten 8 allerdings nicht.

Irgendwas muss ich bei der Initialisierung flasch machen... ich finds aber nicht :/

meine Pinbelegung ist so: PA0-3 sind die Datenleitungen, PA3 is RS und PA5 is Enable R/W liegt auf GND

Ich versuch das LCD so zu initialisieren:


// Port A Pins 0-5 auf Ausgang setzen
DDRA |= ((1<<DDA0)|(1<<DDA1)|(1<<DDA2)|(1<<DDA3)|(1<<DDA4)|(1<<DDA5));

PORTA &= ~((1<<PA0)|(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5));
_delay_ms(15);
for(uint8_t i=1; i<=3; ++i)
{
PORTA |= ((1<<PA0)|(1<<PB1)); // 3 mal 0011 mit 5 ms Pause
lcd_en();
_delay_ms(5);
}

PORTA &= ~(1<<PA0); // 0010 = 4-Bit Modus
lcd_en();

lcd_write(0x28, "");
lcd_write(0x0c, "");
lcd_write(CLEAR, "");
_delay_ms(2);
lcd_write(0x06, "");

lcd_write(0, " BEREIT ");


lcd_write sieht so aus:


void lcd_write(uint8_t com, char string[17])
{
if (com != 0)
{
uint8_t high_nibble = com>>4;
uint8_t low_nibble = com<<4;
low_nibble = low_nibble>>4;

PORTA = high_nibble;
lcd_en();
PORTA = low_nibble;
lcd_en();

_delay_ms(2);
}

else
{
for (int8_t i = 0; i < 16; i++)
{
PORTA |= (1<<PA4); // RS - Bit setzen

uint8_t high_nibble = (uint8_t)string[i]>>4;
uint8_t low_nibble = (uint8_t)string[i]<<4;
low_nibble = low_nibble>>4;

PORTA = high_nibble;
lcd_en();
PORTA = low_nibble;
lcd_en();
_delay_us(50);

PORTA &= ~(1<<PA4); // RS - Bit löschen
}
}
}


und lcd_en so:


_delay_us(1);

PORTA |= (1<<PA5);
asm volatile("nop\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
::);
PORTA &= ~(1<<PA5);


hoffentlich weiß jemand was da nicht stimmt....

mfg Clerian

fwallenwein
25.07.2005, 17:05
Hallo,
ich habe eben mal über Deinen Code geschaut.
Beim drüberfliegen sind mir ein paar Ding aufgefallen.
Das ist mit Sicherheit nicht alles, aber es könnte Dir schon mal weiterfelfen.

- Initialisierung
PORTA |= ((1<<PA0)|(1<<[highlight=red:088a855f56]PB1[/highlight:088a855f56])); // 3 mal 0011 mit 5 ms Pause

wieso PB und nicht PA ( sollte nichts ausmachen - war aber sicher so nicht gemeint.)

- Dein lcd_write
void lcd_write(uint8_t com, char string[17])

Hier solltest Du einen char pointer übergeben und auf Ende des Strings abprüfen.
void lcd_write(uint8_t com, char *string)

So wie Du es jetzt gemacht hast wir das Programm immer die vollen 17 Zeichen rausschreiben. Wenn Du also nur "Hallo" scheiben willst, dann schreibt er "Halloasfaaaaaafa" oder was halt auch immer zufällig im Speicher hinter Deinen String liegen sollte auf das Display.

Statt for (int8_t i = 0; i < 16; i++)
lieber [highlight=red:088a855f56]while (*string != 0x0 )[/highlight:088a855f56]
{
PORTA |= (1<<PA4); // RS - Bit setzen

uint8_t high_nibble = (uint8_t)([highlight=red:088a855f56]*string[/highlight:088a855f56]>>4);
uint8_t low_nibble = (uint8_t)(*string<<4);
low_nibble = low_nibble>>4;

PORTA = high_nibble;
lcd_en();
PORTA = low_nibble;
lcd_en();
_delay_us(50);

PORTA &= ~(1<<PA4); // RS - Bit löschen
[highlight=red:088a855f56]string++;[/highlight:088a855f56]
}

In der Zeile PORTA = high_nibble; oder PORTA = low_nibble;
ueberschreibst Du den ganzen Port A - alle 8 Bit. Auf den anderen 4 Bit liegen aber doch Deine Steuerleitungen - oder ?

Wie wäre es mit was in der Richtung ?
PORTA = ( (PORTA & 0xF0) | ( high_nibble & 0x0F) )

....
Nur meine Ideen
Gruss
Frank