/*
 *	Libreria para controlar un LCD con el PIC16F876A PORTB
 */

/* Escribe un byte en el LCD en modo de 4bits */
extern void lcd_write(unsigned char);

/* Limpia la pantalla y vuelve al inicio el cursor */
extern void lcd_clear(void);

/* Escribe un string de caracteres */
extern void lcd_puts(const char * s);

/* Mueve el cursor a la ubicacion especifica */
extern void lcd_goto(unsigned char pos);
	
/* Inicializa el LCD - (Llamar al principio) */
extern void lcd_init(void);

/* Escribe un caracter */
extern void lcd_putch(char);


void putch(char c);


#define	lcd_cursor(x)	lcd_write(((x)&0x7F)|0x80)
#define	LCD_STROBE()	((LCD_EN = 1),(LCD_EN=0))

int control_store;


void lcd_write(unsigned char c){
	__delay_us(40);
	LCD_DATA = ( ( c >> 4 ) & 0x0F )^control_store;
	LCD_STROBE();
	LCD_DATA = ( c & 0x0F )^control_store;
	LCD_STROBE();
}


void lcd_clear(void) {
	LCD_RS = 0;
	control_store=PORTB&240; 
	lcd_write(0x1);
	__delay_ms(2);
}



void lcd_puts(const char * s) {
	LCD_RS = 1;	// escribe
	control_store=PORTB&240;
	while(*s)
	lcd_write(*s++);
}

void lcd_putch(char c) {
	LCD_RS = 1;
	control_store=PORTB&240; 
	lcd_write( c );
}

void putch(char c) { 
	lcd_putch(c); 
}


void lcd_goto(unsigned char pos) {
	LCD_RS = 0;
	control_store=PORTB&240;
	lcd_write(0x80+pos);
}


void lcd_init() {
	char init_value;
	
	init_value = 0x3;
	
	
	TRISB=0;
	
	LCD_RS = 0;
	LCD_EN = 0;
	LCD_RW = 0;
	
	control_store=PORTB&240; 

	__delay_ms(15);	// espero 15mS
	LCD_DATA	 = init_value^control_store;
	LCD_STROBE();
	__delay_ms(5);
	LCD_STROBE();
	__delay_us(200);
	LCD_STROBE();
	__delay_us(200);
	LCD_DATA = 2^control_store;	// modo de 4 bits
	LCD_STROBE();
	
	lcd_write(0x28); // largo de la interfaz
	lcd_write(0xF & 0x0d & 0x0e); //  Modos: Display On, Cursor On, Cursor blink
	lcd_clear();	// borro pantalla
	lcd_write(0x6); // habilito para escribir
}
