Autor Tema: Problema al leer una trama por RS232  (Leído 16413 veces)

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

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Problema al leer una trama por RS232
« en: 06 de Febrero de 2016, 21:40:51 »

     :-/  hola amigos   :-/

quiero preguntarles como puedo solucionar dicho problema,

estoy leyendo una trama de datos 25&52 por rs232, con un pic16f628a...pero el problema es que la lectura se queda pegada y no es capas de seguir leyendo los datos que le están llegando

nota: después de leer la trama separo los datos y los muestro en display de 4 segmentos

aquí envió el programa para que me puedan orientar con la solución;

saludos   :-/ :-/ :-/
////////////////////////////////////////////////////////////////////////////////////////////


// NUMEROS [0-9] = [ 0  , 1  , 2  , 3  , 4  , 5  , 6  , 7 ,  8  , 9 ]
int Numeros[10]  = {0X00,0X01,0X02,0x03,0x04,0x05,0X06,0x07,0X08,0x09};
char trama_serial[4];                   // Arreglo para recibir los datos.
int1 flag_rx = 0;                // Variable bandera de recepción.
int8  Num_1,Num_2,Num_3,Num_4;

// Servicio de interrupción por recepción de datos RS-232
#INT_RDA
void RECEPCION_RS232(void)

{
   gets(trama_serial);                  // Se recibe la cadena de datos.
   flag_rx = 1;                  // Se indica recepción completa.
}
   
   void main (void)
   {
   int tiempo = 10;
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);
   set_tris_a(0x00);
   set_tris_b(0x02);
     
   while (true)
   {
   
      if(flag_rx == 1)                // Si hay datos en el buffer...
      {
       //
       Num_1 = ((trama_serial[0])-48);   Num_3 = ((trama_serial[3])-48);
       Num_2 = ((trama_serial[1])-48);   Num_4 = ((trama_serial[4])-48);
       printf("%d%d%d%d\r",Num_1,Num_2,Num_3,Num_4);
                      // Limpiar la bandera "flag_rx"
        while (true)
      {
       output_b(0x12); output_a(Numeros[Num_1]);  delay_ms(tiempo);
       output_b(0x22); output_a(Numeros[Num_2]);  delay_ms(tiempo);
       output_b(0x42); output_a(Numeros[Num_3]);  delay_ms(tiempo);
       output_b(0x82); output_a(Numeros[Num_4]);  delay_ms(tiempo);
      }
      flag_rx = 0;   
     
   }
   }
   }

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Problema al leer una trama por RS232
« Respuesta #1 en: 06 de Febrero de 2016, 22:11:16 »
como sabes que no lee mas caracteres?

por que este bucle hace que se muestre siempre lo mismo en los displays

Código: C
  1. while (true)
  2.       {
  3.        output_b(0x12); output_a(Numeros[Num_1]);  delay_ms(tiempo);
  4.        output_b(0x22); output_a(Numeros[Num_2]);  delay_ms(tiempo);
  5.        output_b(0x42); output_a(Numeros[Num_3]);  delay_ms(tiempo);
  6.        output_b(0x82); output_a(Numeros[Num_4]);  delay_ms(tiempo);
  7.       }
-
Leonardo Garberoglio

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al leer una trama por RS232
« Respuesta #2 en: 06 de Febrero de 2016, 22:31:19 »
Agrego a lo de elgarbe

Citar
#INT_RDA
void RECEPCION_RS232(void)
{
   gets(trama_serial);
   flag_rx = 1;                  // Se indica recepción completa.
}

Otra cosa, bajo ningun motivo uses gets().
Por 2 razones:

No tiene una proteccion de bufferoverflow. Si observas no tiene un parametro que limite el tamaño, por lo cual si seguis presionando teclas y nunca presionas enter vas a sobreescribir toda la memoria RAM. Es decir por mas que tu array sea de 10 lugares, podrias terminar escribiendo 100, afectando a otras variables.

