Autor Tema: Usart se bloquea  (Leído 4093 veces)

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

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Usart se bloquea
« en: 31 de Octubre de 2013, 18:17:49 »
Hola amigos, tengo un programa que recibe un dato por el módulo usart y lo entrega a una variable, cuando le llegan muchos byte seguidos la interrupción del módulo usart se bloquea y no vuelve a entrar, el resto del programa funciona perfecto.

A alguno de ustedes le ha sucedido algo similar.

Saludos.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Usart se bloquea
« Respuesta #1 en: 31 de Octubre de 2013, 19:08:29 »
Es raro pero si estas utilizando el ccs y el puerto serial, por hardware, podrias agregar la opcion errors para que te resetee la usart.
Lo otro que puede estar ocuriendo es que tardas mucho tiempo manipulando el primer byte que te llego y luego cuando llega otro no te da tiempo de procesarlo y eso bloquea la usart del pic.   :mrgreen:
Prueba enviando los datos que llegan por la usart mas lento y nos dices.   ;-)

Saludos
« Última modificación: 31 de Octubre de 2013, 21:55:59 por RALF2 »

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: Usart se bloquea
« Respuesta #2 en: 31 de Octubre de 2013, 22:33:02 »
Hola Ralf, gracias por responder, si alcanzan a llegar varios byte al buffer y este no se ha leído el usart se bloquea ?, voy a probar con el detector de errores y te cuento,

Saludos.

Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: Usart se bloquea
« Respuesta #3 en: 31 de Octubre de 2013, 22:36:04 »
Citar
Hola Ralf, gracias por responder, si alcanzan a llegar varios byte al buffer y este no se ha leído el usart se bloquea ?

Asi mismo es, lo puedes leer en el data sheet del Pic   :mrgreen:

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #4 en: 31 de Octubre de 2013, 23:13:31 »
Puede tener uno en el buffer y otro entrando, si hay un tercero se bloquea...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #5 en: 31 de Octubre de 2013, 23:14:45 »
a que velocidad tienes puesto el puerto?
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: Usart se bloquea
« Respuesta #6 en: 01 de Noviembre de 2013, 09:12:16 »
Hola Marcos, el puerto lo tengo a 4800, lo curioso es que en mi programa inmediatamente se genera la interrupción descargo el buffer.

Saludos.

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #7 en: 01 de Noviembre de 2013, 09:15:30 »
Publica tu código, es posible ayudarte mas de ese modo...
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: Usart se bloquea
« Respuesta #8 en: 01 de Noviembre de 2013, 10:42:42 »
El programa consiste en lo siguiente:

Recibe por el usart dos byte de un módulo RF, si el dato es valido lo reenvía por un módulo serial por software a través de el pin RA4, tiene un temporizador para detectar si el módulo de RF deja de enviar para enviar un código de fiscalización, le hice una rutina que detecta si la interrupción del usart se bloquea y así reiniciar el micro.

Gracias por tu interés.

Saludos.

