desktop

Problema bucle infinito USB_CDC PIC 18F2550

Hola, a ver si alguien me puede ayudar.
Estoy haciendo un proyecto en el cual cuando se reciben caracteres por el puerto usb (com emulado por cdc), se deben realizar distintas tareas. Hasta aquí todo bien y funciona pefecto. El problema es cuando una de esas tareas deben ser de tipo bucle infinito, es decir se debe ejecutar indefinidamente hasta que se reciba otro dato distinto, entonces salir del bucle y evaluar a qué otra rutina dirigirse.
He probado evaluando dentro del bucle con usb_cdc_kbhit(), pero siempre aparece verdadero, también probé con interrupciones del tipo INT_USB pero no las puedo usar porque me dice que está ya usada en uno de los archivos .h necesarios para emular cdc.
No se me ocurre nada más, si alguien me puede ayudar porque ya estoy un poco desesperado. Gracias!!!
NOTA: puedo colocar el código si lo desean.
 
¿ No sería pertinente ver el código que estas empleando ?
 
Código:
#include <18F2550.h>             //PIC a emplear
#fuses HSPLL,NOWDT,NOLVP,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)       //Frecuencia del cristal oscilador externo
#define CH0 PIN_B5
#define CH1 PIN_B4
#define CH2 PIN_B3
#include <PWM.h>
#include <stdlib.h>
#include <usb_cdc.h>             //Librería de control USB
#include <string.h>

//DECLARACION DE VARIABLES

long int R,G,B,longitud,modo;
char recibido [12];
char color [12];
char * token;
char delim[] = ",";
char * colorR;
char * colorG;
char * colorB;

void modoCambiarColor(char);
void modoAudioritmicoAudio(int);
int comprobarDatoINT(int);

void main() {
   usb_cdc_init();               //Inicialización del modo CDC
   usb_init();                   //Inicialización del control del USB
   while(!usb_cdc_connected()){} //Espera hasta que el USB esté conectado
   while(true){
      usb_task();                //Detección de la conexión de dispositivo USB
      //Devuelve TRUE si dispositivo ha sido enumerado por el PC
      if (usb_enumerated()) {
         //Si se ha recibido dato...
         if (usb_cdc_kbhit()){
            
            get_string_usb(recibido,12);  //lo lee
         
            longitud = strlen(recibido);  //cuenta longitud de la cadena recibida
            if (longitud>1)
            {
               strcpy(color,recibido);
               modoCambiarColor(color);
            }
            else
            {
               modo=atoi(recibido);
               PWM_stop();
               switch(modo){
               case 1:
                  modoAudioritmicoAudio(modo);
                  break;
               case 2:
                  output_low(PIN_B4);
                  break;
               case 3:
                  output_low(PIN_B3);
                  break;
               default:
                  output_low(PIN_B5);
                  output_low(PIN_B4);
                  output_low(PIN_B3);
                  break;
               }
            }
         }
       }
   }
}

void modoCambiarColor(char color)
{
   //TRANSFORMA EL STRING RECIBIDO EN 3 CHAR RGB DISTINTOS
   token = strtok(color, delim); 
   colorR = token;
   token = strtok(NULL, delim);
   colorG = token;
   token = strtok(NULL, delim);
   colorB = token;
   //TRANSFORMA LOS 3 CHAR RGB EN 3 INT
   R=atol(colorR);
   G=atol(colorG);
   B=atol(colorB);
   
   delay_ms(100);
   PWM_init(50);    //Inicia para generar PWM por software

   write_duty0(R);
   write_duty1(G);
   write_duty2(B);
   
   break;
}

void modoAudioritmicoAudio(int data)
{
   int l = 0;
   while (l==0){
   output_low(PIN_B5);
   output_low(PIN_B4);
   output_low(PIN_B3);
   delay_ms(500);
   output_high(PIN_B5);
   output_high(PIN_B4);
   output_high(PIN_B3);
   delay_ms(500);
   //l=comprobarDatoINT(data);
}
}

int comprobarDatoINT(dato)
{
   char s1;
   int s2;
   usb_task();
   if(usb_enumerated()){
   if(usb_cdc_kbhit()){
   s1 = usb_cdc_getc();  //lo lee
   s2 = atoi(s1);
   if (s2==dato){return 0;}
   else {return 1;}
   }
   }
}



La función modoAudioritmicoAudio es la que necesito que se ejecute en bucle infinito, saliendo de él cuando reciba un dato distinto, y si es igual, permanecer, sino reevaluar con el switch.
 
Última edición:
Eso de while (1 == 0) como que me parece algo demasiado ilógico. ¿No?
Si 1 fuera una variable lo vería posible, pero no, 1 y 0 son constantes.

Prueba a cambiar eso por: while (true)
Que en PIC C de CCS es igual a: while (1 = 1)
 
Gracias compañero, pero sé hacer un bucle infinito jaja.
Pero como expliqué en el primer post, necesito que salga de ese bucle cuando se reciba un nuevo dato diferente al que recibió inicialmente.
El problema es que no sé como hacer que compruebe un dato nuevo en cada iteración de forma rápida sin detenerse, ya que al ponerse a leer un dato nuevo se queda ahí esperando y el bucle no se produce.
No sé si me explico, pero ojalá me puedan ayudar.

Saludos.
 
Gracias amigo, eso trato de hacer con esa funcion que está comentada...pero no funciona porque al leer el dato con usb_cdc_getc el proceso se detiene hasta que le envíe el nuevo...no sé como implementarlo, a ver si me puedes ayudar con eso, porque parece la solución más sencilla.

Saludos!
 
Podría ser así, pero es un ejemplo que necesitarás adaptar:
PHP:
void modoAudioritmicoAudio(int8 data)
{
    while (true)
    {        
        if (l != data)
        {
            output_low(PIN_B5);
            output_low(PIN_B4);
            output_low(PIN_B3);
            delay_ms(500);
            output_high(PIN_B5);
            output_high(PIN_B4);
            output_high(PIN_B3);
            delay_ms(500);
            }
        else
        {
            l = data;
            break;
        }
    }
}
 
Última edición:
Gracias, pero la cuestión que me falta es refrescar en cada iteración el valor de la variable "l".
Eso lo estaba haciendo mediante la llamada a la función comprobarDatoINT, fíjate, pero algo debe estar mal en ella.

Saludos, Daniel.
 
A ver, es que refrescar es adquirir un valor diferente.
Ese valor de L debe compararse entre uno posterior y uno actual.

Trabajar con USB-CDC es muy similar a RS-232, y por lo tanto también se pueden usar arreglos para obtener cadenas.
O sea que tu proceso de adquisición de datos se puede mejorar bastante, e incluso añadir variables que te podrán servir cómo banderas.

Banderas que posteriormente te servirán para elegir los procesos.

Algo así:
PHP:
usb_gets(2,datos_usb,sizeof(datos_usb),100);   // Recibir la cadena de datos.
Y ahí contendrás todo en ASCII si así lo envías y te evitas de conversiones.
A fin de cuentas, es lo que un microcontrolador entiende.
 
Atrás
Arriba