OK. Dann ist hier das ganze nochmal mit Code tags
Code:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "config.h"
#include "main.h"
#define CLOCK 8000000UL
// quite acurate delay delay by active waiting ...
#define LCD_DELAY_MICROSEC(a) ((a)*CLOCK/6000000)
#define LCD_DELAY_MILLISEC(a) ((a)*CLOCK/6000)
void lcd_delay(unsigned long int ticks);
__asm__ (
"lcd_delay: \n"
" subi r22,lo8(1) \n" // 1 clk
" sbci r23,hi8(1) \n" // 1 clk
" sbci r24,hlo8(1) \n" // 1 clk
" sbci r25,hhi8(1) \n" // 1 clk
" brne lcd_delay \n" // 2 clk
" ret \n"
);
// hitachi hd44780 controller commands
#define LCD_CLEAR 0x01
#define LCD_SET_ENTRY_MODE 0x04
#define LCD_ENTRY_INCR 0x02
#define LCD_ON 0x08
#define LCD_DISPLAY_ON 0x04
#define LCD_DISPLAY 0x08
#define LCD_FUNCTION 0x20
#define LCD_8_BIT 0x10
#define LCD_DOUBLE 0x08
#define LCD_SET_DISP_ADDR 0x80
#define LCD_BUSY 0x80
int main(void)
{
_delay_ms(100);
lcd_init();
lcd_print("Hallo");
while(1)
{
}
return 0;
}
// disable LCD by asserting E
static inline void lcd_enable(void)
{
// enable LCD
LCD_CTRL_PORT |= _BV(LCD_CTRL_E1);
lcd_delay(LCD_DELAY_MICROSEC(10));
}
// disable LCD by deasserting E
static inline void lcd_disable(void)
{
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_E1);
lcd_delay(LCD_DELAY_MICROSEC(10));
}
// switch LCD data port to input
static inline void lcd_data_input(void)
{
LCD_DATA_DDR = 0x00; // data lines are input
LCD_DATA_PORT = 0xff; // enable pull-ups
}
// access LCD by enabling and disabling E
static inline void lcd_write(unsigned char data)
{
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RW); // write
LCD_DATA_DDR = 0xFF; // set data I/O lines to output (8bit)
LCD_DATA_PORT = data; // output data, 8bits
lcd_enable();
lcd_disable();
lcd_data_input();
}
static void lcd_wait_while_busy(void)
{
// wait until LCD busy bit goes to zero
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RS); // ctrl access
lcd_data_input();
LCD_CTRL_PORT |= _BV(LCD_CTRL_RW); // read
lcd_enable();
/* wait for BUSY flag to be gone */
while(LCD_DATA_PIN & LCD_BUSY)
{
lcd_disable();
lcd_enable();
}
lcd_disable();
}
// write the control byte to the display controller
static void lcd_write_ctrl(unsigned char data)
{
lcd_wait_while_busy();
LCD_CTRL_PORT &= ~_BV(LCD_CTRL_RS); // ctrl access
lcd_write(data);
}
// write a data byte to the display
static void lcd_write_data(unsigned char data)
{
lcd_wait_while_busy();
LCD_CTRL_PORT |= _BV(LCD_CTRL_RS); // data access
lcd_write(data);
}
//Init lcd
void lcd_init(void)
{
// Controller 1
{
// make the three control lines outputs
LCD_CTRL_PORT &= ~(_BV(LCD_CTRL_RS) | _BV(LCD_CTRL_RW) | _BV(LCD_CTRL_E1) | _BV(LCD_CTRL_E2)); //everything to low
LCD_CTRL_DDR |= (_BV(LCD_CTRL_RS) | _BV(LCD_CTRL_RW) | _BV(LCD_CTRL_E1) | _BV(LCD_CTRL_E2)); //everything outgoing ports
// don't drive data lines
lcd_data_input();
// writing three times the config byte makes sure, that
// the interface is in 8 bit mode afterwards
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);
lcd_write_ctrl(LCD_FUNCTION | LCD_8_BIT | LCD_DOUBLE);
lcd_write_ctrl(LCD_ON | LCD_DISPLAY_ON);
lcd_write_ctrl(LCD_SET_ENTRY_MODE | LCD_ENTRY_INCR);
}
}
//prints text to display
static void lcd_print(char *str)
{
while(*str)
lcd_write_data(*str++);
}
Lesezeichen