Y en la interrupcion, esa funcion se queda esperando que llegue otro caracter, por lo cual rompe el proposito de la interrupcion, que es atender los eventos lo mas rapido posible. Al quedarse ahi esperando por mas que otras interrupciones ocurran  se va a quedar ahi fijo hasta que un "enter" aparezca. Deberias usar getc(), e ir guardando letra por letra en el array. Luego cuando se completo el array ( que llegaron todos los datos ) procedes a activar una bandera como "flag_rx" y asi avisar al main() que el dato esta listo.

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #3 en: 06 de Febrero de 2016, 22:34:06 »
y como se podría hacer eso que me comentas , no he podido mejorarlo

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Problema al leer una trama por RS232
« Respuesta #4 en: 06 de Febrero de 2016, 22:45:51 »
Si no entiendo mal lo de Killer sería algo así:

Código: C
  1. #INT_RDA
  2. void RECEPCION_RS232(void)
  3. {
  4.    getc(trama_serial[idx_Trama]);
  5.    idx_Trama++;
  6.    if (idx_Trama == 4){
  7.        idx_Trama = 0;
  8.        flag_rx = 1;                  // Se indica recepción completa.
  9.    }
  10. }

y necesitas una variable global volatile llama idx_Trama de tipo uint8_t

luego tu bucle principal sería:

Código: C
  1. while (true)
  2.    {
  3.    
  4.       if(flag_rx == 1)                // Si hay datos en el buffer...
  5.       {
  6.        //
  7.        Num_1 = ((trama_serial[0])-48);   Num_3 = ((trama_serial[3])-48);
  8.        Num_2 = ((trama_serial[1])-48);   Num_4 = ((trama_serial[4])-48);
  9.        printf("%d%d%d%d\r",Num_1,Num_2,Num_3,Num_4);
  10.                       // Limpiar la bandera "flag_rx"
  11.  
  12.        output_b(0x12); output_a(Numeros[Num_1]);  delay_ms(tiempo);
  13.        output_b(0x22); output_a(Numeros[Num_2]);  delay_ms(tiempo);
  14.        output_b(0x42); output_a(Numeros[Num_3]);  delay_ms(tiempo);
  15.        output_b(0x82); output_a(Numeros[Num_4]);  delay_ms(tiempo);
  16.  
  17.       flag_rx = 0;  
  18.      
  19.    }
  20.    }

posiblemente me olvide de algo, pero esa es la idea creo...

saludos!

« Última modificación: 06 de Febrero de 2016, 22:57:12 por elgarbe »
-
Leonardo Garberoglio

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #5 en: 06 de Febrero de 2016, 22:54:21 »
gracias por el consejo, lo probare en seguida..tengo el simulador operativo
les comento enseguida como va

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al leer una trama por RS232
« Respuesta #6 en: 06 de Febrero de 2016, 22:54:51 »
Algo asi tambien puede ser:

