Proyectos
 

USB 2.0 Microchip

Microchip permite mediante la programación de sus PIC realizar una comunicación
PIC<->PC de forma sencilla y eficaz.

Para ello usaremos la librería proporcianda por el propio fabricante llamada MPUSBAPI, gracias a la cual podemos escribir y leer en el PIC entre otras muchas otras cosas.

La velocidad de estos dispositivos es teóricamente de 12Mbit/seg, pero para ello necesitaríamos una programación compleja teniendo que abrir muchas pipes (tuberías) para poder alcanzar dicha velocidad.

 

Fundamentos

El USB es una comunicación serie de alta velocidad. Ha sustituido en gran medida al famoso puerto serie RS-232, ello se debe en gran medida a que el USB utiliza señales digitales TTL, mientras que el puerto serie utiliza señales digitales entre -12 y +12 voltios, además de la gran diferencia de velocidad de transmisión entre ambos dispositivos.

Existen en el mercado infinidad de conectores USB, entre los que destaca el puerto MiniUSB debido a su alta estandarización en dispositivos portátiles, sin dejar de lado al conector USB "normal" el cual usa nuestros ordenadores personales.

La velocidad de transferencia a ido aumentando rápidamente a lo largo de estos años. Caben destacar 3 de estos:

USB 1.0: baja velocidad (hasta 1.5Mbit/seg) usado en dispositivos de interfaz humana (HID) como ratones y teclados.

USB 2.0: Alta Velocidad (hasta 480Mbit/seg) unos 60Mg/seg.

USB 3.0: Giga Velocidad, en fase experimental, (hasta 4.8Gbit/seg) unos 600 Mg/seg. Los buses son mucho más rápido debido a la incorporación de una fibra óptica al enlace de cobre.

La transmisión del USB se realiza mediante un cable de cobre de par trenzado con una impedancía de unos 90 ohm llamados D+ y D-. Estos pueden dar energía a dispositivos externos, con una tensión de 5V y un máximo consimo de 500mA.

Existe actualmente en el mercado el dispositivo llamado USB OTG (On The Go), permitiendo actuar a un dispositivo como una PDA como servidor del enlace de datos, es por ello que podemos conectar a la PDA otros dispositivos USB como teclados o ratones.

 

Material necesario

Cuter y cables.
PIC 18F4225 o 18F4550.
Componentes electrónicos del esquemático.
Cable USB.
Programador de PIC correspondiente.

 

Teoría

Vamos a usar un PIC 18F4550 que gestione mediante software la comunicación USB2.0 con nuestro ordenadoraunque tambien se puede usar un PIC 18F2550, el cual configuraremos a nuestro gusto, donde le podremos poner el nombre de la empresa que queramos y el nombre de identificación de éste.

También hay que configurar dos parámetros esenciales en todo dispositivo que son el VID e ID.

VID (Vendor ID):

Es el identificador de la empresa. Cada empresa tiene un identificador, el cual puede vender diferentes productos a los que se les incluye el ID.

ID (Product ID):

Es el identificador del producto. Por tanto un dispositivo tendrá un VID e ID fijos que les hace únicos con lo que no pueden sufrir incompatibilidad con otros dispositivos.

 

Estos son únicos para cada dispositivo que existe en el mercado, ya que si hubiese en nuestro ordenador dos dispositivos con el mismo VID/ID causarían conflictos entre ellos, impidiendo el correcto funcionamiento de ambos.

¿Entonces cómo se soluciona que no haya conflictos entre dos dispositivos con la enorme cantidad de éstos en el mercado informático y electrónico?

La respuesta es muy sencilla, pagando para tener nuestro único e indivisible VID/ID, claro está que para trastear en casa no vamos a comprar un identificador para nuestro dispositivo, pero si queremos comercializarlo no nos quedará otra que comprar una "licencia".

 

Construcción

Primero ADVERTIR que el esquemático está realizado con un 18F4550 TQFP con lo que la numeración de las patillas difiere al integrado DIP (cucaracha). Lo que no difiere es el nombre o funcionalidad de éstas.

Aquí podéis encontrar la versión en OrCAD del esquemático más abajo en el punto Download de este mismo enlace.


Esquemático USB TQFP


Panorámica conexión 18F4550 DIP al portátil mediante USB

 

Programación PIC

La programación del PIC la hemos realizado a través de la aplicación CCS denominada PIC C Compiler, ya que en nuestra opinión es uno, por no decir el mejor y más sencillo complidor en C para microcontroladores.