Código: C
  1. #include <16f1827.h>
  2.  
  3. #use delay(clock = 16mhz)
  4.  
  5. #use rs232(baud=2400, xmit=pin_b2,rcv=pin_b1,stop=2,stream=rs232)
  6. #use rs232(baud=4800, xmit=pin_b0,rcv=pin_b0,stop=2,stream=potencia,timeout=4)
  7.  
  8. #fuses intrc_io, wdt, put, brownout, nomclr
  9.  
  10. #byte   porta = 0x0c            //Definicion de variables del pic
  11. #byte   portb = 0x0d
  12. #byte   wpua = 0x20c
  13. #byte   wpub = 0x20d
  14. #byte   option_reg = 0x95
  15.  
  16. #define dip_sw porta
  17. #define pin_rx bit_test(portb,1)
  18. #define pin_cheq_rf pin_b7
  19.  
  20. int const dir_potencia = 0b10100010;
  21. int dato_recibido[5];
  22. int con_recibir;
  23. int codigo_tecla;
  24. int direccion;
  25. int con_modo_env;
  26. int con_recibir_rf;
  27. int res_codigo_tecla;
  28. int con_seguridad_rf;
  29.        
  30. short ban_enviar;
  31. short ban_tmr1;
  32. short ban_pin_rx;
  33.  
  34. void enviar_dato();
  35. void tiempo_recibir();
  36. void seguridad_rf();
  37.  
  38. ///////////////////////////////////////////////////////////////////////////////
  39. //******************INTERRUPCIONES*********************************************
  40. //*****************************************************************************
  41. //*****************************************************************************
  42. //*****************************************************************************
  43. //*****************************************************************************
  44. //*****************************************************************************
  45. //Vector de interrupcion de la recepcion de datos por el usart
  46. #int_rda                               
  47. void interrupcion_rx()
  48. {
  49.         int respaldo;
  50.        
  51.         respaldo = getc(rs232);
  52.         output_toggle(pin_cheq_rf);
  53.         con_seguridad_rf = 0;
  54.        
  55.         if(con_modo_env == 2)
  56.         {              
  57.                 if(respaldo == direccion) {con_recibir_rf = 0;}
  58.                 return;
  59.         }
  60.        
  61.         con_recibir_rf = 0;
  62.        
  63.         if(con_modo_env == 1)
  64.         {
  65.                 codigo_tecla = respaldo;
  66.                 res_codigo_tecla = respaldo;
  67.                 con_modo_env = 2;      
  68.                 return;
  69.         }
  70.        
  71.         if(respaldo == direccion) {con_modo_env = 1;}  
  72. }
  73. ///////////////////////////////////////////////////////////////////////////////
  74. //se recibe la comunicación del pic de potencia
  75. #int_ext
  76. void recibir_mando()
  77. {
  78.         set_timer2(0);
  79.         clear_interrupt(int_timer2);
  80.         enable_interrupts(int_timer2);
  81.        
  82.         dato_recibido[con_recibir] = getc(potencia);
  83.         con_recibir++;
  84.        
  85.         if(con_recibir == 4)
  86.         {
  87.                 con_recibir = 0;
  88.                         if(dato_recibido[0] == dir_potencia)
  89.                 {
  90.                         ban_enviar = 1;
  91.                         //enviar_dato_pc();
  92.                         memset(dato_recibido, 0, sizeof(dato_recibido));
  93.                         set_timer1(65536 - 2500);
  94.                 }
  95.         }
  96. }
  97. ///////////////////////////////////////////////////////////////////////////////
  98. //vector de interrupcion por desbordamiento del timer 1
  99. #int_timer1                                    
  100. void interrupcion_tmr1()
  101. {
  102.         set_timer1(0);
  103.         ban_tmr1 = 1;
  104.        
  105.         if(!ban_enviar) {return;}
  106.         ban_enviar = 0;
  107.        
  108.         if(codigo_tecla != 0) {enviar_dato();}  //si no han presionado tecla no envia
  109. }
  110. ///////////////////////////////////////////////////////////////////////////////
  111. //Vector de interrupcion por desbordamiento del timer 2
  112. #int_timer2                                    
  113. void interrupcion_tmr2()
  114. {
  115.         con_recibir = 0;
  116.         memset(dato_recibido, 0, sizeof(dato_recibido));
  117.         disable_interrupts(int_timer2);
  118. }
  119. ///////////////////////////////////////////////////////////////////////////////
  120. //******************PROGRAMA GENERAL*******************************************
  121. //*****************************************************************************
  122. //*****************************************************************************
  123. //*****************************************************************************
  124. //*****************************************************************************
  125.  
  126. #zero_ram       //Borrado de la memoria ram
  127.  
  128. void main()             //Rutina principal
  129. {
  130. set_tris_a(0b11111111);         //Configuracion del puerto a
  131. set_tris_b(0b00111011);         //Configuracion del puerto b
  132.  
  133. porta = 0b11111111;
  134. portb = 0b00111111;
  135.  
  136. setup_comparator(nc_nc_nc_nc);
  137.  
  138. setup_oscillator(osc_16mhz | osc_intrc | osc_pll_off);
  139.        
  140. delay_ms(10);
  141.  
  142. setup_timer_0(rtcc_div_1 | rtcc_ext_h_to_l);
  143. setup_timer_1(t1_internal | t1_div_by_8);
  144. setup_timer_2(t2_div_by_64,250,8);
  145. port_b_pullups(true);  
  146.  
  147. setup_wdt(wdt_512ms);
  148. ext_int_edge(h_to_l);
  149. clear_interrupt(int_ext);
  150. enable_interrupts(int_ext);
  151. enable_interrupts(int_rda);
  152. enable_interrupts(int_timer1);
  153. enable_interrupts(int_timer2);
  154. enable_interrupts(global);
  155.  
  156. putc('A', rs232);
  157.  
  158. ///////////////////////////////////////////////////////////////////////////////
  159. //***********************RUTINAS GENERAL DE TECLADO****************************
  160. //*****************************************************************************
  161. while(true)            
  162.         {
  163.                 restart_wdt();
  164.                 delay_ms(5);
  165.                 tiempo_recibir();
  166.                 seguridad_rf();
  167.         }
  168. }
  169. ///////////////////////////////////////////////////////////////////////////////
  170. //***********************RUTINAS***********************************************
  171. //*****************************************************************************
  172. //*****************************************************************************
  173. //*****************************************************************************
  174. //*****************************************************************************
  175. //rutina que envia los datos al pic de potencia
  176. void enviar_dato()     
  177. {
  178.         disable_interrupts(int_timer0);
  179.        
  180.         fputc(0b10100001, potencia);
  181.         fputc(codigo_tecla, potencia);
  182.         fputc(10, potencia);
  183.         fputc(5, potencia);
  184.        
  185.         set_timer2(0);
  186.         clear_interrupt(int_timer0);
  187.         enable_interrupts(int_timer0);
  188.         input(pin_b0);
  189.         codigo_tecla = 0;
  190. }
  191. ///////////////////////////////////////////////////////////////////////////////
  192. //sei se deja de recibir un dato durante 150 ms se envía la función de apagado
  193. void tiempo_recibir()
  194. {
  195.         direccion = dip_sw >> 1;
  196.         direccion &= 0b00001111;
  197.         direccion |= 0b10100000;
  198.                
  199.         con_recibir_rf++;
  200.         if(con_recibir_rf == 30 && con_modo_env == 2)
  201.         {
  202.                 codigo_tecla = res_codigo_tecla + 1;
  203.                 res_codigo_tecla = 0;
  204.                 con_modo_env = 0;
  205.         }
  206. }
  207. ///////////////////////////////////////////////////////////////////////////////
  208. //se chequea el pin de rx rf y se se bloquea la interrupción se resetea el pic
  209. void seguridad_rf()
  210. {
  211.         if(!pin_rx && !ban_pin_rx)
  212.         {
  213.                 ban_pin_rx = 1;
  214.                
  215.                 con_seguridad_rf++;            
  216.                 if(con_seguridad_rf == 5)
  217.                 {
  218.                         con_seguridad_rf = 0;
  219.                         reset_cpu();
  220.                 }              
  221.         }
  222.         if(pin_rx && ban_pin_rx) {ban_pin_rx = 0;}     
  223. }

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #9 en: 01 de Noviembre de 2013, 10:55:00 »
Estas utilizando el mismo pin para enviar y recibir en la segunda uart ??

