TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: cheapekt en 22 de Octubre de 2008, 12:14:22

Título: problema al recibir datos rs232
Publicado por: cheapekt en 22 de Octubre de 2008, 12:14:22
Muy buenas amigos, En este programa grabo unos cuantos datos en una eeprom 24lc512 desde un pic 16f877, el problema está en que cuando el PIC pasa los datos al PC a la hora de recibirlos me llegan unos caracteres raros como estos:
i t:„? Ÿ  ­8„? Ÿ i æ8„? Ÿ  æ8„? Ÿ  æ:„? Ÿ  T8„? Ÿ  T8„? Ÿ  T:„? Ÿ  ‹8„? Ÿ  ‹8„?
Ÿ  ‹:„? Ÿ i :„? Ÿ  Ö8„? Ÿ i 8„? Ÿ  8„? Ÿ  :„? Ÿ  }8„? Ÿ  }8„? Ÿ  }:„? Ÿ  ´8„
? Ÿ  ´8„? Ÿ  ´:„? Ÿ 

En lugar de esas "cifras" me tendrian que llegar numeros 3 digitos int y  unos 20 datos float.
EL programa en cuestión es este, si alguien sabe el motivo por el cual no me llegan los datos correctos os lo agradeceria mucho

Cuando grabo los datos int sumo uno al contado de dirección al igual de cuando los leo, y cuando grabo los datos float sumo 4 bytes al contador al igual de cuando los leo.

No encuentro el error... muchas gracias de antemano

Código: [Seleccionar]
#include <16F877.h> // Se añade la libreria del PIC a utilizar
#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)      //Velocidad del reloj

#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación

//Configuramos los PINS C3 Y C4 para controlar la EEPROM

#define EEPROM_SDA PIN_C4   // pero si estos defines deben estar antes de la libreria external_eeprom.c que usaras
#define EEPROM_SCL PIN_C3   // en una de las librerias esta la directiva #use i2c(...) esa libreria tendrá que estar escrita antes de la otra

