Autor Tema: Lectura parcial de cadenas RS232  (Leído 2587 veces)

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

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Lectura parcial de cadenas RS232
« en: 29 de Diciembre de 2009, 23:43:30 »
Para una aplicación que estoy haciendo requería recibir una cantidad de caracteres terminados con un 0x0D (retorno de carro) y 0x0A (nueva línea). El caracter de nueva línea se quedaba pendiente en el buffer RCREG del PIC y además seguían llegando caracteres después de esa cadena.

Una vez que yo recibía la cadena terminada con 0x0D ya no me interesaba qué más llegaba y deshabilitaba la interrupción RS232. Al hacer esto el buffer RCREG guardaba un dato y el registro de desplazamiento superior al RCREG se desbordaba por no vaciar RCREG a tiempo por la llegada de todos los demás caracteres. Esto levantaba la bandera Overrun Error OERR (bit 1 de RCSTA en 0x0FAB) y cancelaba toda recepción posterior de caracteres aún cuando las interrupciones global y rs232 estuvieran habilitadas.

Para lograr una recepción intermitente RS232 en la que a veces uno lee y a veces no, dejo el siguiente código. Solo es necesario bajar el bit CREN Continuous Receive Enable (bit 4 de RCSTA en 0xFAB) y volverlo a levantar para que el bit OERR regrese a su estado normal.

Código: [Seleccionar]
int1 com_completo=false;

////////////////////////////////////////////////////////////////////////////////
//Subrutina de interrupción RS232
#int_rda
void recibe_comando()
{
disable_interrupts(int_rda);
if(kbhit())
   {
   gets(com_rx);  //recibe hasta encontrar 0x0D
   delay_ms(2000); //espera a que se manden todos los demás caracteres que ignoraré
   com_completo = true;
   }
}
////////////////////////////////////////////////////////////////////////////////

...

////////////////////////////////////////////////////////////////////////////////
void main()
{

...

while(1)
   {
   if(com_completo == true) //ya llegó un comando
      {
      cmp = strcmp(com_rx, COM_GET); //compara lo recibido con lo esperado
      if(cmp == 0x00)
         enviar_respuesta_ok();
      com_completo = false;
      //Vacía buffer de entrada antes de rehabilitar interrupción
while(kbhit())
getc();
//Limpia el bit Overrun Error OERR limpiando el bit CREN de RCSTA
//Útil para cuando se quiere ignorar una cadena RS232
bit_clear(*0x0FAB,4);
                //Y lo vuelve a activar
bit_set(*0x0FAB,4);
      enable_interrupts(int_rda);
      }
   }
}
////////////////////////////////////////////////////////////////////////////////

Espero que les sea de utilidad.  :mrgreen:

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Lectura parcial de cadenas RS232
« Respuesta #1 en: 30 de Diciembre de 2009, 04:15:41 »
Una dudas, Santiago: ¿un kbhit() dentro de la interrupción de recepción USART es necesario?, se supone que si ha llegado ahí es porque hay un carácter pendiente de lectura, ¿no?

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Lectura parcial de cadenas RS232
« Respuesta #2 en: 30 de Diciembre de 2009, 10:40:41 »
Exactamente, la interrupción ocurre al recibir un bit de Stop.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: Lectura parcial de cadenas RS232
« Respuesta #3 en: 30 de Diciembre de 2009, 13:18:11 »
Una dudas, Santiago: ¿un kbhit() dentro de la interrupción de recepción USART es necesario?, se supone que si ha llegado ahí es porque hay un carácter pendiente de lectura, ¿no?


Cierto Manolo, ya no es necesario porque int_rda sólo habilita la interrupción por bandera RCIF y no entra ahí en otra condición. Pueden quitarlo con confianza.

Es que con tanto problema que tuve ya ni sabía por dónde atacarlo y quedó algo de código redundante.

Es un programa algo sucio porque podría recibir todo lo demás sin problemas, en la noche estuve meditando cómo hacerlo. Pero queda el tip de qué hacer ante un buffer overrun.


 

anything