TODOPIC
Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: Oceano en 13 de Julio de 2010, 19:25:00
-
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/picusb
Está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=15812
Está probado en WinXP y Colossus Edition 2 Reloaded.
Saludos.
-
Saludos, me ha interesado FreeBasic desde hace algun tiempo ya que con las librerias de OpenGL que incorpora he logrado hacer algunas animaciones interesantes, todo orientado al lado de la simulacion de robots, en fin, he tratado de compilar el programa que posteas en FreeBasic IDE 0.4.6 y me arroja el siguiente mensaje de error:
Error nr: 14
Mensaje: Expected identifier, found: 'C'
Extern "C"
^
He seguido los pasos que indicas para poder compilar asi que no se cual sera mi error, espero puedas ayudarme...
-
Te felicito Oceano y te doy las gracias por compartir el proyecto
:)
-
Ya di con el problema. Una vez corregido todo marcha OK!!!