
En esta sección aprenderÔs a realizar una comunicación USB mediante la computadora y el microcontrolador PIC, el objetivo es enviar comandos al microcontrolador para encender y/o apagar los LEDs utilizando un monitor serial en la computadora.
Comunicación USB
La comunicación USB (Universal Serial Bus) funciona mediante un protocolo estandarizado que permite la transferencia de datos y la conexión de dispositivos electrónicos. El protocolo USB se basa en la estructura de «maestro-esclavo», donde un dispositivo actúa como el maestro (anfitrión) y controla uno o mÔs dispositivos esclavos (dispositivos USB).
Microchip ofrece una variedad de microcontroladores PIC con capacidades USB integradas, lo que permite que estos dispositivos se comuniquen con una computadora o funcionen como dispositivos USB en sĆ mismos.

Monitor serial
Para realizar la comunicación entre el microcontrolador y la computadora, se utiliza un monitor serial para enviar, recibir y graficar los datos.
Descarga en un archivo .zip, lo extraes en la computadora y abres la aplicación QTseralMonitor.
Circuito de conexión

Procedimiento
Inicialmente en el archivo .h se define el oscilador del microcontrolador, y se habilita la velocidad de la comunicación USB.
#use delay(clock=48MHz,crystal=20MHz,USB_FULL)
Se establece la corriente de funcionamiento necesaria para que el microcontrolador se conecte mediante USB.
#define USB_CONFIG_BUS_POWER 500 //500ma corriente de entrada
Para la comunicación USB se utiliza la siguiente librerĆa.
#include "usb_cdc.h"
Se inicializa la comunicación USB.
usb_init();
En la subrutina recibe(), se recibe la cadena de caracteres o el comando, utilizando la función «usb_cdc_getc()» y en la sentencia «if()» espera el carÔcter «\r\n» para saber cuando terminara de recibir los datos.
void recibe()
{
memset(recibido, 0, sizeof(recibido)); //limpia los registros de la varible
int8 i=0;
while(true)
{
recibido[i] = usb_cdc_getc();//RECIBE EL CARACTER
if(recibido[i] == '\n')//busca el salto de linea \r\n
{
recibido[i-1] = '\0'; // \r = \0 (caracter nulo)
recibido[i] = '\0'; // \n = \0 (caracter nulo)
leds();
return;
}
i++;
}
}
En la subrutina «leds()» inicialmente se colocan los comandos que se pueden recibir para después hacer la comparación con los comandos recibidos.
void leds()
{
signed int8 result;
char LED1_ON[8] = "LED1_ON";
char LED1_OFF[9] = "LED1_OFF";
char LED2_ON[8] = "LED2_ON";
char LED2_OFF[9] = "LED2_OFF";
char LED3_ON[8] = "LED3_ON";
char LED3_OFF[9] = "LED3_OFF";
.
.
.
Los siguiente es utilizar la función «strcmp()» para comparar el comando recibido con los diferentes comandos declarados, cuando la comparación resulta igual, la función devuelve «0» y entrara a la sentencia «if()» para encender o apagar el LED correspondiente al comando recibido.
result = strcmp(recibido, LED1_ON);//compara, si son iguales (0), no (+-1)
if(result==0)
{
OUTPUT_BIT(LED1,1);
return;
}//enciende el led1
result = strcmp(recibido, LED1_OFF);
if(result==0)
{
OUTPUT_BIT(LED1,0);
return;
}
.
.
.
Finalmente antes de colocar la librerĆa Ā«usb_cdc.hĀ», se define la interrupción por recepción de datos USB, colocando la subrutina en este caso Ā«recibe()Ā» y despuĆ©s de definirla se declara la subrutina Ā«void recibe();Ā»
#define USB_CDC_ISR() recibe() //Interrupcion por recepcion de datos
void recibe();//Subrutina de la interrupcion
Código completo
#FUSES NOMCLR
#define USB_CDC_ISR() recibe() //Interrupcion por recepcion de datos
void recibe();//Subrutina de la interrupcion
#define USB_CONFIG_BUS_POWER 500 //500ma corriente de entrada
#include "usb_cdc.h"
#define LED1 PIN_D0
#define LED2 PIN_D1
#define LED3 PIN_D2
char recibido[15];
void leds();
void recibe()
{
memset(recibido, 0, sizeof(recibido)); //limpia los registros de la varible
int8 i=0;
while(true)
{
recibido[i] = usb_cdc_getc();//RECIBE EL CARACTER
if(recibido[i] == '\n')//busca el salto de linea \r\n
{
recibido[i-1] = '\0'; // \r = \0 (caracter nulo)
recibido[i] = '\0'; // \n = \0 (caracter nulo)
leds();
return;
}
i++;
}
}
void leds()
{
signed int8 result;
char LED1_ON[8] = "LED1_ON";
char LED1_OFF[9] = "LED1_OFF";
char LED2_ON[8] = "LED2_ON";
char LED2_OFF[9] = "LED2_OFF";
char LED3_ON[8] = "LED3_ON";
char LED3_OFF[9] = "LED3_OFF";
while (true)
{
result = strcmp(recibido, LED1_ON);//compara, si son iguales (0), no (+-1)
if(result==0)
{
OUTPUT_BIT(LED1,1);
return;
}//enciende el led1
result = strcmp(recibido, LED1_OFF);
if(result==0)
{
OUTPUT_BIT(LED1,0);
return;
}
result = strcmp(recibido, LED2_ON);
if(result==0)
{
OUTPUT_BIT(LED2,1);
return;
}
result = strcmp(recibido, LED2_OFF);
if(result==0)
{
OUTPUT_BIT(LED2,0);
return;
}
result = strcmp(recibido, LED3_ON);
if(result==0)
{
OUTPUT_BIT(LED3,1);
return;
}
result = strcmp(recibido, LED3_OFF);
if(result==0)
{
OUTPUT_BIT(LED3,0);
return;
}
return;
}
}
void main()
{
usb_init();
while(TRUE)
{
//TODO: User Code
}
}