/* mija 2008
source file for lcd HITACHI 16x2,8x2,...
!!! must be set PINs,PORTs,DDR in lcd.h
ver.: 0.0 TESTED
(source from lcd.c from (c)miho 2005)
*/
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include "lcd.h"
#include <stdio.h>
//*************************************************************
#define H_D0 PORT_D0 |=_BV(PIN_D0)
#define L_D0 PORT_D0 &= ~(_BV(PIN_D0))
#define H_D1 PORT_D1 |=_BV(PIN_D1)
#define L_D1 PORT_D1 &= ~(_BV(PIN_D1))
#define H_D2 PORT_D2 |=_BV(PIN_D2)
#define L_D2 PORT_D2 &= ~(_BV(PIN_D2))
#define H_D3 PORT_D3 |=_BV(PIN_D3)
#define L_D3 PORT_D3 &= ~(_BV(PIN_D3))
#define H_E PORT_E |=_BV(PIN_E)
#define L_E PORT_E &= ~(_BV(PIN_E))
#define H_RS PORT_RS |=_BV(PIN_RS)
#define L_RS PORT_RS &= ~(_BV(PIN_RS))
//*************************************************************
// Definice konstant pro LCD display
//
#define LCD_CURSOR_ON_ 0x0E // kurzor jako blikajici radka pod znakem
#define LCD_CURSOR_OFF_ 0x0C // zadny kurzor
#define LCD_LINE_2 0x40 // adresa 1. znaku 2. radky
// Definice rezimu LCD displeje
//
uint8_t PROGMEM LCD_INIT_STRING[4] =
{
0x28, // intrfejs 4 bity, 2 radky, font 5x7
LCD_CURSOR_OFF_, // display on, kurzor off,
0x01, // clear displeje
0x06 // inkrement pozice kurzoru (posun kurzoru doprava)
};
void LCD_init_IO_PIN(void)
{
DDR_D0 |= _BV(PIN_D0);
DDR_D1 |= _BV(PIN_D1);
DDR_D2 |= _BV(PIN_D2);
DDR_D3 |= _BV(PIN_D3);
DDR_E |= _BV(PIN_E);
DDR_RS |= _BV(PIN_RS);
}
void LCD_init(void)
{
uint8_t a;
LCD_init_IO_PIN();
_delay_ms(20);
L_E;
L_RS;
for (a=0;a<3;a++)
{
_delay_ms(2);
LCD_send_nibble(0x3);
}
_delay_us(40);
LCD_send_nibble(0x2);
_delay_us(40);
for (a=0;a<3;a++)
{
LCD_send_command(pgm_read_byte(&(LCD_INIT_STRING[a])));
_delay_ms(2);
}
}
void LCD_putc(uint8_t data)
{
LCD_send_data(data);
}
void LCD_send_command(uint8_t data)
{
L_RS;
LCD_send(data);
H_RS;
}
void LCD_send_data(uint8_t data)
{
H_RS;
LCD_send(data);
}
void LCD_send(uint8_t data)
{
LCD_send_nibble(data >> 4);
LCD_send_nibble(data);
_delay_us(40);
}
void LCD_send_nibble(uint8_t data)
{
L_D0;L_D1;L_D2;L_D3;
if (data & 0x1) H_D0;
if (data & 0x2) H_D1;
if (data & 0x4) H_D2;
if (data & 0x8) H_D3;
H_E;
_delay_us(1);
L_E;
}
void LCD_clear(void)
{
LCD_send_command(1);
_delay_ms(2);
}
void LCD_gotoxy( uint8_t x, uint8_t y)
{
uint8_t Adr;
Adr=x-1;
if(y==2)
Adr+=LCD_LINE_2;
LCD_send_command(0x80|Adr);
}