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
}
}