Código: C
  1. // NUMEROS [0-9] = [ 0  , 1  , 2  , 3  , 4  , 5  , 6  , 7 ,  8  , 9 ]
  2. int Numeros[10]  = {0X00,0X01,0X02,0x03,0x04,0x05,0X06,0x07,0X08,0x09};
  3. char trama_serial[10];                  // Arreglo para recibir los datos.
  4. int1 flag_rx = 0;                       // Variable bandera de recepción.
  5. volatile int indice=0;
  6. int8 basura;
  7.  
  8. void RECEPCION_RS232(void)
  9. {
  10.         if(i<4)    // Solo 4 valores nomas.
  11.         {
  12.                 trama_serial[indice]=getc();
  13.                 indice++
  14.         }
  15.         else
  16.         {
  17.                 flag_rx = 1;                  // Se indica recepción completa.
  18.                 basura = getc();                // Descarto el caracter
  19.         }
  20. }
  21.  
  22. void main (void)
  23. {
  24.         int tiempo = 10;
  25.         int8 j;
  26.         set_tris_a(0x00);
  27.         set_tris_b(0x02);
  28.         enable_interrupts(INT_RDA);
  29.         enable_interrupts(GLOBAL);
  30.      
  31.         while (true)
  32.         {
  33.  
  34.                 if(flag_rx == 1)                // Si hay datos en el buffer...
  35.                 {
  36.  
  37.                         // Pasamos de ASCII a decimal
  38.                        
  39.                         for( j=0 ; j<4 ; j++)
  40.                         {
  41.                                 trama_serial[j] -= 48;
  42.                         }
  43.  
  44.                         // Mostramos por UART
  45.                         printf("%d%d%d%d\r",trama_serial[0],trama_serial[1],trama_serial[2],trama_serial[3]);
  46.  
  47.                         // Mostramos ahora por el puerto A, cada numero
  48.  
  49.                         output_b(0x12);
  50.                         output_a(Numeros[trama_serial[0]]);
  51.                         delay_ms(tiempo);
  52.                         output_b(0x22);
  53.                         output_a(Numeros[trama_serial[1]]);
  54.                         delay_ms(tiempo);
  55.                         output_b(0x42);
  56.                         output_a(Numeros[trama_serial[2]]);
  57.                         delay_ms(tiempo);
  58.                         output_b(0x82);
  59.                         output_a(Numeros[trama_serial[3]]);
  60.                         delay_ms(tiempo);
  61.  
  62.                         // Limpio el indice para que comience de nuevo Y limpio el flag para indicar que termino y no entre mas aca hasta que se llene
  63.                         indice=0;
  64.                         flag_rx = 0;
  65.                 }
  66.         }
  67. }

Solo decirte que este programa espera 4 caracteres desde la UART, que son numeros y descarta TODO lo que pueda llegar hasta que se muestre por completo. Cuando se mostro todo espera otros 4 numeros mas.
La diferencia entre el codigo de interrupcion de el garbe es que el mio como decia tira cualquier numero que pueda llegar mientras estas mostrando las cosas. Mientras que el de elgarbe no y sigue recibiendo a pesar que todavia esta mostrando.

Ahora tenes ya 2 codigos que hacen lo mismo :P

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #7 en: 06 de Febrero de 2016, 23:00:56 »
gracias, lo estoy simulando ahora , la idea es que espere la trama completa y despues la muestre en los display , para que no se se empieze a mesclar las tramas

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #8 en: 06 de Febrero de 2016, 23:09:02 »
Amigos probe el program que me indicaron, pero  igual sigue pegado
les puedo enviar el archivo , ai pueden ver bien el programa

saludos

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Problema al leer una trama por RS232
« Respuesta #9 en: 06 de Febrero de 2016, 23:22:46 »
Yo no estoy en la pc.
Igual es raro, el programa espera 4 números. Hasta q no los ingresas no hace nada. No hay que apretar entre entre ellos. Simplemente poner 1234 y debería funcionar. Pon un breack point dentro de la int de la uart a ver si entra y que recibe.
Que hace el programa cuando lo corres?

Saludos
-
Leonardo Garberoglio

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #10 en: 06 de Febrero de 2016, 23:23:56 »
Amigos

este es el programa completo , necesito recibir esta trama 25&26, logro recibir la trama pero aun no puedo mostrarlos
en los display 7 segemntos, esta trama siempre variara entre 0 al 99  por ejemplo   00&00...hasta  el 99&99


//////////////////////////////////////////////////////////////
#include <16f628A.H>
#fuses NOMCLR
#fuses INTRC_IO
#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES XT                     //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay (clock=4000000)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
#include <stdlib.h>
#define display_1     PIN_B4
#define display_2     PIN_B5
#define display_3     PIN_B6
#define display_4     PIN_B5



