
/* Codigo para manejar LCD 4bits de 2 lineas 20*2 ó 16*2 soporta para iar o comp
   atible con visionavr y Winavr para ATmega8 */
// Modificar esta dirección por la donde se copie el archivo
#include "C:\Documents and Settings\Rapido\Mis documentos\nuevo avr\delay_iar.h"
#ifdef LCD_PORTB      // E=P0 RS=P1 RW=GND pines 4 al 7 bus de datos
#define PORT_LCD PORTB
#define DDR_LCD DDRB
#define FO 0xf0
#define OF 0x0f
#define D 4
#define R 0
#endif

#ifdef LCD_PORTD
#define PORT_LCD PORTD
#define DDR_LCD DDRD
#define FO 0xf0
#define OF 0x0f
#define D 4
#define R 0
#endif

#ifdef LCD_PORTC   // E pin0 RS pin1 RW a tierra ,pin2 a pin5 bus de datos
#define PORT_LCD PORTC
#define DDR_LCD DDRC
#define FO 0x3c
#define OF 0x03
#define D 2
#define R 2
#endif
/* Modo de cursor y movimiento */
#define INCREMENTA_CURSOR  1
#define DECREMENTA_CURSOR  0
#define DESPLASAMINTO  1
#define NORMAL  0


// LCD modo 4bits P.0=e P.1=rs

void _nop(char a){
  while(a){
  asm("nop\n");
  asm("nop\n");
  asm("nop\n");
  asm("nop\n");
  a-=1;
  }
}

void datos(char t){
  char b;
  DDR_LCD=0xff;
  PORT_LCD|=1; // E bit 0 E=1
  PORT_LCD|=2; // RS=1
  PORT_LCD = PORT_LCD&OF;//  data E=P.0 RS=P.1
  b=(t>>R)&FO;
  PORT_LCD |=b;
  _nop(40);
  PORT_LCD &= 254; // desabilita E
  _nop(10);
  PORT_LCD = PORT_LCD&OF;
  PORT_LCD |= 1; // habilita E
  PORT_LCD |= t<<D; // 3 a data E=P.0 RS=P.1
  _nop(40);
  PORT_LCD &= 254;
};


void control(char a){
  char b;
  DDR_LCD=0xff;
  PORT_LCD &=253; // RS=0
  PORT_LCD = PORT_LCD&OF;// 3 a data E=P.0 RS=P.1
  _nop(2);
  PORT_LCD |= 1; // habilita E
  b=(a>>R)&FO;
  PORT_LCD |= b; // 3 a data E=P.0 RS=P.1
  _nop(255);
  PORT_LCD &= 254; // desabilita E
  _nop(255);
  PORT_LCD = PORT_LCD&OF;
  PORT_LCD |= 1; // habilita E
  PORT_LCD |= a<<D;
  _nop(255);
  PORT_LCD &= 254;
}

void lcd_init(){
  char b[]={2,44,12,6,128},i,a;
   DDR_LCD=0xff; //PORT salida
   PORT_LCD&=0x00; // RS=0
   delay_ms(1);
   control(3);
   delay_ms(5);
   for(i=0;i<=4;i++){
     a=b[i];
     control(a);
     delay_ms(5);
   }
}

void lcd_putsf(const char *a){
  char b;
   b=*a;
   while(b){
  datos(b);
  delay_ms(2);
  a+=1;
  b=*a;
  }
}
void lcd_put(char *a){
  char b;
  b=*a;
  while(b){
  datos(b);
  delay_ms(2);
  a+=1;
  b=*a;
  }
}
void lcd_clear(){
  control(1);
  delay_ms(15);
}

void lcd_gotoxy(char x,char y){
  if((x<=20)&&(y==0)){
    x=128+x;
    control(x);
    delay_ms(1);
  }
  if((x<=20)&&(y==1)){
    x=192+x;
    control(x);
    delay_ms(1);
  }
}
void lcd_putchar(char a){
   datos(a);
   delay_ms(5);
}
void lcd_cursor_i_d_desplazar(char c,char d){   
/* c=1 incrementa cursor c=0 decrementa cursor ,d=1 desplaza cursor cada vez que escribe dato en negro d=0 
   modo normal */

   if((c<2)&&( d<2)){
       c=c<<1;
       d=(c|d)|4;
       control(d);
       delay_ms(1);
   }
}
void lcd_cursor_display(char c,char d){  /* c=1 desplaza visualización c=0 cursor, d=1 deplaza derecha d=0 desplaza
    izquierda */
   if((c<2)&&(d<2)){
       c=c<<3;
       d=d<<2;
       d=(d|c)|16;
       control(d);
       delay_ms(1);
    }
}	
          	