Las transmisiones USB bloquean la GUI de mi software

Estoy transmitiendo una matriz de búfer desde el USB incorporado de los controladores PIC 18F y enviando esto a una GUI. Soy capaz de detectar el dispositivo correctamente (enumeración). Pero la GUI falla algunas veces, sin ningún motivo.

Supongo que es un problema de transmisión/interrupción, ya que cada vez que envío un número constante, no falla. Pero cada vez que realizo una operación ADC y envío el valor correspondiente a través de USB, se bloquea.

Esto hizo que supusiera que la transmisión USB o el manejo de interrupciones deben manejarse correctamente.

Soy nuevo en el protocolo USB y probé con este código de trabajo.

No tengo ningún problema con respecto a la enumeración, pero cuando se transmite se produce el bloqueo.

El formato del código es:

 main()
{   usbinit(); // usb initialization

       while(1)

{         
      x=do_adc();
      UsbTasks(); // does usb works    
      yourtasks();//sends the buffer 

}

}

Me gustaría entender cuál podría ser la causa detrás de este comportamiento anómalo.

Como se indica a continuación en los comentarios, la pila USB está configurada para la configuración de sondeo. ¿Cómo debo administrar la lectura de ADC?

Si lo hago:

while(1)

    {         

          UsbTasks(); // does usb works
           x=do_adc();    
          yourtasks();//sends the buffer 

    }

¿Hará algún cambio? ¿O no es esta la mejor manera de enviar valores ADC?

¿Tiene la pila configurada para el modo de sondeo o interrupción? Si está en modo sondeado, la lectura del ADC probablemente esté deteniendo la llamada UsbTasksdurante demasiado tiempo.
Muchas gracias @PeterJ. Tengo que verificar eso. Estoy revisando el código ahora mismo.
Si la GUI en la PC se bloquea, suena como un problema de software, no de electrónica.
@PeterJ La pila está configurada para la configuración de sondeo. ¿Cómo debo administrar el adcread entonces?

Respuestas (1)

De acuerdo con la nota de aplicación USB CDC Class on an Embedded Device de Microchip, que también se aplicaría principalmente a otras clases de dispositivos:

La rutina USBTasks se puede utilizar de manera cooperativa, como se muestra. Si es así, nada en el bucle principal debe bloquearse durante más de unos pocos microsegundos o los eventos pueden perderse.

Entonces, las dos soluciones principales que se me ocurren son:

  • En lugar de esperar a que termine la conversión del ADC, inicie la conversión y luego use una interrupción de conversión completa para que el ciclo de procesamiento principal pueda continuar mientras el ADC toma una muestra.

  • Configure la pila USB para usar el modo controlado por interrupción para eliminar los requisitos para llamar UsbTaskscon tanta frecuencia.

Para la mayoría de las aplicaciones, diría que esta última es probablemente la solución más fácil, por lo que no tiene que preocuparse tanto si su bucle principal se detiene un poco.

Confío en que la conversión de adc tomará algunos microsegundos :). ¿Podría ser eso también un problema?
Depende de la configuración de la pieza y del ADC, pero creo que la velocidad típica más rápida para la mayoría de las piezas del PIC18 es de alrededor de 100 ksps, por lo que serían 10 us.
Eso no causará ningún problema, espero que sea correcto :)
Los documentos de Microchip dicen unos 'pocos' microsegundos que, aunque no son precisos, interpretaría como dos o tres, tal vez un poco más, por lo que bien podría funcionar. También puede haber algunas desventajas al ejecutar un ADC a la velocidad máxima, por lo que sería mejor evitar leerlo en el modo sondeado y usar interrupciones para el lado USB o ADC.
Gracias. Todavía tengo una duda, puede ser debido a conceptos básicos no tan sólidos. Perdónenme por eso. Pero me gustaría preguntar si el controlador deja main() y va a ISR() y si ISR ​​toma más tiempo. ¿será eso un problema>? ¿O main() ejecutará las tareas USB sin ningún problema?