//Khoi tao lcd : lcd_init();
//Cac lenh cho LCD:
//Xoa man hinh: lcd_putc("\f");
//Dinh toa do hien thi: lcd_gotoxy(x,y) voi x la cot(0->15),y la hang(0,1)
//Xuong dong : dong 1: lcd_putc("\1");
//            dong 2: lcd_putc("\2");
//            dong 3: lcd_putc("\3");
//            dong 4: lcd_putc("\4");
//Vi du: Hien thi: Truong dai hoc
//               cong nghiep
//Lenh la: lcd_putc("\f\1Truong dai hoc\2cong nghiep");               
#include <16F887.h>
#include "lcd.h"
#use delay(clock=4000000)
void write_data(char data) {
//    output_bit(LCD_RW, 0);
    output_bit(LCD_EN, 0);
    output_bit(LCD_D7, (data >> 7)&1);
    output_bit(LCD_D6, (data >> 6)&1);
    output_bit(LCD_D5, (data >> 5)&1);
    output_bit(LCD_D4, (data >> 4)&1);
    output_bit(LCD_EN, 1);
    output_bit(LCD_EN, 0);
    delay_us(20);
    output_bit(LCD_D7, (data >> 3)&1);
    output_bit(LCD_D6, (data >> 2)&1);
    output_bit(LCD_D5, (data >> 1)&1);
    output_bit(LCD_D4, data & 1);
    output_bit(LCD_EN, 1);
    output_bit(LCD_EN, 0);
    delay_us(20);
}

void lcd_command(char command) {
    delay_us(20);
    output_bit(LCD_RS, 0);
    write_data(command);
}

void lcd_gotoxy(unsigned char col, unsigned char row) {
    unsigned char address;
    switch (row) {
        case 0: address = 0x00;
            break; //line 1: begin 0  (0x00) -> 39  (0x27)
        case 1: address = 0x40;
            break; //line 2: begin 64 (0x40) -> 103 (0x67)
        case 2: address = 0x14;
            break; //line 3: begin 64 (0x40) -> 103 (0x67)
        case 3: address = 0x54;
            break; //line 4: begin 64 (0x40) -> 103 (0x67)
        default:address = 0x00;

    }
    address += col;
    lcd_command(0x80 | address); //goto memory cell at address of DDRAM (setup DDRAM address)
    delay_ms(2);
}

void lcd_putc(char c) // Ham se hien thi ky tu c tai vi tri ke tiep tren C.LCD.
{
    switch (c) {
        case '\f': // Chuc nang xoa hien thi.
            lcd_command(0x01); // Goi ham truyen thong tin (lenh) sang C
            delay_ms(100); // Lenh: Xoa hien thi tren man hinh C.LCD (0x01).
            break;
        case '\a': // Chuc nang bat dau hang thu 1.
            lcd_gotoxy(0, 0); // Goi ham truyen thong tin (du lieu) sang C.LCD.
            break;
        case '\b': // Chuc nang bat dau hang thu 2.
            lcd_gotoxy(0, 1); // Goi ham truyen thong tin (du lieu) sang C.LCD.
            break;
        case '\c': // Chuc nang bat dau hang thu 2.
            lcd_gotoxy(0, 2); // Goi ham truyen thong tin (du lieu) sang C.LCD.
            break;
        case '\d': // Chuc nang bat dau hang thu 2.
            lcd_gotoxy(0, 3); // Goi ham truyen thong tin (du lieu) sang C.LCD.
            break;
        default: // Chuc nang hien thi ky tu c tai vi tri ke tiep tren C.LCD.
            output_bit(LCD_RS, 1);
            write_data(c);
            break;
    }
}

void lcd_puts(char*s) {
    while (*s) {
        lcd_putc(*s++);
    }
}

void lcd_init() {
   set_tris_d(0x00);
   //set_tris_e(0x00);
    lcd_command(0x30);
    delay_us(100);
    lcd_command(0x30);
    delay_us(100);
    lcd_command(0x32);
    delay_us(500);
    lcd_command(0x28);
    lcd_command(0x0c);
    lcd_command(0x06);
    lcd_command(0x01);
    delay_ms(500);
}