#include <24512.c> // Se añade la libreria de la EEPROM 24LC512
#include <external_eeprom.c> // Se añade la libreria para controlar una EPROM externa
////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///
///                                                                              ///   
///                           PROGRAMA PRINCIPAL                                 ///
///                                                                              ///
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
void main(void) // Inicio del programa principal
{

///////////////////////////////////////////////////////////////////////////////////
///                              ///                                 
///            DECLARACIÓN DE LAS VARIABLES E INICIALIZACION DE ÉSTAS           ///                             
///                              ///
///////////////////////////////////////////////////////////////////////////////////
//Variables float que contienen datos de las tablas

   float irra[]    = {1, 2, 3, 6};
   float tempa[]    = {6, 3, 2, 1};
   float tempm[]    = {2, 4, 5, 6};
   float vel[]    = {2, 4, 5, 6};
   float volt[]    = {2, 4, 5, 6};
   float inte[]    = {2, 4, 5, 6};

//Variables int que contienten el valor de la fecha
   int min,sec,hr;

//Inicialización de las variables necesarias para movernos por la EEPROM
   int dir=0,dir2=0,i=0;

//Iniciaización variables para necesarias para moverse dentro de los datos
   int f=0,g=0,h=0,v=0,j=0,k=0;
   float dato=0,dato2=0;
   min=0;
   sec=0;
   hr=0;

////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///                                 
///        GUARDAR DATOS EN EEPROM EXTERNA Y INICIALIZAR CONTAJE RELOJ           ///                             
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////

   init_ext_eeprom(); // Inicializamos EEPROM EXTERNA
   delay_ms(500);// retraso 200 milisegundos para no colapsar PIC

   write_ext_eeprom(dir,hr); // Escribimos la hora en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM
delay_ms(500);// retraso 200 milisegundos para no colapsar PIC
   write_ext_eeprom(dir,min); // Escribimos los minutos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM
delay_ms(500);// retraso 200 milisegundos para no colapsar PIC
   write_ext_eeprom(dir,sec); // Escribimos los segundos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM
delay_ms(500);// retraso 200 milisegundos para no colapsar PIC
      delay_ms(500);
      for (f=0; f<4; f++){ // Escribimos las irradiancias en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, irra[f]);
         delay_ms(500);     
         dir=dir+4;
      }
      f=0;

      for (g=0; g<4; g++){// Escribimos las temperaturas ambientes en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempa[g]);
         delay_ms(500);     
         dir=dir+4;
      }
      g=0;

      for (h=0; h<4; h++){// Escribimos las temperaturas en la placa en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempm[h]);
         delay_ms(500);     
         dir=dir+4;
      }
      h=0;

      for (i=0; i<4; i++){// Escribimos las velocidades del viento en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, vel[v]);
         delay_ms(500);
         dir=dir+4;
      }

      v=0;
      for (j=0;j<4;j++){// Escribimos los voltios en la EEPROM EXTERNA
        write_float_ext_eeprom(dir, volt[j]);
        delay_ms(500);   
         dir=dir+4;
      }
      j=0;

      for (k=0;k<4;k++){// Escribimos las intensidades en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, inte[k]);
         delay_ms(500);   
         dir=dir+4;
      }
      k=0;

   dato=read_ext_eeprom(dir2); // Leemos la hora en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf(dato);// Enviamos dato a ordenador
   delay_ms(500);

   dato=read_ext_eeprom(dir2); // Leemos los minutos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf(dato);// Enviamos dato a ordenador
   delay_ms(500);

   dato=read_ext_eeprom(dir2); // Leemos los segundos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf(dato);// Enviamos dato a ordenador
   delay_ms(500);


      delay_ms(200);
      for (f=0; f<4; f++){ // Leemos las irradiancias de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);     
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }
      for (g=0; g<4; g++){// Leemos las temperaturas ambientes en la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);     
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }     
      for (h=0; h<4; h++){// Leemos las temperaturas en la placa de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);     
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }
      for (i=0; i<4; i++){// Leemos las velocidades del viento de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }
      for (j=0;j<4;j++){// Leemos los voltios de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);   
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }
      for (k=0;k<4;k++){// Leemos las intensidades de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(500);   
         dir2=dir2+4;
         printf(dato2);// Enviamos dato a ordenador
      }

   do{
   delay_ms(500);                  // espera por ejemplo 0,5 seg para enviar nuevamente el dato,
   output_HIGH(PIN_B1);        // por ejemplo conectas un led entre el pin B1 y masa y este debe prender
   delay_ms(250);                  // espera por ejemplo 0,25 seg
   output_LOW(PIN_B1);         // se apaga el led
   delay_ms(250);                  // esperas otros 0,25 seg para enviar nuevamente el dato,
   }while(TRUE);
}



Un saludo amigos!
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 22 de Octubre de 2008, 13:46:44
Siento haberos hecho perder el tiempo.... la solucion era tan facil como en las sentencias printf(%u,....) era indicar el tipo de dato que contenía!!! gracias =mente...... es un placer pertenecer a este foro..... GRACIAS INFINITAS A TODOS LOS QUE AYUDAIS  a lso novatillos como yo!!!!!1

Muchas gracias!!!!!!
Título: Re: problema al recibir datos rs232
Publicado por: maunix en 22 de Octubre de 2008, 16:20:03
Siento haberos hecho perder el tiempo.... la solucion era tan facil como en las sentencias printf(%u,....) era indicar el tipo de dato que contenía!!! gracias =mente...... es un placer pertenecer a este foro..... GRACIAS INFINITAS A TODOS LOS QUE AYUDAIS  a lso novatillos como yo!!!!!1

Muchas gracias!!!!!!

Te estaba por responder y me dio error la página, justamente te decía que el problema podría venir por ahí, pero el foro me daba error todo el tiempo que quería acceder.
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 23 de Octubre de 2008, 08:08:45
Muchisimas gracias maunix;

Este mismo programa quiero que lo realice cuando el PC envie un dato al PIC y a ete le salte una interrupción, pero tengo un problema y es que el PIC interpreta que mientras no envia tiene el puerto abierto como si estuviese recibiendo... y entonces al ejecutar este código creo que continuamente me salta la interrupción, como puedo arreglarlo para que tan solo envie datos cuando el PC envia la señal para que este los envie aquí os dejo el código. UN saludo a todos!!!
Código: [Seleccionar]
#include <16F877.h> // Se añade la libreria del PIC a utilizar

#device adc=8 // Escogemos una resolucion del conversor de 8 bits

#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)      //Velocidad del reloj

#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación

//Configuramos los PINS C3 Y C4 para controlar la EEPROM

#define EEPROM_SDA PIN_C4   
#define EEPROM_SCL PIN_C3 

#include <24512.c> // Se añade la libreria de la EEPROM 24LC512
#include <external_eeprom.c> // Se añade la libreria para controlar una EPROM externa
//#include <ds1302.c> // Se añade la libreria del RTC al proyecto
//Interrupción probocada por el PC para volcar datos
#int_rda
void serial_isr(){
///////////////////////////////////////////////////////////////////////////////////
///                                                                             ///                                 
///            LECTURA DE DATOS EN LA EEPROM Y ENVIAR AL PC                     ///                             
///                                                                             ///
///////////////////////////////////////////////////////////////////////////////////
   int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
   float dato2=0;
 
   dato=read_ext_eeprom(dir2); // Leemos la hora en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los minutos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los segundos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);


      delay_ms(200);
      for (f=0; f<4; f++){ // Leemos las irradiancias de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (g=0; g<4; g++){// Leemos las temperaturas ambientes en la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }     
      for (h=0; h<4; h++){// Leemos las temperaturas en la placa de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (i=0; i<4; i++){// Leemos las velocidades del viento de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (j=0;j<4;j++){// Leemos los voltios de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (k=0;k<4;k++){// Leemos las intensidades de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
}
////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///
///                                                                              ///   
///                           PROGRAMA PRINCIPAL                                 ///
///                                                                              ///
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
void main(void) // Inicio del programa principal
{

///////////////////////////////////////////////////////////////////////////////////
///                              ///                                 
///            DECLARACIÓN DE LAS VARIABLES E INICIALIZACION DE ÉSTAS           ///                             
///                              ///
///////////////////////////////////////////////////////////////////////////////////
//Variables float que contienen datos de las tablas

   float irra[]    = {1, 2, 3, 6};
   float tempa[]    = {6, 3, 2, 1};
   float tempm[]    = {2, 4, 5, 6};
   float vel[]    = {2, 4, 5, 6};
   float volt[]    = {2, 4, 5, 6};
   float inte[]    = {2, 4, 5, 6};

//Variables int que contienten el valor de la fecha
   int min,sec,hr;

//Inicialización de las variables necesarias para movernos por la EEPROM
   int dir=0;

//Iniciaización variables para necesarias para moverse dentro de los datos
   int f=0,g=0,h=0,i=0,j=0,k=0;

   min=0;
   sec=0;
   hr=0;
setup_adc_ports (A_ANALOG_RA3_REF);

setup_adc(ADC_CLOCK_INTERNAL);
////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///                                 
///        GUARDAR DATOS EN EEPROM EXTERNA Y INICIALIZAR CONTAJE RELOJ           ///                             
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
   
   init_ext_eeprom(); // Inicializamos EEPROM EXTERNA
   //rtc_init(); // Inicializamos el Real Time Clock
   delay_ms(200);// retraso 200 milisegundos para no colapsar PIC
   
   
   //rtc_get_time(hr,min,sec); //Guardamos la hora, minuto y segundo que nos da el RTC
   write_ext_eeprom(dir,hr); // Escribimos la hora en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

   write_ext_eeprom(dir,min); // Escribimos los minutos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

   write_ext_eeprom(dir,sec); // Escribimos los segundos en la EEPROM
   dir=dir+1; // Incrementamos el puntero de la EEPROM

      delay_ms(200);
      for (f=0; f<4; f++){ // Escribimos las irradiancias en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, irra[f]);
         delay_ms(200);     
         dir=dir+4;
      }
      f=0;

      for (g=0; g<4; g++){// Escribimos las temperaturas ambientes en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempa[g]);
         delay_ms(200);     
         dir=dir+4;
      }
      g=0;

      for (h=0; h<4; h++){// Escribimos las temperaturas en la placa en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, tempm[h]);
         delay_ms(200);     
         dir=dir+4;
      }
      h=0;

      for (i=0; i<4; i++){// Escribimos las velocidades del viento en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, vel[i]);
         delay_ms(200);
         dir=dir+4;
      }

      i=0;
      for (j=0;j<4;j++){// Escribimos los voltios en la EEPROM EXTERNA
        write_float_ext_eeprom(dir, volt[j]);
        delay_ms(200);   
         dir=dir+4;
      }
      j=0;

      for (k=0;k<4;k++){// Escribimos las intensidades en la EEPROM EXTERNA
         write_float_ext_eeprom(dir, inte[k]);
         delay_ms(200);   
         dir=dir+4;
      }
      k=0;
            enable_interrupts(global);
      enable_interrupts(int_rda);
   do{
   delay_ms(500);                  // espera por ejemplo 0,5 seg para enviar nuevamente el dato,
   output_HIGH(PIN_B1);        // por ejemplo conectas un led entre el pin B1 y masa y este debe prender
   delay_ms(250);                  // espera por ejemplo 0,25 seg
   output_LOW(PIN_B1);         // se apaga el led
   delay_ms(250);                  // esperas otros 0,25 seg para enviar nuevamente el dato,
   }while(TRUE);

}


Gracias de antemano!!!!!!!
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 23 de Octubre de 2008, 08:56:21
He pensado en poner que para que salte la interrupción el PIC reciba algun dato en concreto por ejemplo "hola", eso es posible realizarlo, así dará igual que siempre el PIC este recibiendo datos, ya que tan solo saltará la interrupción cuando reciba el dato en conctreto,

Muchas gracias de antemano!!!
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 23 de Octubre de 2008, 09:31:55
He estado haciendo pruebas para que la interrupción no salga continuamente, viendo ejemplos del foro la última prueba que he realizado ha sido en la interrupción añadir esta aprte de código
Código: [Seleccionar]
#int_rda
void serial_isr(){

///////////////////////////////////////////////////////////////////////////////////
///                                                                             ///                                 
///            LECTURA DE DATOS EN LA EEPROM Y ENVIAR AL PC                     ///                             
///                                                                             ///
///////////////////////////////////////////////////////////////////////////////////
   int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
   float dato2=0;

   if(kbhit()){
      getc();
      printf(" Interrupcion ");
     
   
   dato=read_ext_eeprom(dir2); // Leemos la hora en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los minutos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los segundos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);


      delay_ms(200);
      for (f=0; f<4; f++){ // Leemos las irradiancias de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (g=0; g<4; g++){// Leemos las temperaturas ambientes en la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }     
      for (h=0; h<4; h++){// Leemos las temperaturas en la placa de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (i=0; i<4; i++){// Leemos las velocidades del viento de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (j=0;j<4;j++){// Leemos los voltios de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (k=0;k<4;k++){// Leemos las intensidades de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
   }
}

Pero Igualmente salta la interrupción continuamente y en el hiperterminal me sale el siguienet texto continuamente:

Interrupcion 0001.002.003.006.006.003.002.001.002.004.005.006.002.004.005.006.0
02.004.005.006.002.004.005.006.00 Interrupcion 0001.002.003.006.006.003.002.001.
002.004.005.006.002.004.005.006.002.004.005.006.002.004.005.006.00 Interrupcion
0001.002.003.006.006.003.002.001.002.004.005.006.002.004.005.006.002.004.005.006
.002.004.005.006.00 Interrupcion 0001.002.003.006.006.003.002.001.002.004.005.00
6.002.004.005.006.002.004.005.006.002.004.005.006.00 Interrupcion

Es decir, entiendo que la interrupción salta continuamente sin parar.

Gracias!!!! Un saludo!!!
Título: Re: problema al recibir datos rs232
Publicado por: maunix en 24 de Octubre de 2008, 11:33:31
Esperate antes de ver el código explicame bien qué quieres hacer, cómo quieres o desearias que sea la secuencia de eventos, quién iniciará la comunicación, etc.

Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 24 de Octubre de 2008, 14:06:21
lo que quiero es grabar los datos en el pic primero sin necesidad de que se ejecute ninguna interrupcion, luego enviar a traves del PC cualquier dato por ejemplo "start", y que se active la interrupcion en el pic para que este lea los datos en la memoria eeprom y los envie al PC.

EL problema que tal y como esta puesto la interrupcion se ejecuta continuamente.

Muchas gracias!!!
Título: Re: problema al recibir datos rs232
Publicado por: Giovanny en 24 de Octubre de 2008, 18:34:24
lo que puedes hacer es un buffer de almacenamiento de las lectura de datos,
dentro de la interrupcion de recepcion serial #int_rda.
y tener dos diferentes datos de 'start'. Uno para iniciar a grabar datos.  y otro para 'start' de eeprom.
y usar la interrupcion solamente para grabar en el/los buffer , y en realidad  los procesas en el main.

tambien podrias usar un ciclo de getc() en el main, y  al recibir un dato en particular, habilitar
la interrupcion rda.

en fin. nos cuentas el progreso!

saludos. :lol:
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 25 de Octubre de 2008, 11:09:35
Buenas !!!

Citar
tambien podrias usar un ciclo de getc() en el main, y  al recibir un dato en particular, habilitar
la interrupcion rda.

Esa opcion creo que es la mas adecuada!!!!

¿EL getc() que lo pongo delante de?  enable_interrupts(global);
                                                          enable_interrupts(int_rda);

No se donde lo tengo que colocar. ALGUIEN ME PUEDE ECHAR UNA MANO!!!

GRACIAS!!!!!
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 27 de Octubre de 2008, 09:32:25
He estado probando códigos para ver que los datos tan solo pasen al PC cuando este envie alguna señal al PIC,....

Pero la interrupción salta cnstantemente... este es un codigo que he probado.... si alguien me peude ayudar se lo agradezo enormemente!!!!!
Código: [Seleccionar]
#int_rda
void serial_isr(){

///////////////////////////////////////////////////////////////////////////////////
///                                                                             ///                                 
///            LECTURA DE DATOS EN LA EEPROM Y ENVIAR AL PC                     ///                             
///                                                                             ///
///////////////////////////////////////////////////////////////////////////////////
   int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
   float dato2=0;
   char answer;

answer=getch();
    if(answer='Y'){
    printf(" Interrupcion ");
     
   
   dato=read_ext_eeprom(dir2); // Leemos la hora en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los minutos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);

   dato=read_ext_eeprom(dir2); // Leemos los segundos en la EEPROM
   dir2=dir2+1; // Incrementamos el puntero de la EEPROM
   printf("%u",dato);// Enviamos dato a ordenador
   delay_ms(200);


      delay_ms(200);
      for (f=0; f<4; f++){ // Leemos las irradiancias de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (g=0; g<4; g++){// Leemos las temperaturas ambientes en la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }     
      for (h=0; h<4; h++){// Leemos las temperaturas en la placa de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);     
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (i=0; i<4; i++){// Leemos las velocidades del viento de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (j=0;j<4;j++){// Leemos los voltios de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
      for (k=0;k<4;k++){// Leemos las intensidades de la EEPROM EXTERNA
         dato2= read_float_ext_eeprom(dir2);
         delay_ms(200);   
         dir2=dir2+4;
         printf("%f",dato2);// Enviamos dato a ordenador
      }
   }
}

Gracias!
Título: Re: problema al recibir datos rs232
Publicado por: ema en 27 de Octubre de 2008, 11:30:27
Si desactivas la interrupción funcionara correctamente.

Quedaria asi.

#int_rda
void serial_isr(){

        // lo que estaba aca lo borre para que no sea tan largo

        disable_interrupts(int_rda);//Aqui deshabilito la interrupción
   answer=getch();
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 27 de Octubre de 2008, 12:06:50
Muchisimas gracias ema, lo pruebo y comento!!!!!!! un placer!!!!!11

Saludos amigos!!!
Título: Re: problema al recibir datos rs232
Publicado por: gera en 27 de Octubre de 2008, 12:11:10
tambien seria bueno volver a habilitar la interrupcion al final de la rutina si queres seguir recibiendo datos.
saludos!!!
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 28 de Octubre de 2008, 14:38:12
Buenas he probado el siguiente código y se me ejecuta la interrupción sin necesidad de enviar nada desde el PC, y despues no se vuelve a ejecutar aunque envie el cáracter 'Y' desde el PC. El código abreviado es el siguiente:
Código: [Seleccionar]
#include <16F877.h> // Se añade la libreria del PIC a utilizar

#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)      //Velocidad del reloj

#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación


#include <24512.c> // Se añade la libreria de la EEPROM 24LC512
#include <external_eeprom.c> // Se añade la libreria para controlar una EPROM externa
//#include <ds1302.c> // Se añade la libreria del RTC al proyecto
//Interrupción probocada por el PC para volcar datos
#int_rda
void serial_isr(){

///////////////////////////////////////////////////////////////////////////////////
///                                                                                                ///                                 
///            LECTURA DE DATOS EN LA EEPROM Y ENVIAR AL PC        ///                             
///                                                                                                ///
///////////////////////////////////////////////////////////////////////////////////
      int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
      float dato2=0;
      char answer;
     disable_interrupts(int_rda);//Aqui deshabilito la interrupción
     answer=getch();
     if(answer='Y'){
     printf(" Interrupcion ");
     
   //Leo datos de eeprom y envio al PC
   
   }
}
////////////////////////////////////////////////////////////////////////////////////
///                                                                                                   ///
///                                                                                                   ///   
///                           PROGRAMA PRINCIPAL                                      ///
///                                                                                                  ///
///                                                                                                  ///
////////////////////////////////////////////////////////////////////////////////////
void main(void) // Inicio del programa principal
{

///////////////////////////////////////////////////////////////////////////////////
///                                                                                                  ///                                 
///DECLARACIÓN DE LAS VARIABLES E INICIALIZACION DE ÉSTAS           ///                             
///                              ///
///////////////////////////////////////////////////////////////////////////////////
//Variables float que contienen datos de las tablas

   float irra[]    = {1, 2, 3, 6};
   float tempa[]    = {6, 3, 2, 1};
   float tempm[]    = {2, 4, 5, 6};
   float vel[]    = {2, 4, 5, 6};
   float volt[]    = {2, 4, 5, 6};
   float inte[]    = {2, 4, 5, 6};

//Variables int que contienten el valor de la fecha
   int min,sec,hr;

//Inicialización de las variables necesarias para movernos por la EEPROM
   int dir=0;

//Iniciaización variables para necesarias para moverse dentro de los datos
   int f=0,g=0,h=0,i=0,j=0,k=0;

   min=0;
   sec=0;
   hr=0;

////////////////////////////////////////////////////////////////////////////////////
///                                                                              ///                                 
///        GUARDAR DATOS EN EEPROM EXTERNA Y INICIALIZAR CONTAJE RELOJ           ///                             
///                                                                              ///
////////////////////////////////////////////////////////////////////////////////////
   
   init_ext_eeprom(); // Inicializamos EEPROM EXTERNA
   
   delay_ms(200);// retraso 200 milisegundos para no colapsar PIC
   
   
   
   // Escribimos datos en la eeprom

            enable_interrupts(global);
            enable_interrupts(int_rda);
   do{
   delay_ms(500);                  // espera por ejemplo 0,5 seg para enviar nuevamente el dato,
   output_HIGH(PIN_B1);        // por ejemplo conectas un led entre el pin B1 y masa y este debe prender
   delay_ms(250);                  // espera por ejemplo 0,25 seg
   output_LOW(PIN_B1);         // se apaga el led
   delay_ms(250);                  // esperas otros 0,25 seg para enviar nuevamente el dato,
   }while(TRUE);

}

¿Sabéis porqué motivo sucede?

Gracias un saludo
Título: Re: problema al recibir datos rs232
Publicado por: ema en 28 de Octubre de 2008, 17:02:46
Prueba con esto

Código: [Seleccionar]
#include <16F877.h> // Se añade la libreria del PIC a utilizar
#FUSES NOWDT,HS,NOPUT,PROTECT,NOBROWNOUT,NOLVP,NOCPD,NOWRT,NODEBUG
#use delay(clock=20000000)      //Velocidad del reloj

#use rs232(baud=9600,parity=N,bits=8,stop=1,xmit=PIN_C6,rcv=PIN_C7,enable=PIN_C5,errors) //enable=PIN_C5 hace que el C maneje el pin de habilitación


#include <24512.c> // Se añade la libreria de la EEPROM 24LC512
#include <external_eeprom.c> // Se añade la libreria para controlar una EPROM externa

#int_rda
void serial_isr(){


      int dato=0,dir2=0,i=0,f=0,g=0,h=0,j=0,k=0;
      float dato2=0;
      char answer;
     disable_interrupts(int_rda);//Aqui deshabilito la interrupción
     answer=getch();
     if(answer='Y'){
     printf(" Interrupcion ");
     
   //Leo datos de eeprom y envio al PC
   
   }
}


void main(void) // Inicio del programa principal
{

   float irra[]    = {1, 2, 3, 6};
   float tempa[]    = {6, 3, 2, 1};
   float tempm[]    = {2, 4, 5, 6};
   float vel[]    = {2, 4, 5, 6};
   float volt[]    = {2, 4, 5, 6};
   float inte[]    = {2, 4, 5, 6};

//Variables int que contienten el valor de la fecha
   int min,sec,hr;

//Inicialización de las variables necesarias para movernos por la EEPROM
   int dir=0;

//Iniciaización variables para necesarias para moverse dentro de los datos
   int f=0,g=0,h=0,i=0,j=0,k=0;

   min=0;
   sec=0;
   hr=0;

   init_ext_eeprom(); // Inicializamos EEPROM EXTERNA
   
   delay_ms(200);// retraso 200 milisegundos para no colapsar PIC
   
   
   
   // Escribimos datos en la eeprom

   do{

            enable_interrupts(int_rda);
            enable_interrupts(global);

   delay_ms(500);                  // espera por ejemplo 0,5 seg para enviar nuevamente el dato,
   output_HIGH(PIN_B1);        // por ejemplo conectas un led entre el pin B1 y masa y este debe prender
   delay_ms(250);                  // espera por ejemplo 0,25 seg
   output_LOW(PIN_B1);         // se apaga el led
   delay_ms(250);                  // esperas otros 0,25 seg para enviar nuevamente el dato,
   }while(TRUE);

}
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 29 de Octubre de 2008, 09:05:40
Gracias ema por la opción, pero ahora el programa hace, que la interrupción se ejecute constantemente,  El programa lo que ahce es graba los datos en la memoria y luego ejecuta el while y constantemente envia datos al PC sin encesidad de que este le envie ninguna señal, alguien puede decirme como solucionar esto?

Muchas gracias amigos
Título: Re: problema al recibir datos rs232
Publicado por: cheapekt en 31 de Octubre de 2008, 09:04:31
Mirando la pagina de RedRaven, he visto que al utilizar la transmision de datos por rs232 hace una interrupcion tal que asi:
char Keypress=' ';

#int_rda
void serial_isr() {

  Keypress=0x00;
  if(kbhit()){
    Keypress=getc();
    if(Keypress!=0x00){
      putchar(keypress);
      keypress=0x00;
         ###3 codigo a ejecutar
    }
  }
}

Entiendo que  si yo pongo mi codigo debajo de keypress=0x00;  tansolo se ejecutara lo que hay debajo cuando a putchar le llegue algo que no es 00 pero como constantemente en mi programa esta en estado de recibir, saltara la interrupcion constantemente, alguien me puede ayudar porfavor.

Un saludo
Título: Re: problema al recibir datos rs232
Publicado por: Giovanny en 31 de Octubre de 2008, 17:20:29
 :shock: :? el problema no es que la interrupcion se este ejecutando constantemente, eso es normal(siempre y cuando no la desactives) ... el problema que veo es que tienes todo el codigo dentro de la interrupcion y no en el main.
y no solo eso. tambien veo que dentro de la interrupcion pones printf("%u",dato); y delay_ms(200); varias veces...  :mrgreen:

preguntate ¿cuantos datos transmitidos por puerto serie, podrias recibir durante ese tiempo?... seguramente vas a resultar perdiendo informacion.

... he hecho un pequeño programa que funciona asi.
 + dentro de la interrupcion almacena lo que recibe en un buffer siempre y cuando no llegue un enter(\n \r)
 + cuando llega un enter(\n \r)pone null en el buffer y sube una bandera de recepcion de mensaje.
 + tiene una rutina para comparar el buffer de datos recibidos con 3 buffers almacenados en el pic, usando la funcion
    strcmp de la librea string.h
 + en el main, pregunta por la bandera de recepcion de mensaje. cuando esta activa,
    1. desactiva temporalmente la interrupcion rda.
    2. llama la rutina de comparacion.
    3. de acuerdo al resultado de la misma, cambia la salida del puerto a
    4. baja la bandera de recepcion de mensaje
    5. activa nuevamente la interrupcion rda
 :-/  :-/
Cheapekt, espero te sirva como guia para usar 'mejor' (a mi modo de ver) la interrupcion.

Código: [Seleccionar]
///////////////////////////////////////////////////////
//   Prueba de Recepcion de Cadenas Por puerto Serial
//   usando interrupcion #int_rda y un buffer[]
//   Hecho por Giovanny para Todopic
///////////////////////////////////////////////////////
#include   <16f627A.h>
#fuses INTRC,NOWDT,NOPROTECT,NOLVP,NOMCLR
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)

#include <string.h>

typedef unsigned char uchar;

#define BUFFER_MAX_LENGHT 20

unsigned char cont=0;
unsigned char data;
unsigned char buffer[BUFFER_MAX_LENGHT];
unsigned char *s1 = "OK";
unsigned char *s2 = "HOLA";
unsigned char *s3 = "MUNDO";

int1 smsOk = FALSE;

unsigned char cmp_result;

#int_rda
void serialInterrupt (){

   data=getc();
   if (data!=0X0D && data!=0X0A){//datos diferentes de ("\n" y "\r") enter
       buffer[cont]=data;
   }
   else if (data==0X0D) {
       buffer[cont]='\0';
   }
   else { // \r   if (data==0X0A)
      smsOk=TRUE;
      cont=-1;
      disable_interrupts(int_rda);
   }
   cont++;
}//
uchar compare_buffer(){
   if(strcmp(s1,&buffer[0])==0)return 1;
   else if(strcmp(s2,&buffer[0])==0)return 2;
   else if(strcmp(s3,&buffer[0])==0)return 3;
   
}//
void main ( ) {

   enable_interrupts(int_rda);
   enable_interrupts(global);
   for(;;){
      if(smsOk==TRUE){
         disable_interrupts(int_rda);
         cmp_result = compare_buffer();
         switch(cmp_result){
            case 1:
               output_a(0b00000001);
            break;
            case 2:
               output_a(0b00000010);
            break;
            case 3:
               output_a(0b00000100);
            break;
            default:
               output_a(0b00010000);
            break;
         }
         smsOk=FALSE;
         enable_interrupts(int_rda);
      }
   }

}
Saludos a todos. :mrgreen:  :mrgreen: