#INCLUDE <16F887.h>
#DEVICE ADC=10
#USE DELAY(CLOCK=20000000)
#FUSES XT,NOPROTECT,NOWDT,NOBROWNOUT,PUT,NOLVP
#DEFINE USE_PORTB_KBD   //Por defecto el teclado se conecta al puerto D,
                        //como el microcontrolador que se esta usando
                        //no tiene puerto D se conecta al puerto B.*/
#INCLUDE <LCD.C>
#INCLUDE <KBD4x4.C>  //Incluir en el encabezado el driver para
                      //manejar el teclado telefónico MODIFICADO
#include <stdlib.h>
#include <string.h>

#use     standard_io(b) 
#define  KEYHIT_DELAY   200    //Tiempo de espera del teclado en milisegundos
#byte PORTB= 6
#byte PORTC= 7
#BYTE PORTA= 5
#BYTE PORTD= 8

int16 adc,control=0;
long T=100; //100 ms
float R=0;
char c;
int opcion=0, Timer2,Poscaler;
int16 duty=0;


/*===========================================================================*/
/*=======================       FUNCION TECLA         =======================*/
/*===========================================================================*/
//Funcion encargada de esperar a que se presione una tecla 
char tecla(void)
{
   char c;
   do{ //espera hasta que se presione una tecla
      c=kbd_getc(); //Captura valor del teclado
     }
   while(c=='\0'); 
   return(c);
}

/*===========================================================================*/
/*=======================    FUNCION TECLA CON TIMER  =======================*/
/*===========================================================================*/
// Pregunta por una Tecla por un tiempo, si no hay actividad, deja de preguntar
// y deja que el PIC continue con su trabajo

char tecla_time(void) {
   char c='\0';
   unsigned int16 timeout;
   timeout=0;
   c=kbd_getc(); //Captura valor del teclado
   while(c=='\0' && (++timeout< (KEYHIT_DELAY*100)))
   {
      delay_us(10);
      c=kbd_getc(); //Captura valor del teclado
   }
   return(c);
}

/*===========================================================================*/
/*============   FUNCION PARA DIGITAR ESCALÓN/SETPOINT  =====================*/
/*===========================================================================*/
long escalon(int nd)
{
   //Esta funcion captura el escalon desde el teclado, si el proceso está tomando
   //datos el escalon sirve para exitar el sistema, por otro lado si el sistema
   //está controlando, el escalo sirve para establecer el setpoint del sistema
   
   long val;
   int i;
   char str[5]; //Variable tipo String
   
   str[0]='0';
   for(i=0;i<nd;i++)
   {
      
      c=tecla();  //Lee el valor del teclado y espera hasta que alguna tecla se pulse
      if(c!='*'){
         //Muestra el digito presionado en el LCD
         lcd_gotoxy(5+i,4);
         lcd_putc(c);
         //Almacena el dato presionado en la variable String
         str[i]=c;
      }
      else{i=nd;} //Si se presiona * sale del For      
   }
   val = atol(str); //Convierte el String en un valor numerico
   return (val);
}

/*===========================================================================*/
/*=======================    FUNCION DEL PRINCIPAL    =======================*/
/*===========================================================================*/
void main()
{
   Timer2=71;    
   Poscaler=1; 
   setup_timer_2(t2_div_by_1,Timer2,Poscaler);  //Configuracion de Timer 2 para establecer frec. PWM a 1kHz
   setup_ccp1(ccp_pwm);                //Configurar modulo CCP1 en modo PWM
                      //Dejo en cero la salida PWM
   port_b_pullups (0xFF);  //Utiliza las resistencias PULL UP internas del puerto B
   set_tris_c(0);
   set_tris_d(0);
   LCD_INIT();                         //Inicializo el LCD
   LCD_PUTC("\f");                     //Limpio el LCD

      
   while(1)
   {

         lcd_gotoxy(1,1);
         LCD_PUTC("velocidad");
         lcd_gotoxy(1,4);
         LCD_PUTC("D:        ");
         R=escalon(3); //Llama la funcion para digitar el escalon de exitacion
         //Valida si R esta entre 0 y 256 (Esto es otra forma de usar el if - else)
         R= (R>256) ? 256:R;
         duty= R;
         //Muestra el SETPOINT en pantalla
         lcd_gotoxy(1,4);
         printf(lcd_putc,"SP: %3.1f",R);
         delay_ms(200); 
         set_pwm1_duty(duty);
         
    }
}
