Según lo que describes el PIC18F4550 es una buena opción, sobretodo si ya tienes experiencia con él, pero no has comentado en concreto qué tipo de información es la que planeas enviar de la PC hacia la tarjeta, lo que comento a continuación es pensando en que se tratará de comandos para accionar quizá un servomotor o activar alguna salida del microcontrolador.
La comunicación por USB es más compleja que por ejemplo un módulo UART, porque involucra más complejidad tanto en el host (generalmente una PC) y el dispositivo, por ello en la especificación del protocolo ya están definidas algunas clases de dispositivos estándar en los cuales se pueden basar las aplicaciones para acelerar la implementación, algunas comunes:
- HID (Human Interface Device)
- CDC (Communication Device Class)
- MSC (Mass Storage Device Class)
- UVC (USB Video Device Class)
Puedes ver varias clases más en Wikipedia:
https://en.wikipedia.org/wiki/USB#Device_classesEl configurar el módulo USB del microcontrolador para utilizar alguna de estas clases facilita el desarrollo puesto que muchos sistemas operativos ya incluyen los controladores/drivers necesarios para comunicarse con clases de dispositivos de uso común, así es como puedes sin problema conectar "casi" cualquier ratón, teclado, memoria de almacenamiento, etc. por USB a cualquier computadora sin necesidad de instalar controladores.
Posiblemente para tu propósito el tipo de dispositivo más práctico sea CDC, mediante la emulación de un puerto serie virtual (en Windows se reconocería el dispositivo como un puerto COM en el administrador de dispositivos), prácticamente todos los lenguajes de programación cuentan con módulos para comunicación con puertos serie en todos los sistemas operativos, así que con este modo no debes tener ninguna restricción en cuanto a la herramienta que quieras elegir, por ejemplo con python puedes usar la biblioteca pyserial:
https://pythonhosted.org/pyserial/Hasta aquí tratamos de protocolo a nivel transferencia de datos, y ahora toca que definas el protocolo a nivel de tu aplicación, es decir, en concreto qué mensajes enviaras de uno a otro lado para entenderse, por ejemplo, pensando en que quisieras mover un servomotor a cierta posición o encender/apagar una salida digital, podrías considerar algo como esto:
| Comando | Descripción |
| CMD SERVO 90\r | Mover servo a posición 90° |
| CMD SALIDA 1\r | Encender salida |
| CMD SALIDA 0\r | Apagar salida |
En la tabla anterior describo un protocolo muy simple en que cada comando empieza con las letras CMD y termina con un retorno de carro, en el microcontrolador podrías acumular lo recibido por puerto serie hasta encontrar un retorno de carro y entonces analizar lo recibido.
Un protocolo como el anterior es muy simple de manejar desde una PC pero dependiendo la experiencia podría ser un poco complejo en un microcontrolador, algo más simple podría ser usar solamente caracteres, donde cada caracter enviado es una instrucción en específico, por ejemplo el caracter '0' serviría para apagar una salida, el '1' para encenderla, si tuvieras más salidas podrías continuar con un '2' para apagar la salida 2 y un '3' para apagarla, etc.
Un protocolo para comunicar instrucciones puede ser muchísimo más complejo que estos dos ejemplos muy simples que describo, pueden utilizar por ejemplo datos que no tienen representación en caracteres comunes (algunos le llamarían datos "binarios"), considerar que un paquete de comunicación contenga tanto una marca de inicio como una de fin, validaciones de la información transmitida (checksums), etc.
Espero haber dado una idea sobre tu duda, también si describes un poco más sobre lo que planeas transmitir entre la PC y la tarjeta podemos comentar sobre si lo anterior es suficiente o quizá tuvieras que utilizar algo diferente.
Lo olvidaba, si utilizas el compilador CCS, en esta página hay unos ejemplos en específico para el microcontrolador 18F4550:
https://picmania.garcia-cuervo.net/usb_0_desencadenado.php