Los proyectos de PicUsb para PC suelen estar en VisualBasic, C++ y Delphi.
Os propongo otro lenguaje de programación, parecido al QBasic pero es mucho más potente, gratis y es para plataformas de 32 bits; me refiero a
FreeBasic.Está basado en los ejemplos en CCS que a lo largo de este tiempo han ido desarrollando J1M (un saludo y un fuerte abrazo), y también:
* J1M (
http://hobbypic.com/ ) él mismo.
* Pedro (
http://www.unpocodelectronica.netau.net/mis-primeros-pasos-con-el-18f4550 )
* MigSantiago (
http://www.migsantiago.com )
* Slalen (
http://slalen.ifastnet.com/ )
El programa en
FreeBasic maneja el modo "Bulk Transfer" usando la librería MPUSBAPI.DLL.
Antes de nada agradecer y reconocer a MichaelW de FreeBasic Forum la ayuda que me ofreció para poder implementar la librería MPUSBAPI.DLL en FreeBasic.
El programa hace lo siguiente:
1) Enviamos al PIC dos números para sumar.
2) El PIC nos devuelve el resultado al PC y también lo saca a través de 8 LED.
Nota: Aunque declaramos 64 bytes para enviar y recibir, sólo usaremos dos bytes para enviar y un byte para recibir.
FreeBasic code:
#Inclib "mpusbapi"
#Include Once "windows.bi"
Extern "C"
Declare Function MPUSBGetDLLVersion Alias "_MPUSBGetDLLVersion" () As Integer
Declare Function MPUSBGetDeviceCount Alias "_MPUSBGetDeviceCount" _
(ByVal pVid_Pid As ZString Ptr) As Integer
Declare Function MPUSBOpen Alias "_MPUSBOpen" _
(ByVal instance As Integer, _
ByVal pVid_Pid As ZString Ptr, _
ByVal pEP As ZString Ptr, _
ByVal dwDir As Integer, _
ByVal dwReserved As Integer) As Integer
Declare Function MPUSBRead Alias "_MPUSBRead" _
(ByVal handle As Integer, _
ByVal pData As Byte Ptr, _
ByVal dwLen As Integer, _
ByRef pLength As Integer Ptr, _
ByVal dwMilliseconds As Integer) As Integer
Declare Function MPUSBWrite Alias "_MPUSBWrite" _
(ByVal handle As Integer, _
ByVal pData As Byte Ptr, _
ByVal dwLen As Integer, _
ByRef pLength As Integer Ptr, _
ByVal dwMilliseconds As Integer) As Integer
Declare Function MPUSBReadInt Alias "_MPUSBReadInt" _
(ByVal handle As Integer, _
ByVal pData As Byte Ptr, _
ByVal dwLen As Integer, _
ByRef pLength As Integer Ptr, _
ByVal dwMilliseconds As Integer) As Integer
Declare Function MPUSBClose Alias "_MPUSBClose" _
(ByVal handle As Integer) As Integer
End Extern
Const MP_WRITE = 0
Const MP_READ = 1
Const OutPipe = "\MCHP_EP1"
Const InpPipe = "\MCHP_EP1"
Dim As Integer Version
Dim As Integer MyInpPipe
Dim As Integer MyOutPipe
Dim As Integer SentDataLength
Dim As Integer RecdDataLendth
Dim As Integer DevCount
Dim As UByte Put2PIC( 0 To 63 )
Dim As UByte Get2Pic( 0 To 63 )
Dim Vid_Pid As String = "vid_04d8&pid_0011"
DevCount = MPUSBGetDeviceCount( StrPtr( Vid_Pid ) )
Print "Device Counts : "; DevCount
Version = MPUSBGetDLLVersion()
Print "MPUSBAPI.DLL Version : "; Hex( Version )
MyOutPipe = INVALID_HANDLE_VALUE
MyInpPipe = INVALID_HANDLE_VALUE
MyOutPipe = MPUSBOpen( 0, Vid_Pid, OutPipe, MP_WRITE, 0 )
MyInpPipe = MPUSBOpen( 0, Vid_Pid, InpPipe, MP_READ, 0 )
Print "Out Pipe : "; Hex(MyOutPipe)
Print "Inp Pipe : "; Hex(MyInpPipe)
If ( MyOutPipe = INVALID_HANDLE_VALUE ) Or _
( MyInpPipe = INVALID_HANDLE_VALUE ) Then
Print "Pipers Error!"
MPUSBClose ( MyInpPipe )
MPUSBClose ( MyOutPipe )
Sleep
End
EndIf
Print
Print "Suma de dos cifras. El resultado no ha de ser mayor de 255."
Print
Input "ADD1 (Ejemplo: 0..127)"; Put2PIC(0)
Input "ADD2 (Ejemplo: 0..127)"; Put2PIC(1)
MPUSBWrite(myOutPipe, @Put2PIC(0), 2, @SentDataLength, 1000)
MPUSBRead (myInpPipe, @Get2PIC(0), 1, @RecdDataLendth, 1000)
Print "La inteligencia artificial del PIC piensa que es...: "; Get2PIC(0)
MPUSBClose ( MyInpPipe )
MPUSBClose ( MyOutPipe )
Sleep
End
Importante:
* El contenido de la variable Vid_Pid = "vid_04d8&pid_0011" debe ser en minúsculas. Si lo pones en mayúsculas no funcionará.
* "\MCHP_EP1" nota que sólo tiene una '\', como en VisualBasic. En C++ y Delphi son dos '\\'.
CCS code:
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
#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 2 //size to allocate for the rx endpoint 1 buffer
#include <pic18_usb.h> //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include "usb_desc_scope.h" //Enumerator Palitroquez!
#include <usb.c> //handles usb setup tokens and get descriptor reports
#use fast_io(b) //you have to manually configure TRISB
void main(void) {
int8 recibe[2];
int8 envia[1];
set_tris_b(0x00); //All PortB outputs
output_b(0x00); // PortB off
setup_adc (adc_clock_div_32); //No ADC, no comparators...
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
usb_init(); //init USB
usb_task(); //enable usb device and interruptions
usb_wait_for_enumeration(); //wait
output_high(PIN_B7); // the PortB.7 LED blink 3 times.
delay_ms(500);
output_low(PIN_B7);
delay_ms(500);
output_high(PIN_B7);
delay_ms(500);
output_low(PIN_B7);
delay_ms(500);
output_high(PIN_B7);
delay_ms(500);
output_low(PIN_B7);
delay_ms(500);
while (true)
{
if(usb_enumerated()) //if PicUSB is configurated
{
if (usb_kbhit(1)) //if it contains data
{
usb_get_packet(1, recibe, 2); //Take two bytes, which will
//then be recibe[0] and recibe[1]
envia[0]=recibe[0]+recibe[1]; //add the two received data
output_b(envia[0]); //the result will be seen by PortB (with 8 LED)
usb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //moreover,
//sends the result to PC.
}
}
}
}
Puedes cambiar la PIC:
# Include <18F4550.h>
por (por ejemplo):
# Include <18F2550.h>
Mientras respete el tipo 18Fxx5x. Lo he probado y va bien.
Nota:
Los "fuses" del programa CCS están configurados para tener un cristal de 20 MHz. Si quieres poner uno de 4 MHz has de cambiar la línea donde pone #fuses... por:
#fuses XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
Sólo para cristales de 4MHz o menor cambiamos HSPLL por XTPLL.
PLLx cambia la 'x' dependiendo del cristal que pongamos:
PLL1 = 4MHz y sería XTPLL
PLL2 = 8MHz y sería HSPLL
PLL3 = 12MHz y sería HSPLL.
PLL4 = 16MHz y sería HSPLL.
PLL5 = 20MHz y sería HSPLL.
En el fichero "usb_desc_scope.h" está el Vid_Pid para el PIC. Esto es muy importante. Si usas otro Vid & Pid tendrías que modificarlo también en el fichero mencionado (usb_desc_scope.h).
Todo el proyecto lo puedes bajar desde aquí:
https://sites.google.com/site/roboticproyects/picusbEstán todo lo necesario, es decir, el código fuente y ejecutable en FreeBasic, en CCS (.C y .HEX), los drivers de instalación para el PIC y el fichero usb_desc_scope.h
Si usas FreeBasic, para compilar el código fuente has de tener la librería "libmpusbapi.dll.a" para FreeBasic. También está incluida en el zip de descarga y has de ponerla en C:..\FreeBASIC\lib\win32. Más información aquí:
http://www.freebasic.net/forum/viewtopic.php?t=15812Está probado en WinXP y Colossus Edition 2 Reloaded.
Saludos.