-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-
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-