Problem mit LCD 4 Bit Initalisierung

OP #1749493
Lesenswert?

Hallo
ich habe folgendes Problem. Die 4 Bit Initalisierung funktioniert mit 
einem Atmega 32 problemlos. Auf einem Atmega 8 werden nur undefinierte 
Zeichen ausgegeben.

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

void delay_ms(unsigned int anz_milisekunden);
void delay_100us(unsigned int anz);
void init_ports(void);
void lcd_init_4bit(void);
void lcd_write_data(unsigned char data);
void lcd_write_command(unsigned char command);
void lcd_enable(void);

void lcd_write_text(char * textstring);


//////////////////////////////////////////////////////////////////////// 
/////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void init_ports(void)
{
DDRC=DDRC | 0b00001111;  //Ausgabe
DDRB=0b11111111;  //Bits 5,4 und 3 auf Ausgabe

PORTC=0x00;
PORTB=0x00;
}


//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_enable(void)
{
int p;
PORTB = PORTB | 0b00000001;
delay_ms(6);
PORTB = PORTB & 0b11111110;
delay_ms(6);
return;
}



//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_write_data(unsigned char data)
{
int p;
unsigned char nibble_h, nibble_l;

PORTB = PORTB & 0b11111101; //  R/W auf 0 für Write
PORTB = PORTB | 0b00000100; //  RS  auf 1 für Datenregister

nibble_h =   (data >> 4)  & 0b00001111;
nibble_l =   data & 0b00001111;


PORTC = nibble_h;
lcd_enable();
delay_ms(6);

PORTC = nibble_l;
lcd_enable();

delay_ms(6);        // Viel Sicherheit: Manche brauchen 40 us, andere 
1,6ms

}



//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_write_command(unsigned char command)
{
int p;
unsigned char nibble_h, nibble_l;


PORTB = PORTB & 0b11111101; // R/W auf 0 für Write
PORTB = PORTB & 0b11111011; // RS  auf 0 für Befehlsregister

nibble_h =   (command >> 4) & 0b00001111;
nibble_l =    command   & 0b00001111;


PORTC = nibble_h;
lcd_enable();
delay_ms(6);

PORTC = nibble_l;
lcd_enable();

delay_ms(6);        // Viel Sicherheit: Manche brauchen 40 us, andere 
1,6ms

}


//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_write_command8(unsigned char command)
{
PORTB = PORTB & 0b11111101; // R/W auf 0 für Write
PORTB = PORTB & 0b11111011; // RS  auf 0 für Befehlsregister
PORTC = command;
lcd_enable();
delay_ms(6);        // Viel Sicherheit: Manche brauchen 40 us, andere 
1,6ms

}





//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_init_4bit(void)
{
delay_ms(20);
lcd_write_command8(0b00110000); //Reset
delay_ms(8);
lcd_write_command8(0b00110000); //s.o.
lcd_write_command8(0b00110000); //s.o.

lcd_write_command8(0b00101000); //Auf 4-Bit-Interface !

//Ab hier mit der 4-Bit-Routine Schreiben!!!

lcd_write_command(0b00101000); //4-Bit-Interface, 2-zeilig, 5*7-Font

lcd_write_command(0b00001100); //Display ein, Cursor aus, blinken aus

lcd_write_command(0b00000001); //Display löschen, Cursor auf 
Home-Position

lcd_write_command(0b00000110); //Cursor Auto-Increment
}




//////////////////////////////////////////////////////////////////////// 
////////////////////
//////////////////////////////////////////////////////////////////////// 
/////////////////////
void lcd_write_text(char * textstring)
{
int i;

for (i=0; (textstring[i] != 0) && (i<8) ; i=i+1)
    {
  lcd_write_data(textstring[i]);
  }
}
Angehängte Dateien:
OP #1749504
Lesenswert?

Moin
hier die delay

#include <avr/io.h>

void delay_ms(unsigned int anz_milisekunden)
{
unsigned int i,k,l;

for(i=0;i<anz_milisekunden; i=i+1)
  {
  for(k=0;k<39; k=k+1)
    {
    l=0xff; //Irgendeine sinnlose Anweisung zur Zeitverschwendung
    }
    l=l+1;    //s.o.
  l=11;    //s.o.
  }

}



void delay_100us(unsigned int anz)
{
unsigned int i,l;

l=l+1;    //sinnlos
l=l+1;    //sinnlos
l=l+1;    //sinnlos
l=l+1;    //sinnlos
for(i=1;i<anz; i=i+1)
  {
    l=l+1;    //sinnlos
  l=l+1;    //sinnlos
  l=l+1;    //sinnlos
  l=l+1;    //sinnlos
  l=l+1;    //sinnlos
  l=l+1;    //sinnlos
  }

}
Angehängte Dateien:
#1749661
Lesenswert?

Auch die Takteinstellung noch einmal überprüfen.

Aber als erstes: wirf deine eigenen delay Funktionen raus und ersetze 
sie mit _delay_ms() aus delay.h

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

Je nach Compiler Einstellung werden die nämlich wegoptimiert (und AVR 
Studio hat per Default den Optimizer eingeschaltet. Für delay.h ist das 
gut, für deinen Code aber schlecht)

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