TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: Modulay en 17 de Enero de 2008, 21:29:39

Título: No consigo que la usart provoque interrupción
Publicado por: Modulay en 17 de Enero de 2008, 21:29:39
A ver si alguien me saca de dudas,porque he probado mil cosas y no consigo..¡encender un led!
Tengo un led conectado a RB5,pues no hay forma de que el led se encienda mediante la rutina de interrupción...sin embargo,usando lo que está denro del WHILE se enciende a la primera ¿qué hago mal? no lo entiendo la verdad :(

Código: C++
  1. /////////////////////////////////////////////////////////////////////////
  2. #include <18F2550.h>
  3. #fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
  4. #use delay(clock=48000000)
  5. /////////////////////////////////////////////////////////////////////////////
  6.  
  7. #define USB_HID_DEVICE     FALSE            
  8. #define USB_EP1_TX_ENABLE  USB_ENABLE_BULK  
  9. #define USB_EP2_RX_ENABLE  USB_ENABLE_BULK  
  10. #define USB_EP1_TX_SIZE    64              
  11. #define USB_EP2_RX_SIZE    64                
  12.  
  13. #DEFINE EP1 1
  14. #DEFINE EP2 2
  15.  
  16. /////////////////////////////////////////////////////////////////////////////
  17.  
  18. #include <pic18_usb.h>
  19. #include <usbmidi.h>
  20. #include <usb.c>        
  21. #use rs232 (BAUD=31250,BITS=8,PARITY=N,rcv=PIN_C7)
  22.  
  23. //////////////////////////////////////////////////////////////////////////////
  24.  
  25. #INT_RDA
  26. void serial_isr()
  27. {
  28.   output_high(PIN_B5);
  29. }
  30.  
  31.  
  32. void main(void)
  33. {
  34.    int8 midi[4];
  35.  
  36.    set_tris_c(0x80);
  37.    usb_init();
  38.    usb_wait_for_enumeration();
  39.    enable_interrupts(INT_RDA);
  40.    enable_interrupts(GLOBAL);
  41.    output_low(PIN_B5);
  42.    
  43.    WHILE (TRUE)
  44.       {
  45.      
  46.       /*
  47.       if (kbhit())
  48.          {
  49.          output_high(PIN_B5);
  50.          }
  51.       */  
  52.          
  53.       }
  54. }
Título: Re: No consigo que la usart provoque interrupción
Publicado por: jfh900 en 17 de Enero de 2008, 21:35:51
Se presupone que lo tienes conectado al ordenador por un cable RS232 y le envías caracteres para que se active la interrupción. ¿Estará bien conectado y configurado el puerto RS232?

Un saludo
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Modulay en 17 de Enero de 2008, 21:51:02
Hola Jesús.
Pues no va conectado al pc.

Se trata de un puerto midi y lo tengo conectado a un piano digital,pero el funcionamiento del midi es completamente análogo al rs232,con la particularidad de que el bitrate es fijo a 31250 baudios y el midi in (RX) va optoacoplado.

(http://ciberia.ya.com/Modulay/img/midi2.jpg)

Es raro porque el kbhit() dentro del bucle si que funciona,por lo que se supone que los datos llegan,pero la interrupción no salta.
Título: Re: No consigo que la usart provoque interrupción
Publicado por: jfh900 en 17 de Enero de 2008, 21:54:29
Conéctalo primero a un PC y comprueba que funciona correctamente y cuando estés seguro de su funcionamiento, pasa a conectarlo al equipo MIDI.

Un saludo
Título: Re: No consigo que la usart provoque interrupción
Publicado por: fastyx2 en 17 de Enero de 2008, 21:56:46
me parece que en el tris del puerto c tenes que colocar el bit c6 de recepcion serial como entrada , y lo tenes en 0x80

espero sea de utilidad...
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Cryn en 17 de Enero de 2008, 21:58:33
en tu rutina de interrupcion nunca recoges ningun dato

#INT_RDA
void serial_isr()
{
 output_high(PIN_B5);
}

una vez he hecho algo parecido a ti, y lo que pasaba era que se quedaba colgado en la interrupcion, pues nunca descargaba el buffer, entonces lo solucione aquella vez, incuyendo una linea de codigo, que en tu caso tb puede ser algo asi:

#INT_RDA
void serial_isr()
{
 c=getc();   // copio el valor capturado por rs232 para salir de la interupcion al acabar la rutina
 output_high(PIN_B5);
}

y bueno definir un char c y talvez la libreria string.h

o talvez debas hacer algo parecido para que tu buffer sea descargado
Título: Re: No consigo que la usart provoque interrupción
Publicado por: maunix en 17 de Enero de 2008, 22:00:38
No uso CCS pero ¿se activa el PEIE al habilitar un módulo como el IRDA?

Tal vez esté allí el problema.

Título: Re: No consigo que la usart provoque interrupción
Publicado por: fastyx2 en 17 de Enero de 2008, 22:02:38
mil perdones :lol: estaba sin los lentes y cambie las patas de rx y tx
Título: Re: No consigo que la usart provoque interrupción
Publicado por: fastyx2 en 17 de Enero de 2008, 22:06:22
una duda con lo que expuso cryn : a pesar que se llena el buffer o que no se vacia , aunque sea una vez no tentra  a la interrrupcion para prender el led?
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Cryn en 17 de Enero de 2008, 22:09:23
pues si, creo que deberia encenderse y nunca mas apagarse, hasta que le quites las alimentacion o resetees

seguramente el pic no esta reconociendo el byte que le envia el otro dispositivo, porqeu no entra a la interrupcion
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Modulay en 17 de Enero de 2008, 22:13:20
Vaya cuantas respuestas,gracias gente.
Pues voy comentando cosas.

Jesús,he descartado que la causa esté en el hardware ya que mediante polling, haciendo uso del kbhit() dentro del bucle principal, consigo recibir los datos,que posteriormente proceso y redirijo al usb.

Cryn,he probado a descargar el buffer,tanto con getc() como con gets(string) y sigue igual.

Fastyx...jeje,tranquilo...aunque el dibujo que he puesto tampoco es un ejemplo de claridad.

Maunix,yo diría que si...voy a comprobarlo
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Modulay en 17 de Enero de 2008, 22:24:21
Pues los bits de habilitación de interrupción son seteados como es debido.

....................    //usb_wait_for_enumeration();
....................    enable_interrupts(INT_RDA);
012A:  BSF    F9D.5    ; RCIE = 1
....................    enable_interrupts(GLOBAL);
012C:  MOVLW  C0
012E:  IORWF  FF2,F   ;  GIE = 1, PEIE = 1
Título: Re: No consigo que la usart provoque interrupción
Publicado por: jfh900 en 17 de Enero de 2008, 22:31:58
Te sigo recomendando (si tienes la posibilidad) que lo pruebes con un puerto serie de un PC para descartar problemas de comunicación. Otra posibilidad es que lo simules haber que pasa.

Un saludo
Título: Re: No consigo que la usart provoque interrupción
Publicado por: Nocturno en 18 de Enero de 2008, 07:54:51
Incluye estos defines al principio:
#byte RCSTA=             0xFAB       // Registro de recepcion de la usart
#bit SPEN=                RCSTA.7      // Bit activación puerto serie
#bit CREN=                RCSTA.4      // Se activa para recepción continua

Y esto en el main, antes de activar las interrupciones:
   SPEN=1;           // USART activada
   CREN=1;           // Recepción activada

Con eso chuta seguro
Título: Re: No consigo que la usart provoque interrupción
Publicado por: maunix en 18 de Enero de 2008, 11:56:01
Modulay, solo me resta pensar que tengas 'ruido' al encender la aplicación y que se quede bloqueada la usart para recibir.

Revisa el estado del bit OERR y FERR , si están encendidos.  El FERR se soluciona vaciando el buffer de la usart, el OERR es más dañino y hay que resetear el módulo usart, borrando y activando el bit CREN.

Si el OERR está encendido, la usart no recibe nada más.  Tal vez por allí esté tu problema.


Título: Re: No consigo que la usart provoque interrupción
Publicado por: Modulay en 18 de Enero de 2008, 18:56:21
Con lo que ha sugerido Manolo ya se consigue que entre en la interrupción,aunque parece que interfiere con el usb y la enumeración falla.
Maunix,he comprobado esos bits y no parece que ninguno se active.
He suprimido todo lo relacionado al usb y esto sigue haciendo cosas que no me explico.

¿os podeis creer que así el led se enciende...

Código: C++
  1. int8 dato;
  2. boolean usart = FALSE;
  3.  
  4.  
  5. #INT_RDA
  6. void serial_isr()
  7. {
  8.   output_high(PIN_B5);
  9.   usart = true;
  10.   if(kbhit())
  11.     {
  12.     dato = getc();
  13.     }
  14. }
  15.  
  16.  
  17. void main(void)
  18. {
  19.  
  20.    set_tris_c(0x80);
  21.    output_low(PIN_B5);
  22.    enable_interrupts(INT_RDA);
  23.    SPEN=1;           // USART activada
  24.    CREN=1;           // Recepción activada
  25.    enable_interrupts(GLOBAL);
  26.  
  27.    while(TRUE)
  28.       {
  29.          if(usart == true)
  30.            {
  31.            //output_high(PIN_B5);
  32.            }
  33.       }
  34.  
  35. }

...y asi no?

Código: C++
  1. int8 dato;
  2. boolean usart = FALSE;
  3.  
  4.  
  5. #INT_RDA
  6. void serial_isr()
  7. {
  8.   //output_high(PIN_B5);
  9.   usart = true;
  10.   if(kbhit())
  11.     {
  12.     dato = getc();
  13.     }
  14. }
  15.  
  16.  
  17. void main(void)
  18. {
  19.  
  20.    set_tris_c(0x80);
  21.    output_low(PIN_B5);
  22.    enable_interrupts(INT_RDA);
  23.    SPEN=1;           // USART activada
  24.    CREN=1;           // Recepción activada
  25.    enable_interrupts(GLOBAL);
  26.  
  27.    while(TRUE)
  28.       {
  29.          if(usart == true)
  30.            {
  31.            output_high(PIN_B5);
  32.            }
  33.       }
  34.  
  35. }


 :?