El código principal para crear nuestro USB 2.0 es el siguiente además de convertir nuestro microcontrolador en una calculadora de operaciones lógicas mediante un programa en Visual C++ 2005.

#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VREGEN
#use delay(clock=12000000)

#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 1 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 3 //size to allocate for the rx endpoint 1 buffer

#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h> //Configuración del USB y los descriptores para este dispositivo
#include <usb.c> //handles usb setup tokens and get descriptor reports

#define LEDV PIN_B4
#define LEDR PIN_B5
#define LED_ON output_high
#define LED_OFF output_low

#define modo recibe[0]
#define param1 recibe[1]
#define param2 recibe[2]

#define resultado envia[0]

void main(void) {

int8 recibe[3]; //declaramos variables
int8 envia[1];

LED_OFF(LEDV); //encendemos led rojo
LED_ON(LEDR);

usb_init(); //inicializamos el USB

usb_task(); //habilita periferico usb e interrupciones
usb_wait_for_enumeration(); //esperamos hasta que el PicUSB sea configurado por el host

LED_OFF(LEDR);
LED_ON(LEDV); //encendemos led verde

while (TRUE)
{
if(usb_enumerated()) //si el PicUSB está configurado
{
if (usb_kbhit(1)) //si el endpoint de salida contiene datos del host
{
usb_get_packet(1, recibe, 3); //cojemos el paquete de tamaño 3bytes del EP1 y almacenamos en recibe

if (modo == 0) // Modo_Suma
{
resultado = param1 + param2; //hacemos la suma

usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}

if (modo == 1) // Modo_Led
{
if (param1 == 0)
{
LED_OFF(LEDV); LED_OFF(LEDR);
}
if (param1 == 1)
{
LED_ON(LEDV); LED_OFF(LEDR);
}
if (param1 == 2)
{
LED_OFF(LEDV); LED_ON(LEDR);
}
}

if (modo == 2) // Modo_XOR
{
LED_OFF(LEDV); LED_OFF(LEDR);
resultado = param1 ^ param2;
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}

if (modo == 3) // Modo_NOT
{
LED_ON(LEDV); LED_OFF(LEDR);
resultado = ~param1; //hacemos complementario

usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}

if (modo == 4) // Modo_OR
{
LED_ON(LEDV); LED_OFF(LEDR);
resultado = param1 | param2; //hacemos la suma

usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}

if (modo == 5) // Modo_AND
{
LED_ON(LEDV); LED_ON(LEDR);
resultado = param1 & param2; //hacemos la suma

usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de tamaño 1byte del EP1 al PC
}
}
}
}
}

Este programa está esperando a que haya una interrupción del usb, usb_kbhit(1), de haberla, metemos lo recibido en la variable recibe mediante la función, usb_get_packet. Ahora vemos que es lo que hemos recibido. recibe[0] indica el modo de operación (suma, AND, OR...), mientras que recibe[1] y recibe[2] con las variables para realizar la operación suma o lógica.

El microcontrolador realiza dicha operación y lo envía al ordenador en la variable envia mediante la función usb_put_packet.

Una cuestión muy importante es el PLL del PIC

Necesitamos que a nuestro micro le lleguen sólo 4MHz por lo que hay que usar un prescaler. Para ello en CCS se usa la sentencia PLLX, donde X significa la división de nuestro clock. Así pues si tenemos un cristal de 20MHz, el prescaler tendrá que ser 20 : 4 = 5 ->PLL5. Si por el contrario nuestro cristal es de 12MHz sería PLLl3.

Ahora bien, ¿Dónde personalizamos nuestro dispositivo?.

Esta se realiza en el archivo PicUSB.h en las siguientes líneas de código.

.....
.....
.....

//device descriptor
char const USB_DEVICE_DESC[] ={
USB_DESC_DEVICE_LEN, //the length of this report
0x01, //constant DEVICE (0x01)
0x10,0x01, //usb version in bcd
0x00, //class code (if 0, interface defines class. FF is vendor defined)
0x00, //subclass code
0x00, //protocol code
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8)
0xD8,0x04, //vendor id (0x04D8 is Microchip)
0x11,0x00, //product id

0x01,0x00, //device release number
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below)
0x02, //index of string descriptor of the product
0x00, //index of string descriptor of serial number
USB_NUM_CONFIGURATIONS //number of possible configurations
};

.....
.....
.....

