Datos_teclado_pic18f887A

Buenas noches a todos.
Q
uiero almacenar los datos ingresados por un teclado numérico de la siguiente manera:
Que se pueda ingresar un dato y se mantenga en ese dato por un tiempo ingresado también por teclado.
Luego presionando la tecla (*) se ingrese otro dato y se mantenga en ese dato por un tiempo ingresado por teclado, así sucesivamente hasta que se puedan ingresar 5 procesos similares.
A
l final después de ingresar todos los datos presionando la tecla (#) ejecute todos los procesos en el orden que se ingresaron.
Hasta el momento solo he podido ingresar un dato y que lo muestre en la LCD.
Por-favor, quisiera que me ayudaran. Adjunto el código que llevo.
C:
#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=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 70kHz

   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);

        

    }

}
1632032645756.png
 
Yo creo que podrías usar las etiquetas </> para tabular el código y sobre todo usar el buscador del foro, porque hilos de teclados, LCDs y PICs hay muchísimos.
 
Es muy limitante programar saltando a rutinas de control y detener el programa en un solo bucle.
El programa , cualquiera sea este, tiende a andar a los saltitos y se notan mucho los defectos, conforme a las rutinas que se van agregando-

Resulta mucho mas estable, si se programa a base de RAFAGAS y rutinas de interrupción.
Por ejemplo : 1 ráfaga de programa cada 10 milisegundos es un punto de partida razonable.
Es decir que el programa nunca para en un punto, de esa manera da la apariencia que el controlador hace todo al mismo tiempo de manera interactiva. Solo se detiene cuando ya no tiene NADA para hacer, pero cada 10 milisegundos indaga a todo periférico u ordena el STACK o el puntero de su memoria de datos

Abajo le dejo el esqueleto de un sistema operativo para PIC que SI funciona para Cualquier aplicación , solo que está en assembler, si aprende a leerlo, podrá escribir casi cualquier programa, como si fuera un PLC INDUSTRIAL , fue un trabajo de MESES

Basicamente la rutina interrupción tiene que atender todos los periféricos de manera transparente asi usted se concentra en SU problema.
.
 

Adjuntos

  • SOP16F628A.rar
    5.4 KB · Visitas: 7
Última edición:
Amigos, es la primera vez que escribo acá, pido excusas por el desorden, realmente no tengo ninguna respuesta, podrían ayudarme con alguna forma de solucionarlo? Estaba pensando en hacerlo por switch case, pero no se si sea lo mejor... Agradecería las respuestas obtenidas.
 
Por si así se lee mejor el código:
Código:
#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=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 70kHz
   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);
    }
}
 
Arriba