//coder: PCM Programmer
#define LCD_DB4 PIN_b0
#define LCD_DB5 PIN_b1
#define LCD_DB6 PIN_b2
#define LCD_DB7 PIN_b3
#define LCD_E PIN_b5
#define LCD_RS PIN_b4
#define LCD_RW PIN_b7
#define LCD_CGRAM_ADDR 0x40
#define LCD_DDRAM_ADDR 0x80
#define USE_LCD_RW 1
#define lcd_type 2
#define lcd_line_two 0x40
#define LCD_CHAR_1 0x01
#define LCD_CHAR_2 0x02
#define LCD_CHAR_3 0x03
#define LCD_CHAR_4 0x04
#define LCD_CHAR_5 0x05
#define LCD_CHAR_6 0x06
#define LCD_CHAR_7 0x07
#define LCD_CHAR_8 0x08
int8 const LCD_INIT_STRING[4] =
{0x20 | (lcd_type << 2),0xc,1,6};
void lcd_send_nibble(int8 nibble)
{
output_bit(LCD_DB4, !!(nibble & 1));
output_bit(LCD_DB5, !!(nibble & 2));
output_bit(LCD_DB6, !!(nibble & 4));
output_bit(LCD_DB7, !!(nibble & 8));
delay_cycles(1);
output_high(LCD_E);
delay_us(2);
output_low(LCD_E);
}
#ifdef USE_LCD_RW
int8 lcd_read_nibble(void)
{
int8 retval;
#bit retval_0 = retval.0
#bit retval_1 = retval.1
#bit retval_2 = retval.2
#bit retval_3 = retval.3
retval = 0;
output_high(LCD_E);
delay_cycles(1);
retval_0 = input(LCD_DB4);
retval_1 = input(LCD_DB5);
retval_2 = input(LCD_DB6);
retval_3 = input(LCD_DB7);
output_low(LCD_E);
return(retval);
}
#endif
#ifdef USE_LCD_RW
int8 lcd_read_byte(void)
{
int8 low;
int8 high;
output_high(LCD_RW);
delay_cycles(1);
high = lcd_read_nibble();
low = lcd_read_nibble();
return( (high<<4) | low);
}
#endif
void lcd_send_byte(int8 address, int8 n)
{
output_low(LCD_RS);
#ifdef USE_LCD_RW
while(bit_test(lcd_read_byte(),7)) ;
#else
delay_us(60);
#endif
if(address)
output_high(LCD_RS);
else
output_low(LCD_RS);
delay_cycles(1);
#ifdef USE_LCD_RW
output_low(LCD_RW);
delay_cycles(1);
#endif
output_low(LCD_E);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_setcursor_vb(short visible, short blink) {
lcd_send_byte(0, 0xC|(visible<<1)|blink);
}
void lcd_init(void)
{
int8 i;
output_low(LCD_RS);
#ifdef USE_LCD_RW
output_low(LCD_RW);
#endif
output_low(LCD_E);
delay_ms(15);
for(i=0 ;i < 3; i++)
{
lcd_send_nibble(0x03);
delay_ms(5);
}
lcd_send_nibble(0x02);
for(i=0; i < sizeof(LCD_INIT_STRING); i++)
{
lcd_send_byte(0, LCD_INIT_STRING[i]);
#ifndef USE_LCD_RW
delay_ms(5);
#endif
}
}
void lcd_gotoxy(int8 x, int8 y)
{
int8 address;
if(y != 1)
address = lcd_line_two;
else
address=0;
address += x-1;
lcd_send_byte(0, 0x80 | address);
}
void lcd_putc(char c)
{
switch(c)
{
case '\f':
lcd_send_byte(0,1);delay_ms(2);break;
case '\n':lcd_gotoxy(1,2);break;
case '\b':lcd_send_byte(0,0x10);break;
default:
lcd_send_byte(1,c);break;
}
}
#ifdef USE_LCD_RW
char lcd_getc(int8 x, int8 y)
{
char value;
lcd_gotoxy(x,y);
while(bit_test(lcd_read_byte(),7));
output_high(LCD_RS);
value = lcd_read_byte();
output_low(lcd_RS);
return(value);
}
#endif