Hacer notar que la numeración hexadecimal de la descripción del VID / ID va al revés, es decir, el primero número hex. será el último y viceversa.

.....
.....
.....

char const USB_STRING_DESC[]={
//string 0
4, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
0x09,0x04, //Microsoft Defined for US-English
//string 1 --> la compañia del producto ???
8, //length of string index (número de letras + 1)*2->(3 + 1)*2=4*2=8
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'J',0,
'V',0,
'R',0,
//string 2 --> nombre del dispositivo
34, //length of string index (número de letras + 1)*2->(16 + 1)*2=17*2=34
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'U',0,
'S',0,
'B',0,
' ',0,
'M',0,
'U',0,
'C',0,
'H',0,
'O',0,
' ',0,
'T',0,
'R',0,
'A',0,
'S',0,
'T',0,
'O',0
};

#ENDIF

La longitud de la cadena tiene que ser exacta, sino saldrán caracteres que no tienen que ver con nuestro dispositivo si el número de la cadena es mayor o se suprimirán caracteres si el número de la cadena es inferior, para ello hay una fórmula muy sencilla que es:

(Número de letras + 1)*2 = longitud a poner

Ejemplo en string1 queremos poner JVR, esta tiene 3 caracteres por tanto:

longitud a poner = ( 3 + 1 ) + 2 = 4 + 2 = 8

 

Instalación PIC

Para que nuestro dispositivo sea detectado por el ordenador lo primero que tenemos que hacer es configurar nuestro driver. Para ello abriremos con el archivo mchpcdc.inf.

; Installation file for mchpusb driver
; Copyright (C) 2004 by Microchip Technology, Inc.
; All rights reserved

[Version]
Signature=$CHICAGO$
Class=Unknown
ClassGuid={4D36E97E-E325-11CE-BFC1-08002BE10318}
Provider=%ONEYSOFT%
CatalogFile=mchpusb.cat
DriverVer=12/13/2005

[Manufacturer]
%MFGNAME%=DeviceList

[DestinationDirs]
DefaultDestDir=10,System32\Drivers

[SourceDisksFiles]
mchpusb.sys=1
wdmstub.sys=1

[SourceDisksNames]
1=%INSTDISK%,,,

[DeviceList]
%DESCRIPTION%=DriverInstall,USB\VID_04D8&PID_0011 ; Modificable

;------------------------------------------------------------------------------
; Windows 2000/XP Sections
;------------------------------------------------------------------------------

[DriverInstall.ntx86]
CopyFiles=DriverCopyFiles

[DriverCopyFiles]
mchpusb.sys,,,2

[DriverInstall.ntx86.Services]
AddService=MCHPUSB,2,DriverService

[DriverService]
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%10%\system32\drivers\mchpusb.sys
AddReg=TraceFlags

;------------------------------------------------------------------------------
; Windows 98/Me Sections
;------------------------------------------------------------------------------

[DriverInstall]
AddReg=DriverAddReg
CopyFiles=DriverCopyFiles,StubCopyFiles
DriverVer=20/12/2007 ; Modificable

[DriverAddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,"wdmstub.sys,mchpusb.sys"

[StubCopyFiles]
wdmstub.sys,,,2

;------------------------------------------------------------------------------
; String Definitions
;------------------------------------------------------------------------------

[Strings] ; Modificable
ONEYSOFT="Muchotrasto Soft"
MFGNAME="Muchotrasto.com"
DESCRIPTION="Muchotrasto.com USB2.0"

Una vez configurado el driver a nuestro gusto, pasaremos a la instalación del puerto USB.

Lo primero será conectar nuestro dispositivo a algún puerto usb libre que tengamos. Posteriormente tendremos que seguir los mismos pasos que para instalar nuestro VCP, lo podeís encontrar en este enlace.

Emulación CDC RS-232 USB

 

Programación PC

Para comprobar que nuestro programita funcione perfectamente hemos realizado un programa en Visual C++ 2005 donde el microcontrolador se encarga de realizar las operaciones matemáticas y luego envía el resultado al ordenador.


Captura de PicCalculadoraUSB en Visual C++ 2005

Podéis encontrar como hacer este ejemplo de aplicación e incluso descargaros el código fuente en el enlace:

PIC Calculadora USB.

 

Download

Esquemático en OrCAD.

Proyecto PIC en CCS.

Drivers USB Muchotrasto.

 
 



Inicio | Foro | FAQ | MapaWeb | BuscadorWeb