Autor Tema: Ingreso de datos por teclado  (Leído 3061 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Ingreso de datos por teclado
« en: 22 de Enero de 2008, 20:48:28 »
Hola quisiera saber como tengo que hacer para ingresar datos de dos numeros por teclado usando el puerto serie RS232, este es el codigo con el que estoy tratando de hacer pero no logro hacerlo funcionar..

#include <18f4550.h>
//#fuses HS,MCLR,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN,NOLVP,NOCPD,NODEBUG,NOWRT,NOVREGEN
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

int1 flanco=0;
int buffer;
char rec=0x00;

byte dato1;
byte dato2;
byte dato3;

// INTERRUPCION por RECEPCION SERIE -------------------------------------------

#int_rda
void serial_isr() {

   if(kbhit()){
     rec=getc();
     if(rec=='R'){ buffer=1; }
     if(rec=='C'){ buffer=2; }
    if(rec=='T'){ buffer=3; }
     } 

 switch(buffer)
            {
               case 1:     
               {
            printf("Lectura del dato1 \r\n\n");
               do {
               if(kbhit()){
                  dato1=getc();   
              }   
               }
            while (TRUE);    
                break;
         }
               case 2:       
               {
                printf("Lectura del dato2 \r\n\n");
               do {
               if(kbhit()){
                  dato2=getc();   
              }   
            }
            while (TRUE);    
                break;
          }

               case 3:       
               {
                printf("Lectura del dato3 \r\n\n");
               do {
               if(kbhit()){
                  dato3=getc();   
              }   
              }
            while (TRUE);    
                break;
            }
       }
}


void main() {

   enable_interrupts(global);
   enable_interrupts(int_rda);
   set_tris_b(0b00000111);

 while (TRUE);
  {
//
 }
 }

Desconectado omix

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 244
Re: Ingreso de datos por teclado
« Respuesta #1 en: 22 de Enero de 2008, 21:17:48 »
Hola Medusa,
yo no lo haria tal como lo tienes, en la interrupción conviene meter solamente el minimo código posible para manejarla, ya que si la sobrecargas puedes obtener resultados no deseados en la ejecución. Yo lo haria de la siguiente forma:

Código: C
  1. char buffer[16];
  2. unsigned int8 head;  //Indice para introducir datos en el buffer
  3. unsigned int8 tail;    //indice para sacar datos del buffer
  4.  
  5. #int_rda
  6. void serial_isr() {
  7.         head = (head + 1) % 16;
  8.         buffer[head] = getc();
  9.        
  10. }
  11.  
  12. int8 Usart_RxEmpty(){
  13.         return(head == tail);
  14. }  
  15.  
  16. char Usart_Get(){
  17.         tail = (tail + 1) % 16;
  18.         return buffer[tail];
  19.        
  20. }
  21.  
  22. void main(){
  23.  
  24.         char c;
  25.  
  26.             //Configuración del pic y perifericos
  27.             ...
  28.  
  29.             head = 0;
  30.             tail = 0;
  31.  
  32.         while(true){    //aqui iria la rutina de procesamiento de los datos recibidos de la usart
  33.                 if(!Usart_RxEmpty()){   //si el buffer de recepción no está vacío leemos un byte
  34.                         c = Usart_Get(); //obtenemos un byte (caracter) del buffer de recepción
  35.  
  36.                         switch(c){                     
  37.                                 case 'R': break; //añadir el código para procesar los datos
  38.                                 case 'C': break;
  39.                                 case 'T': break;
  40.  
  41.                         }      
  42.  
  43.                 }
  44.  
  45.         }
  46. }

Un saludo.

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re: Ingreso de datos por teclado
« Respuesta #2 en: 23 de Enero de 2008, 02:15:45 »
Hola Omix, gracias por tu ayuda, lo que pretendo es que el pic este en un lazo y que cuando se produce una interupcion por el RB0, el pic envie un mensaje por el hiperterminal indicando que se lecciones cualquiera de las tres opciones (R,C,T) que corresponden a dato1, dato2 y dato3, al seleccionar la opcion el pic pueda recibir 2 digitos los guarde en su respectivo buffer y lo muestre por pantalla como siguie:


Selecciona el dato a Ingresar:

R - Ingresar Dato1
C - Ingresar Dato2
T - Ingresar Dato3

Seleccionar:_

Por ejemplo si se selecciona R

Debe de aparecer el mensaje:

Ingresar Dato1 (0-99):_
Y cuando se intruce el numero debe de aparece el sigte mensaje con dato introducido
El Dato1 es:
 

Este es mi codigo pero ya no se como seguir..

Código: [Seleccionar]
#include <16F877.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#int_EXT
EXT_isr(){
    disable_interrupts(int_EXT);
    printf("Selecciona el dato a Ingresar: \r\n");
    printf("R Ingresar Dato1: \r\n");
    printf("C Ingresar Dato2: \r\n");
    printf("T Ingresar Dato3: \r\r\n");
    printf("Seleccionar: ");

#int_rda
void serial_isr() {
     if(kbhit()){
     rec=getc();
.
.
.
.
.
.

    enable_interrupts(int_EXT);
}

void main(){

set_tris_b(0b00000000);
enable_interrupts(int_rda);
enable_interrupts(global);
ext_int_edge (L_TO_H); //interrupcion externa al pasar de 1 a 0
enable_interrupts(INT_EXT); //interrupcion externa RB0

printf("Esto es una Prueba \r\n");

while(true){
}
//..
}


Desconectado omix

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 244
Re: Ingreso de datos por teclado
« Respuesta #3 en: 23 de Enero de 2008, 19:42:46 »
Hola de nuevo,  en base a lo que me comentas he escrito un pequeño ejemplo de como lo haria yo, pruebalo y me cuentas que tal te va.

Código: C
  1. #include <16F877A.h>
  2. #fuses HS,NOWDT,NOPROTECT,NOLVP
  3. #use delay(clock=20000000)
  4. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  5.  
  6. char buffer[16];
  7. unsigned int8 head;  //Indice para introducir datos en el buffer
  8. unsigned int8 tail;    //indice para sacar datos del buffer
  9. char EstadoAutomata = 'I';         //I = Espera INT en RB0, S = Seleccion dato, R = Ingresar dato 1, C = ...  
  10.  
  11. #int_ext
  12. void ext_isr(){
  13.     disable_interrupts(INT_EXT);
  14.     printf("Selecciona el dato a Ingresar: \r\n");
  15.     printf("R Ingresar Dato1: \r\n");
  16.     printf("C Ingresar Dato2: \r\n");
  17.     printf("T Ingresar Dato3: \r\n");
  18.     printf("Seleccionar: ");
  19.     EstadoAutomata = 'S';
  20. }
  21.  
  22. #int_rda
  23. void serial_isr() {
  24.    head = (head + 1) % 16;
  25.    buffer[head] = getc();
  26. }
  27.  
  28.  
  29. int8 Usart_RxEmpty(){
  30.  
  31.    return(head == tail);
  32.  
  33. }
  34.  
  35. char Usart_Get(){
  36.  
  37.    tail = (tail + 1) % 16;
  38.  
  39.    return buffer[tail];
  40. }
  41.  
  42. void main(){
  43.  
  44.    char c;
  45.    int8 dato1;
  46.    unsigned int8 EstadoLectura = 0; //0 = leyendo primer digito, 1 = leyendo 2 digito
  47.    
  48.    
  49.    set_tris_b(0b00000001);
  50.    enable_interrupts(int_rda);
  51.    enable_interrupts(global);
  52.    ext_int_edge (H_TO_L); //interrupcion externa al pasar de 1 a 0
  53.    enable_interrupts(INT_EXT); //interrupcion externa RB0
  54.  
  55.    printf("Esto es una Prueba \r\n");
  56.  
  57.  
  58.    head = 0;
  59.    tail = 0;
  60.  
  61.    while(1){    
  62.       switch(EstadoAutomata){
  63.          case 'I':            
  64.             break;
  65.          case 'S':
  66.             if(!Usart_RxEmpty()){ //si el buffer de recepción no está vacío leemos un byte
  67.                c = Usart_Get(); //obtenemos un byte (caracter) del buffer de recepción
  68.                switch(c){
  69.                   case 'R':
  70.                      dato1 = 0;
  71.                      EstadoAutomata = 'R';
  72.                      printf("R Ingresar Dato1 (0-99): \r\n");  
  73.                      EstadoLectura = 0;   //pasamos al primer estado del miniautomata que lee dos digitos numericos de la usart
  74.                      break;
  75.                   case 'C': EstadoAutomata = 'C'; break;
  76.                   case 'T': EstadoAutomata = 'T'; break;
  77.                }
  78.             }break;
  79.          case 'R':            
  80.             switch(EstadoLectura){
  81.                case 0:
  82.                   if(!Usart_RxEmpty()){
  83.                      c = Usart_Get();
  84.                      if((c >= '0')&&(c <= '9')){
  85.                         dato1 = c - 48; //convierte a entero
  86.                         EstadoLectura++; //pasamos a leer el siguiente digito
  87.                      }
  88.                   }break;
  89.                case 1:
  90.                   if(!Usart_RxEmpty()){
  91.                      c = Usart_Get();
  92.                      if((c >= '0')&&(c <= '9')){
  93.                         dato1 = ((dato1*10) + (c - 48)); //convierte a entero
  94.                         EstadoLectura++; //pasamos a leer el siguiente digito
  95.                         printf("Dato leido: %d\r\n", dato1);
  96.                         EstadoAutomata = 'I'; //volvemos al estado de reposo
  97.                         enable_interrupts(INT_EXT);
  98.                      }
  99.                   }break;
  100.             }break;
  101.          case 'C': break;        
  102.          case 'T': break;                    
  103.       }
  104.    }
  105. }

Un saludo.

Desconectado Medusa

  • PIC18
  • ****
  • Mensajes: 252
Re: Ingreso de datos por teclado
« Respuesta #4 en: 28 de Enero de 2008, 17:52:50 »
Hola Omix,  :-/

Muchas gracias por tu ayuda, tu ejemplo me ha servido de mucho.. saludos...