La primera es por hardware ?? Los pines B1 y B2 son de hardware ??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Usart se bloquea
« Respuesta #10 en: 01 de Noviembre de 2013, 11:08:41 »
No se casi nada de CCS pero... ¿dentro de la interrupción no deberías borrar el flag de la fuente que ha producido la interrupción?. Si no... en cuanto el PC sale de la interrupción vuelve a entrar....

Un saludo.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #11 en: 01 de Noviembre de 2013, 11:31:31 »
Se borra solo el flag de int, en CCS.

Porque usas 2 bit de stop en las comunicaciones ??
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado manwenwe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2211
Re: Usart se bloquea
« Respuesta #12 en: 01 de Noviembre de 2013, 11:36:50 »
Se borra solo el flag de int, en CCS.

Porque usas 2 bit de stop en las comunicaciones ??

Lo decía porque en "void interrupcion_rx()" no se borra ningún flag. Perdón.
Ojo por ojo y todo el mundo acabará ciego - Mahatma Gandhi -

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
Re: Usart se bloquea
« Respuesta #13 en: 01 de Noviembre de 2013, 11:38:34 »
Entiendo.
Es que el manejador de interrupciones de CCS lo hace solo, si uno mira el codigo en asm generado, se ve que es asi... :mrgreen:
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado Diego E.

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1086
Re: Usart se bloquea
« Respuesta #14 en: 01 de Noviembre de 2013, 12:06:27 »
Tengo dos módulos el primer UART es hardware y el segundo es una comunicación especial utilizando el mismo pin RB0, interrupción externa, ambos tienen 2 bit de stop.

Acá todo funciona perfecto, el problema es que cuando el módulo RF envía datos muy seguidos la interrupción UART 1 (Hardware) se bloquea y no vuelve a recibir, como comenté antes, lo que hice fue estar preguntando independientemente por el PIN RX de este UART 1 e ir incrementando un contador, cuando hay interrupción por UART 1 se borra el contador, pero si la interrupción está bloqueada el contador incrementa hasta cierto valor y ahí se resetea el PIC.