Autor Tema: PIC USB con FreeBasic.  (Leído 4076 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Oceano

  • PIC10
  • *
  • Mensajes: 22
    • Proyectos Roboticos.
PIC USB con FreeBasic.
« 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:

Código: [Seleccionar]

#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:

Código: [Seleccionar]

#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:

Código: [Seleccionar]
#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.
« Última modificación: 16 de Agosto de 2010, 17:56:17 por Oceano »

Desconectado agauss

  • PIC16
  • ***
  • Mensajes: 147
Re: PIC USB con FreeBasic.
« Respuesta #1 en: 07 de Septiembre de 2010, 17:55:44 »
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...
No es el conocimiento, sino el acto de aprendizaje, y no la posesión, sino el acto de llegar allí, que concede el mayor disfrute.
"Carl Friedrich Gauss"

El tacto es el arte de hacer un punto sin hacer un enemigo.
"Isaac Newton"

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: PIC USB con FreeBasic.
« Respuesta #2 en: 08 de Septiembre de 2010, 14:42:01 »
Te felicito Oceano y te doy las gracias por compartir el proyecto

 :)

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado agauss

  • PIC16
  • ***
  • Mensajes: 147
Re: PIC USB con FreeBasic.
« Respuesta #3 en: 10 de Septiembre de 2010, 19:23:36 »
Ya di con el problema. Una vez corregido todo marcha OK!!!
No es el conocimiento, sino el acto de aprendizaje, y no la posesión, sino el acto de llegar allí, que concede el mayor disfrute.
"Carl Friedrich Gauss"

El tacto es el arte de hacer un punto sin hacer un enemigo.
"Isaac Newton"