Comunicación USB, Pic C Compiler

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
   }

}
PCBWay2
Scroll al inicio