// NUMEROS [0-9] = [ 0  , 1  , 2  , 3  , 4  , 5  , 6  , 7 ,  8  , 9 ]
int Numeros[10]  = {0X00,0X01,0X02,0x03,0x04,0x05,0X06,0x07,0X08,0x09};
char trama_serial[4];                  // Arreglo para recibir los datos.
int1 flag_rx = 0;                       // Variable bandera de recepción.
volatile int indice=0;
int8 basura;
int i;
void RECEPCION_RS232(void)
{
        if(i<4)    // Solo 4 valores nomas.
        {
                trama_serial[indice]=getc();
                indice++;
        }
        else
        {
                flag_rx = 1;                  // Se indica recepción completa.
                basura = getc();                // Descarto el caracter
        }
}
 
void main (void)
{
        int tiempo = 10;
        int8 j;
        set_tris_a(0x00);
        set_tris_b(0x02);
        enable_interrupts(INT_RDA);
        enable_interrupts(GLOBAL);
     
        while (true)
        {
 
                if(flag_rx == 1)                // Si hay datos en el buffer...
                {
 
                        // Pasamos de ASCII a decimal
                       
                        for( j=0 ; j<4 ; j++)
                        {
                                trama_serial[j] -= 48;
                        }
 
                        // Mostramos por UART
                        printf("%d%d%d%d\r",trama_serial[0],trama_serial[1],trama_serial[2],trama_serial[3]);
 
                        // Mostramos ahora por el puerto A, cada numero
 
                        output_b(0x12);
                        output_a(Numeros[trama_serial[0]]);
                        delay_ms(tiempo);
                        output_b(0x22);
                        output_a(Numeros[trama_serial[1]]);
                        delay_ms(tiempo);
                        output_b(0x42);
                        output_a(Numeros[trama_serial[2]]);
                        delay_ms(tiempo);
                        output_b(0x82);
                        output_a(Numeros[trama_serial[3]]);
                        delay_ms(tiempo);
 
                        // Limpio el indice para que comience de nuevo Y limpio el flag para indicar que termino y no entre mas aca hasta que se llene
                        indice=0;
                        flag_rx = 0;
                }
        }
}

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #11 en: 06 de Febrero de 2016, 23:29:13 »
esto es lo que se visualiza

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Problema al leer una trama por RS232
« Respuesta #12 en: 07 de Febrero de 2016, 01:22:38 »
Sinceramente no comprendo demasiado por que no hay un circuito "completo". Los displays 7 segmentos por que son manejados ? Directamente desde el PIC o por un cd4511 ?

Por que hay un LCD en la captura de pantalla, cuando no hay nada de LCD en el codigo.

El codigo que pasamos esperan 4 numeros SEGUIDOS, y no separados por un '&'. Lo cual estaria agregando un caracter mas.

Cuando nos indiques eso va a ser mas facil.


PD: Por mi no subas ningun archivo de Proteus por que no lo tengo.

Desconectado futurama

  • PIC10
  • *
  • Mensajes: 47
Re:Problema al leer una trama por RS232
« Respuesta #13 en: 07 de Febrero de 2016, 01:41:14 »

OK, AMIGO

DATOS DEL FUNCIONAMIENTO

1- El lcd es parte del programa del transmisor que es un PIC16F877A, el esta mandando la trama 26&50 , programe un lcd para visualizar la trama         que se esta transmitiendo.

2- los primeros 4 bit del PORTA del  pic16f628a le envian señales al 4511 para encender los display multiplexados, los display son catodo comun
    por lo cual el portb esta comandando las activaciones de los transitores para activar el negativo de los display

la misión es poder separar la trama enviada y colocar cada numero en cada display por ejemplo:

si la trama que se recepciono fue  "25&58" , tengo que separar cada numero en cada display

     2                   5                  5             8
Display 1   -  Display2  -  Display3  - Display4





Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2178
Re:Problema al leer una trama por RS232
« Respuesta #14 en: 07 de Febrero de 2016, 03:10:41 »
Y no podrías probar sin enviar el & entre los dos grupos de numeros? porque el programa así como está debería funcionar reciviendo 4 números.... podrías poner el instrumento RS232 de proteus para ver la trama real que sale de un micro y llega al otro para aislar el problema....

sds.
-
Leonardo Garberoglio


 

anything