#use delay (clock = 20000000)
struct lcd_pin_map {
BOOLEAN rs;
BOOLEAN enable;
BOOLEAN rw;
BOOLEAN unused;
int data : 4;
} lcd;
#byte lcd = 8
#define set_tris_lcd(x) set_tris_d(x)
#define lcd_type 2
#define lcd_line_two 0x40
byte const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0x0c, 1, 6};
struct lcd_pin_map const LCD_WRITE = {0, 0};
struct lcd_pin_map const LCD_READ = {0, 15};
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n) {
lcd.rs = 0;
delay_us(500);
lcd.rs = address;
delay_cycles(1);
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0x0f);
}
void lcd_gotoxy( byte x, byte y) {
byte address;
if(y != 1)
address = lcd_line_two;
else
address = 0;
address += x-1;
lcd_send_byte(0,0x80|address);
}
void lcd_init() {
byte i;
set_tris_lcd(LCD_WRITE);
set_tris_d(0B00000000);
lcd.rs = 0;
delay_ms(15);
for (i=1; i<=3; ++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for (i=0; i<=3; ++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}
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;
case '\p' : lcd_gotoxy(9,2); break;
default : lcd_send_byte(1,c); break;
}
}