#include "lcd.h"
// ***********************************************************
// ******************** PUBLIC FUNCTIONS *********************
// ***********************************************************
void lcdInit4(void)
{ // initialize LCD control & data
// lines to output
PORTD = 0b00000001; // pull-up on unused input
DDRD = 0b11111110; // set ctrl & data as outputs
delay_ms(50); // - wait 15ms or more
// -------------------
CLEARBIT(PORTD, LCD_CTRL_RS); // set RS to "control"
CLEARBIT(PORTD, LCD_CTRL_RW); // set R/W to "write"
// 4 bit write
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
// PORTD = (PORTD | 0x30) & 0x3F; // output data, high 4 bits
PORTD = (PORTD | 0x20) & 0x2F; // output data, high 4 bits
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
// -------------------
delay_ms(5); // - wait 4.1ms
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
// -------------------
delay_ms(1); // - wait 0.1ms
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
// -------------------
while(lcdBusy()) /* wait */ ; // check for not busy
// -------------------
PORTD = (PORTD | 0x20) & 0x2F; // output data, high 4 bits
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
// -------------------
lcdControlWrite(0x28); // 0x28 - function set (2 rows, 5x8 font)
lcdControlWrite(0x08); // 0x08 - display OFF
lcdControlWrite(0x01); // 0x01 - clear display
lcdControlWrite(0x06); // 0x06 - shift right
lcdControlWrite(0x0C); // 0x0C - display ON, cursor OFF
}
// ************************************************************
// ********************** LOCAL FUNCTIONS *********************
// ************************************************************
void lcdControlWrite(unsigned char c_data) // write the CONTROL byte to the display controller
{
while(lcdBusy()) /* wait here */ ; // wait until LCD not busy or timeout
CLEARBIT(PORTD, LCD_CTRL_RS); // set RS to "control"
CLEARBIT(PORTD, LCD_CTRL_RW); // set R/W to "write"
PORTD = (PORTD&0x0F)|(c_data&0xF0); // output data, high 4 bits
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
PORTD = (PORTD&0x0F) | (c_data<<4); // output data, low 4 bits
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
}
void lcdDataWrite(unsigned char w_data) // write a DATA byte to the display
{
while(lcdBusy()) /* wait */ ; // wait until LCD not busy or timeout
SETBIT(PORTD, LCD_CTRL_RS); // set RS to "data"
CLEARBIT(PORTD, LCD_CTRL_RW); // set R/W to "write"
PORTD = (PORTD&0x0F) | (w_data&0xF0); // output data, high 4 bits
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
PORTD = (PORTD&0x0F) | (w_data<<4); // output data, low 4 bits
SETBIT(PORTD, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
CLEARBIT(PORTD, LCD_CTRL_E); // clear "E" line
}
// ak vrati 1, OK
// ak vrati 0, vyprsal timeout
volatile unsigned char t_out_LCD; // timeout displeja (krok 1024 us)
// krok 1ms
unsigned char lcdBusy(void)
{
delay_ms(10);
return 0;
/*
unsigned char pom;
t_out_LCD=4; // pockam cca 4ms
// wait until LCD busy bit goes to zero
// do a read from control register
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
LCD_DATA_PORT |= 0xF0; // set pull-ups to on (4bit)
LCD_DATA_DDR &= 0x0F; // set data I/O lines to input (4bit)
SETBIT(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
pom= LCD_DATA_PIN&0xF0; // input data, high 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
pom|=(LCD_DATA_PIN>>4)&0x0F; // input data, low 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
while ((pom & (1<<LCD_BUSY)) && t_out_LCD )
{
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
pom=LCD_DATA_PIN&0xF0; // input data, high 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
pom|=(LCD_DATA_PIN>>4)&0x0F; // input data, low 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
}
// leave data lines in input mode so they can be most easily used for other purposes
if(t_out_LCD)
return 1; // ak vrati 1 timeout OK
else
return 0; // ak vrati 0 timeout notOK
*/
}
/*
unsigned char lcdControlRead(void)
{
// read the control byte from the display controller
register unsigned char r_data=0;
if(lcdBusyWait()) // wait until LCD not busy or time out
{
outb(LCD_DATA_PORT, inb(LCD_DATA_PORT)|0xF0); // set pull-ups to on (4bit)
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "control"
SETBIT(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
r_data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
r_data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
// leave data lines in input mode so they can be most easily used for other purposes
}
return r_data;
}
unsigned char lcdDataRead(void)
{
// read a data byte from the display
register unsigned char r_data =0;
if(lcdBusyWait()) // wait until LCD not busy or time out
{
outb(LCD_DATA_PORT, inb(LCD_DATA_PORT)|0xF0); // set pull-ups to on (4bit)
outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F); // set data I/O lines to input (4bit)
SETBIT(LCD_CTRL_PORT, LCD_CTRL_RS); // set RS to "data"
SETBIT(LCD_CTRL_PORT, LCD_CTRL_RW); // set R/W to "read"
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
r_data = inb(LCD_DATA_PIN)&0xF0; // input data, high 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
LCD_DELAY; // wait
SETBIT(LCD_CTRL_PORT, LCD_CTRL_E); // set "E" line
LCD_DELAY; // wait
r_data |= inb(LCD_DATA_PIN)>>4; // input data, low 4 bits
CLEARBIT(LCD_CTRL_PORT, LCD_CTRL_E); // clear "E" line
}
// leave data lines in input mode so they can be most easily used for other purposes
return r_data;
}
*/
void delay_ms(unsigned int ms)
{
unsigned int index;
while (ms)
{
index = F_CPU / 5000; // vypocitajte, kolko treba, aby sme dostali 1ms!!
while (index)
{
asm volatile ("nop");
index--;
}
ms--;
}
}