fugitivus
07.04.2011, 10:41
Hi !
Ich versuche schon seit einigen Tagen ein Display mit HD44780, in 4-bit Betrieb anzusteuern....
Ich habe mich so ein bisschen an folgende Anleitung gehalten:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
Ich habe auch definitiev nicht alles falsch gemacht, da die Command befehle wie z.B Cursor setzen aktivieren / deaktivieren und auch das initialisieren in den 4-bit modus zu funktionieren scheint.....
Was ich jezt überhaupt nicht verstehe, ist wie ich ein ascii zeichen sende....
So wie ich das verstanden habe, ist es auch ein byte (high/low-nibble)übertragen wie bei einem Command... nur das der RS pin in diesem fall auf HIGH gezogen werden muss...
Achso ich habe bewusst auf RW verzichtet.... mache ich vlt einen timing fehler ?
Also ganz konkret: wie sende ich ein z.B 'a' an die aktuelle Cursor Position ?
Hier erst mal der code:
lcd.h:
//Frequenz MicroProzessorUnit:
#define MPU_XTAL 8000000
//LCD-IO-Pins (nur 4-bit Betrieb!):
#define LCD_COM_DDR DDRB
#define LCD_COM_PORT PORTB
#define LCD_DATA_DDR DDRB
#define LCD_DATA_PORT PORTB
#define LCD_RS_PORT LCD_COM_PORT
#define LCD_RW_PORT LCD_COM_PORT
#define LCD_E_PORT LCD_COM_PORT
//Command lines(cmd pins müssen nicht auf selbem port liegen):
#define LCD_E_PIN 0
#define LCD_RS_PIN 1
#define LCD_RW_PIN 7
//Data lines(data pins müssen auf selbem port liegen reiehnfolge beliebig):
#define LCD_DATA4_PIN 2
#define LCD_DATA5_PIN 3
#define LCD_DATA6_PIN 4
#define LCD_DATA7_PIN 5
//User Konstanten:
#define LCD_ON_CURSOR_ON 14
#define LCD_ON_CURSOR_OFF 12
#define LCD_ON_CURSOR_BLINK 15
#define LCD_OFF 0
#define LCD_CLS 1
#define LCD_HOME 2
#define LCD_CFG_4BIT_5x07 56
#define LCD_CFG_4BIT_5x10 60
#define LCD_INCR_CURSOR 20
#define LCD_DECR_CURSOR 16
//LCD Interne Konstanten:
#define LCD_WR_DATA 1
#define LCD_WR_COMMAND 0
//LCD-Init-Funktionen:
void cfgLcdCommandLines(void);
void cfgLcdDataByteLinesWrite(void);
void cfgLcdDataByteLinesRead(void);
void toggleE(void);
unsigned char mkOutNibble(unsigned char dataByte);
void lcdSendByte(unsigned char dataByte, unsigned char mode);
void lcdSendData(unsigned char dataByte);
void cfgLcd4Bit();
void lcdIncrCursor(void);
void lcdDecrCursor(void);
void lcdCls(void);
void lcdHome(void);
void lcd_init(unsigned char mode);
lcd.c
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
#include "usart.h"
void cfgLcdCommandLines(void)
{
LCD_COM_DDR |= (1<<LCD_E_PIN);
LCD_COM_DDR |= (1<<LCD_RS_PIN);
LCD_COM_DDR |= (1<<LCD_RW_PIN);
}
void cfgLcdDataByteLinesWrite(void)
{
LCD_DATA_DDR |= (1<<LCD_DATA4_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA5_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA6_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA7_PIN);
}
void cfgLcdDataByteLinesRead(void)
{
LCD_DATA_DDR &=~ (1<<LCD_DATA4_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA5_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA6_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA7_PIN);
}
void toggleE(void)
{
LCD_COM_PORT |= (1<<LCD_E_PIN);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
LCD_COM_PORT &=~ (1<<LCD_E_PIN);
}
unsigned char mkOutNibble(unsigned char dataByte)
{
unsigned char out = 0;
out = ((dataByte & 1)<<LCD_DATA4_PIN);
out |= ((dataByte & 2)<<(LCD_DATA5_PIN-1));
out |= ((dataByte & 4)<<(LCD_DATA6_PIN-2));
out |= ((dataByte & 8)<<(LCD_DATA7_PIN-3));
return out;
}
void lcdSendByte(unsigned char dataByte, unsigned char mode)
{
unsigned char lNibble = dataByte & 15;
unsigned char uNibble = (dataByte>>4) & 15;
if(mode==LCD_WR_DATA)
{
LCD_COM_PORT |= (1<<LCD_RS_PIN);
_delay_ms(1);
}else
{
LCD_COM_PORT &=~ (1<<LCD_RS_PIN);
}
LCD_DATA_PORT = mkOutNibble(uNibble);
toggleE();
LCD_DATA_PORT = mkOutNibble(lNibble);
toggleE();
}
void lcdSendData(unsigned char dataByte)
{
unsigned char lNibble = dataByte & 15;
unsigned char uNibble = (dataByte>>4) & 15;
LCD_COM_PORT |= (1<<LCD_RS_PIN);
LCD_DATA_PORT = mkOutNibble(uNibble);
toggleE();
LCD_DATA_PORT = mkOutNibble(lNibble);
toggleE();
}
void cfgLcd4Bit()
{
LCD_COM_PORT &=~ (1<<LCD_RS_PIN);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(10);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(1);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(1);
LCD_DATA_PORT = mkOutNibble(2);
toggleE();
_delay_ms(10);
}
void lcdIncrCursor(void)
{
lcdSendByte(LCD_INCR_CURSOR,LCD_WR_COMMAND);
_delay_ms(8);
}
void lcdDecrCursor(void)
{
lcdSendByte(LCD_DECR_CURSOR,LCD_WR_COMMAND);
_delay_ms(8);
}
void lcdGotoXY(unsigned char xVal, unsigned char yVal)
{
}
void lcdCls(void)
{
lcdSendByte(LCD_CLS, LCD_WR_COMMAND);
}
void lcdHome(void)
{
lcdSendByte(LCD_HOME, LCD_WR_COMMAND);
}
void lcd_init(unsigned char mode)
{
_delay_ms(200);
cfgLcdCommandLines();
cfgLcdDataByteLinesWrite();
cfgLcd4Bit();
lcdSendByte(mode, LCD_WR_COMMAND);
lcdSendByte(LCD_CFG_4BIT_5x10, LCD_WR_COMMAND);
lcdSendByte(7, LCD_WR_COMMAND);
_delay_ms(10);
lcdCls();
}
main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "init.h"
#include "usart.h"
#include "globals.h"
#include "lcd.h"
int main(void)
{
cfgPorts();
cfgUsart();
enableInterrupts();
lcd_init(LCD_ON_CURSOR_BLINK);
while(1)
{
asm("nop");
asm("nop");
}
return 0;
}
Ich währe über jedlichen Ansatz sehr dankbar !
Mfg Fugitivus
Ich versuche schon seit einigen Tagen ein Display mit HD44780, in 4-bit Betrieb anzusteuern....
Ich habe mich so ein bisschen an folgende Anleitung gehalten:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
Ich habe auch definitiev nicht alles falsch gemacht, da die Command befehle wie z.B Cursor setzen aktivieren / deaktivieren und auch das initialisieren in den 4-bit modus zu funktionieren scheint.....
Was ich jezt überhaupt nicht verstehe, ist wie ich ein ascii zeichen sende....
So wie ich das verstanden habe, ist es auch ein byte (high/low-nibble)übertragen wie bei einem Command... nur das der RS pin in diesem fall auf HIGH gezogen werden muss...
Achso ich habe bewusst auf RW verzichtet.... mache ich vlt einen timing fehler ?
Also ganz konkret: wie sende ich ein z.B 'a' an die aktuelle Cursor Position ?
Hier erst mal der code:
lcd.h:
//Frequenz MicroProzessorUnit:
#define MPU_XTAL 8000000
//LCD-IO-Pins (nur 4-bit Betrieb!):
#define LCD_COM_DDR DDRB
#define LCD_COM_PORT PORTB
#define LCD_DATA_DDR DDRB
#define LCD_DATA_PORT PORTB
#define LCD_RS_PORT LCD_COM_PORT
#define LCD_RW_PORT LCD_COM_PORT
#define LCD_E_PORT LCD_COM_PORT
//Command lines(cmd pins müssen nicht auf selbem port liegen):
#define LCD_E_PIN 0
#define LCD_RS_PIN 1
#define LCD_RW_PIN 7
//Data lines(data pins müssen auf selbem port liegen reiehnfolge beliebig):
#define LCD_DATA4_PIN 2
#define LCD_DATA5_PIN 3
#define LCD_DATA6_PIN 4
#define LCD_DATA7_PIN 5
//User Konstanten:
#define LCD_ON_CURSOR_ON 14
#define LCD_ON_CURSOR_OFF 12
#define LCD_ON_CURSOR_BLINK 15
#define LCD_OFF 0
#define LCD_CLS 1
#define LCD_HOME 2
#define LCD_CFG_4BIT_5x07 56
#define LCD_CFG_4BIT_5x10 60
#define LCD_INCR_CURSOR 20
#define LCD_DECR_CURSOR 16
//LCD Interne Konstanten:
#define LCD_WR_DATA 1
#define LCD_WR_COMMAND 0
//LCD-Init-Funktionen:
void cfgLcdCommandLines(void);
void cfgLcdDataByteLinesWrite(void);
void cfgLcdDataByteLinesRead(void);
void toggleE(void);
unsigned char mkOutNibble(unsigned char dataByte);
void lcdSendByte(unsigned char dataByte, unsigned char mode);
void lcdSendData(unsigned char dataByte);
void cfgLcd4Bit();
void lcdIncrCursor(void);
void lcdDecrCursor(void);
void lcdCls(void);
void lcdHome(void);
void lcd_init(unsigned char mode);
lcd.c
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
#include "usart.h"
void cfgLcdCommandLines(void)
{
LCD_COM_DDR |= (1<<LCD_E_PIN);
LCD_COM_DDR |= (1<<LCD_RS_PIN);
LCD_COM_DDR |= (1<<LCD_RW_PIN);
}
void cfgLcdDataByteLinesWrite(void)
{
LCD_DATA_DDR |= (1<<LCD_DATA4_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA5_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA6_PIN);
LCD_DATA_DDR |= (1<<LCD_DATA7_PIN);
}
void cfgLcdDataByteLinesRead(void)
{
LCD_DATA_DDR &=~ (1<<LCD_DATA4_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA5_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA6_PIN);
LCD_DATA_DDR &=~ (1<<LCD_DATA7_PIN);
}
void toggleE(void)
{
LCD_COM_PORT |= (1<<LCD_E_PIN);
asm("nop");
asm("nop");
asm("nop");
asm("nop");
LCD_COM_PORT &=~ (1<<LCD_E_PIN);
}
unsigned char mkOutNibble(unsigned char dataByte)
{
unsigned char out = 0;
out = ((dataByte & 1)<<LCD_DATA4_PIN);
out |= ((dataByte & 2)<<(LCD_DATA5_PIN-1));
out |= ((dataByte & 4)<<(LCD_DATA6_PIN-2));
out |= ((dataByte & 8)<<(LCD_DATA7_PIN-3));
return out;
}
void lcdSendByte(unsigned char dataByte, unsigned char mode)
{
unsigned char lNibble = dataByte & 15;
unsigned char uNibble = (dataByte>>4) & 15;
if(mode==LCD_WR_DATA)
{
LCD_COM_PORT |= (1<<LCD_RS_PIN);
_delay_ms(1);
}else
{
LCD_COM_PORT &=~ (1<<LCD_RS_PIN);
}
LCD_DATA_PORT = mkOutNibble(uNibble);
toggleE();
LCD_DATA_PORT = mkOutNibble(lNibble);
toggleE();
}
void lcdSendData(unsigned char dataByte)
{
unsigned char lNibble = dataByte & 15;
unsigned char uNibble = (dataByte>>4) & 15;
LCD_COM_PORT |= (1<<LCD_RS_PIN);
LCD_DATA_PORT = mkOutNibble(uNibble);
toggleE();
LCD_DATA_PORT = mkOutNibble(lNibble);
toggleE();
}
void cfgLcd4Bit()
{
LCD_COM_PORT &=~ (1<<LCD_RS_PIN);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(10);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(1);
LCD_DATA_PORT = mkOutNibble(3);
toggleE();
_delay_ms(1);
LCD_DATA_PORT = mkOutNibble(2);
toggleE();
_delay_ms(10);
}
void lcdIncrCursor(void)
{
lcdSendByte(LCD_INCR_CURSOR,LCD_WR_COMMAND);
_delay_ms(8);
}
void lcdDecrCursor(void)
{
lcdSendByte(LCD_DECR_CURSOR,LCD_WR_COMMAND);
_delay_ms(8);
}
void lcdGotoXY(unsigned char xVal, unsigned char yVal)
{
}
void lcdCls(void)
{
lcdSendByte(LCD_CLS, LCD_WR_COMMAND);
}
void lcdHome(void)
{
lcdSendByte(LCD_HOME, LCD_WR_COMMAND);
}
void lcd_init(unsigned char mode)
{
_delay_ms(200);
cfgLcdCommandLines();
cfgLcdDataByteLinesWrite();
cfgLcd4Bit();
lcdSendByte(mode, LCD_WR_COMMAND);
lcdSendByte(LCD_CFG_4BIT_5x10, LCD_WR_COMMAND);
lcdSendByte(7, LCD_WR_COMMAND);
_delay_ms(10);
lcdCls();
}
main.c
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "init.h"
#include "usart.h"
#include "globals.h"
#include "lcd.h"
int main(void)
{
cfgPorts();
cfgUsart();
enableInterrupts();
lcd_init(LCD_ON_CURSOR_BLINK);
while(1)
{
asm("nop");
asm("nop");
}
return 0;
}
Ich währe über jedlichen Ansatz sehr dankbar !
Mfg Fugitivus