71113661 Mis Primeros Pasos Con El 18F4550
-
Upload
luis-pariapaza-rumiche -
Category
Documents
-
view
249 -
download
2
Transcript of 71113661 Mis Primeros Pasos Con El 18F4550
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
1/35
Mis Primeros pasos con el 18F4550
(http://www.unpocodelectronica.netau.net/mis-primeros-pasos-con-el-
18f4550) Introduccin Etapa Osciladora Conociendo el PiN1 MCLR PORTx vs LATx Mdulo CAD o ADC (I) Mdulo CAD o ADC (II) Primera Prctica: PiCUSB USB CDC (I) USB CDC (II) Monitorear el puerto COM virtual Detectando el HOST (I) Detectando el HOST (II)
Primera Aplicacin CDC Conociendo al SnoopyPRO mpusbapi.dll (I) mpusbapi.dll (II) mpusbapi.dll (III) mpusbapi.dll (parte 4) mpusbapi.dll (parte 5) mpusbapi.dll (Primera Aplicacin) Agradecimientos y Mritos Correspondientes
Estudio de mpusbapi.dll (parte I)
vamos a estudiar en forma la transmisin USB usando la biblioteca de vnculo dinmicompusbapi.dll y que mejor que empezar con el ejemplo de J1M. hay que tener una ideade porque Jaime utiliz esas llamadas a los drivers y que hace cada una de ellas.
hay muchas preguntas en cuanto a este tipo de transmisin, por ejemplo:
podemos transmitir a 12Mbits/seg en lenguaje C?si estamos ejecutando un proceso de muestreo, podremos llegar a esa velocidad?
las posibles respuestas a estas, sin nimo de desilusionar a nadie (incluyndome) veanesto (mitos y realidades pgina 9 de 858_USB.pdf):
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
2/35
Mitos y verdades acerca del USB
una cosa que hay que tener en consideracin y sobre todo para lo que estudiamos esto
en lenguaje de alto nivel, el protocolo de transmisin USB tambin lo llaman la pilaUSB
reas Implementadas de la pila USB
observen que tiene cierto parecido al modelo OSI. en las capas superiores tenemos lasfunciones bsicas que el usuario puede realizar (comunicacin lgica). esto a su vez vaa parar a la segunda capa y luego a la tercera capa(comunicacin fsica) que involucra elaspecto elctrico. En nuestro caso estaramos directamente metidos en la capa superior,
pero algunas veces entrando en las otras dos:
primera capa(superior): programacin bsica en C.segunda capa(intermedio): llamados a los drivers que trae el compilador de C.tercera capa(inferior): llamados a los drivers que trae el compilador de C (procesosdentro de los drivers) y conexin del mdulo USB al HOST.
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag26_usb2.0.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag9_858_usb.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
3/35
esta tema es fascinante pero a la vez extenso, as que hay que ir por partes para noperdernos.
ESTUDIO DEL LADO DEL PIC:
por lo pronto lo que hay que hacer, es estudiar los drivers que trae el CCS (que es elcompilador de C que uso), estos son:
- pic18_usb.h- PicUSB.h- usb.c- usb.h
tratando de meter un poco de teora a cada lnea que nos encontremos y siguiendo elmismo mtodo anterior: analizando el cdigo a la inversa.
veamos el cdigo reza as:
//// PicUSB.c //////// //////// Este ejemplo muestra como desarrollar un sencillo dispositivo //////// USB con el PIC18F2550, aunque puede ser facilmente adaptado //////// para la serie 18Fxx5x. Se suministra el PicUSB.exe, as como ////
//// su cdigo fuente para Visual C# 2005, podris encontrar tb //////// los drivers para el dispositivo. No se suministra esquema de //////// conexin puesto que est pensado para ser usado en el GTP USB, //////// cualquiera de las tres versiones disponibles, si aun no teneis //////// el programador, podeis utilizar el esquema de ese proyecto. //////// //////// Cuando el dispositivo sea conectado al PC, saldr el asistente //////// para la instalacin del driver. Instala el suministrado junto //////// a este ejemplo, lo encontrareis dentro de la carpeta Driver. //////// Una vez instalado podreis usar el PicUSB.exe para encender o //////// apagar el led bicolor del GTP USB, y para realizar la suma de ////
//// dos nmeros introducidos. //////// //////// Realizado con el compilador CCS PCWH 3.227 //////// //////// Por: Jaime Fernndez-Caro Belmonte [email protected] //////// //////// http://www.hobbypic.com /////////////////////////////////////////////////////////////////////////////#include //#fusesHSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,CPUDIV1,VRE
GEN
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
4/35
#fusesXTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN // el fuse// modificado para USB -> VREGEN#use delay(clock=48000000)
///////////////////////////////////////////////////////////////////////////////// CCS Library dynamic defines. For dynamic configuration of the CCS Library// for your application several defines need to be made. See the comments// at usb.h for more information///////////////////////////////////////////////////////////////////////////////#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivasHID#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
///////////////////////////////////////////////////////////////////////////////// If you are using a USB connection sense pin, define it here. If you are// not using connection sense, comment out this line. Without connection// sense you will not know if the device gets disconnected.// (connection sense should look like this:// 100k// VBUS-----+----/\/\/\/\/\----- (I/O PIN ON PIC)// |// +----/\/\/\/\/\-----GND// 100k// (where VBUS is pin1 of the USB connector)///////////////////////////////////////////////////////////////////////////////
//#define USB_CON_SENSE_PIN PIN_B2 //CCS 18F4550 development kit hasoptional conection sense pin///////////////////////////////////////////////////////////////////////////////// Include the CCS USB Libraries. See the comments at the top of these// files for more information///////////////////////////////////////////////////////////////////////////////#include //Microchip PIC18Fxx5x Hardware layer for CCS's PICUSB driver
#include //Configuracin del USB y los descriptores para estedispositivo
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
5/35
#include //handles usb setup tokens and get descriptor reports
///////////////////////////////////////////////////////////////////////////////
// Al conectar el PicUSB al PC encendemos el Led Rojo hasta que el dispositivo// halla sido configurado por el PC, en ese momento encederemos el Led Verde.// Esperaremos hasta que se reciba un paquete proveniente del PC. Comprobaremos// el primer byte del paquete recibido para comprobar si queremos entrar en el// modo Suma, donde se realizar una suma de dos operandos, que corresponderan// con los dos bytes restantes del paquete recibido; una vez realizada la suma// enviaremos el paquete con el resultado de vuelta al PC. Si entramos en el// modo Led comprobaremos el segundo byte del paquete recibido para comprobar// si deberemos apagar los leds, encender el verder o el rojo.///////////////////////////////////////////////////////////////////////////////
#define LEDV PIN_B6#define LEDR PIN_B7#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 variablesint8 envia[1];
LED_OFF(LEDV); //encendemos led rojoLED_ON(LEDR);
usb_init(); //inicializamos el USB
usb_task(); //habilita periferico usb e interrupcionesusb_wait_for_enumeration(); //esperamos hasta que el PicUSB sea configurado porel 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{
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
6/35
usb_get_packet(1, recibe, 3); //cojemos el paquete de tamao 3bytes del EP1 yalmacenamos en recibe
if (modo == 0) // Modo_Suma{
resultado = param1 + param2; //hacemos la sumausb_put_packet(1, envia, 1, USB_DTS_TOGGLE); //enviamos el paquete de
tamao 1byte del EP1 al PC}
if (modo == 1) // Modo_Led{
if (param1 == 0) {LED_OFF(LEDV); LED_OFF(LEDR);} //apagamos losleds
if (param1 == 1) {LED_ON(LEDV); LED_OFF(LEDR);} //encendemos led
verdeif (param1 == 2) {LED_OFF(LEDV); LED_ON(LEDR);} //encendemos led
rojo}
}}
}}
all estn las funciones usb_task(), usb_init() que ya las vimos por encimita, la novedadson las funciones: usb_wait_for_enumeration(), usb_get_packet y usb_put_packet
tambin estn las definiciones USB_EP1_TX_ENABLE USB_ENABLE_BULK
comencemos por el principio (lgico no? )
--------------------------------------------------------------------------------#define USB_HID_DEVICE FALSE //deshabilitamos el uso de las directivas HID
Qu significa HID?
HID es acrnimo en espaol de Dispositivo de Interfaz Humana como bien lo describeDiego en su artculo EL USB DESENCADENADO : HID USB
y resulta que en los drivers del CCS viene activado por defecto.
si lo vamos a usar, no colocamos nada. si NO lo usaremos, lo negamos en el define (estprogramado al revs, digo yo )#define USB_EP1_TX_ENABLE USB_ENABLE_BULK //turn on EP1(EndPoint1)
for IN bulk/interrupt transfersque es eso de endpoint? bulk/interrup transfers?
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
7/35
voy a colocar aqu una explicacin que me pareci excelente tomada de un proyectoespecial de grado link Capitulo 3: Bus Serie Universal, funcionamiento Pg. 38
cita:...
"Los dispositivos (o mejor dicho, las funcionas) tienen asociados unos canaleslgicos unidireccionales (llamados pipes) que conectan al host controlador conuna entidad lgica en el dispositivo llamada endpoint. Los datos son enviadosen paquetes de largo variable (potencia de 2). Tpicamente estos paquetes sonde 64, 128 o ms bytes.Estos endpoints (y sus respectivos pipes) son numerados del 0 al 15 en cadadireccin, por lo cual un dispositivo puede tener hasta 32 endpoints (16 deentrada y 16 de salida). La direccin se considera siempre desde el punto devista del host controlador. As un endpoint de salida ser un canal quetransmite datos desde el host controlador al dispositivo. Un endpoint solo
puede tener una nica direccin. El endpoint 0 (en ambas direcciones) est
reservado para el control del bus."...
Se puede decir que los endpoint son buffer temporales de datos de entrada/salida encada tipo. En el mdulo USB existen 16 de salida (OUT) y 16 de entrada (IN) peroagrupados en forma bidirecional, de acuerdo a un par de bits de configuracin (ver Pg.171). Ojo un endpoint es unidireccional.
para quien tenga dudas con el pipe, una imagen representativa:
Flujo de Comunicacin del USB
respecto a la otra pregunta, existen 4 tipos de transferencias: transferencias de control:usado para comandos (y respuestas) cortos y simples. Es el tipo de transferencia usada
por el pipe 0
transferencias iscronas:
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag33_usb2.0.JPG -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
8/35
proveen un ancho de banda asegurado pero con posibles prdidas de datos. Usadotpicamente para audio y video en tiempo real
transferencias interruptivas:para dispositivos que necesitan una respuesta rpida (poca latencia), por ejemplo,
mouse y otros dispositivos de interaccin humana.
transferencias masivas (BULK):para transferencias grandes y espordicas utilizando todo el ancho de banda disponible,
pero sin garantas de velocidad o latencia. Por ejemplo, transferencias de archivos.entonces nosotros debemos definir que tipo de transferencia vamos a realizar.en el ejemplo de Jaime se estn declarando 2 endpoints (1 bidirecionales) comotransferencia masiva o BULK.
#define USB_EP1_TX_SIZE 1 //size to allocate for the tx endpoint 1 buffer
podemos definir el tamao del buffer en bytes, el lmite lo tendremos que buscar en eldriver correspondiente (con FS hasta 64 bytes por transaccin).nota: no confundir FS con HS, con High Speed se llega hasta 480Mbps, el mdulo USBdel pic soporta Full Speed = 12Mbps
usb_wait_for_enumeration() segn el concepto que dan en el driver, hace lo mismo queusb_enumerated(). La diferencia est en que el primero se queda en un bucle indefinidohasta que el HOST le d la orden de habilitacin.
para propsitos donde queramos hacer otras actividades en el PIC, usaremos el segundo.ahora hablaremos de como se hace para transmitir y recibir datos. para eso estnusb_put_packet(,,) y usb_get_packet(,,) ambas necesitan de 3 argumentos. vamos con
put_packet:
.../* usb_put_packet(endpoint,*ptr,len,toggle)/*/* Input: endpoint - endpoint to send packet to/* ptr - points to data to send/* len - amount of data to send/* toggle - whether to send data with a DATA0 pid, a DATA1 pid, or toggle fromthe last DATAx pid.
/*/* Output: TRUE if data was sent correctly, FALSE if it was not. The only reason itwill/* return FALSE is if because the TX buffer is still full from the last time you/* tried to send a packet./*/* Summary: Sends one packet out the EP to the host. Notice that there is a difference/* between a packet and a message. If you wanted to send a 512 byte message you/* would accomplish this by sending 8 64-byte packets, followed by a 0 length
packet./* If the last (or only packet) being sent is less than the max packet size defined
/* in your descriptor then you do not need to send a 0 length packet to identify/* an end of message.
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
9/35
...
el 1 argumento endpoint ya se explic.- el 2 argumento apunta a la direccin del dato a enviar (es una variable declarada por
nosotros).
- el 3 argumento es el tamao del paquete en bytes.- el 4 argumento habla sobre DATA1, DATA2, toggle. y eso que es?
como parte de su protocolo, nos encontraremos entre otras cosas que USB maneja latransmisin de datos por paquetes, llamados TOKEN en la cul el HOST es el iniciadorde todas las transferencias que se producen en el BUS [2]
Los paquetes de datos
pues bien en la parte de transmisin de datos USB, los paquetes de datos se encuentranen grupos de paquetes de datos, y dentro de estos, existen unos llamados DATA0,DATA1. hay un proceso llamado sincronizacin del data toggle. a grandes rasgos estono es mas que un mtodo de validacin de paquetes, y lo que hace es enviaralternadamente a DATA0 y DATA1 en una secuencia seguido de su ACK respectivo.todo con el objetivo de mantener la sincronizacin transmisor receptor.
Transacciones Consecutivas
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag233_usb_20.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag206_usb_20.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
10/35
ese tercer argumento definido en el cdigo ejemplo: USB_DTS_TOGGLE
enum USB_DTS_BIT {USB_DTS_DATA1=1, USB_DTS_TOGGLE=2,USB_DTS_DATA0=0,
USB_DTS_STALL=3, USB_DTS_USERX=4};
segn la pgina 174 de 39632c.pdf el data toggle est definido por un bit llamadoDTSEN y es mas, all lo explican.
Bit DTSEN en recepcin de paquetes
hay toda una teora en lo relacionado a los grupos de paquetes, no lo mencionar parano salirme del objetivo principal.seguro alguien preguntar, y si yo no quiero usar la sincronizacin del data toggle?esto depende del tipo de transferencia a usar, hay casos donde es recomendable usarlo.ej: transferencias de mltiples transacciones y casos donde no se puede usar. para mayor
informacin ver paginas 56 y 232 de usb_20.pdf
usb_get_packet()
/*******************************************************************************/* usb_get_packet(endpoint, *ptr, max)/*/* Input: endpoint - endpoint to get data from/* ptr - where to save data to local PIC RAM
/* max - max amount of data to receive from buffer/*/* Output: the amount of data taken from the buffer./*/* NOTE - IF THERE IS NO PACKET TO GET YOU WILL GET INVALIDRESULTS!/* VERIFY WITH USB_KBHIT() BEFORE YOU CALLUSB_GET_PACKET()!/*/* Summary: Gets a packet of data from the USB buffer and puts into local PIC RAM./* Until you call usb_get_packet() the data will sit in the endpoint/* buffer and the PC will get NAKs when it tries to write more data/* to the endpoint.
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/pag174_39632c.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
11/35
...
el argumento 1 es el buffer de datos de entrada, donde llega el paquete de datos.el argumento 2 es el apuntador adonde guardaremos ese dato.el argumento 3 es el tamao de paquete en bytes.
-vaya- se fue todo en pura teora, entonces en la prxima parte veremos si hacemos elestudio del lado del HOST mediante mpusbapi.dll y como hacerla funcionar por ej: enVB a travs de una Interfaz de Programacin de Aplicaciones API
Estudio de mpusbapi.dll (parte II)
para hacer este estudio vamos a ver unos ejemplos de Slalen(programa1) y Ernesto
Mozota Navarro(programa2). Este ltimo lo pueden bajar de http://www.hobbypic.com/
ambos sirven para el firmware que escribi Jaime J1M, el programa2 tambin aadeotras posibilidades (PWM, CAD)
lo primero, probar el cdigo. Claro! jeje y grabar el firmware PICusb en el PIC. Esto yalo hice varios post atrs, pero no lo expliqu y ahora le toca el turno al Visual Basicusando el programa1.
como mencion anteriormente, para usar nuestra aplicacin corriendo en VB, tenemos
que hacer uso de unas llamadas a la librera mpusbapi.dll (apis).PublicDeclareFunction MPUSBGetDLLVersion Lib"mpusbapi.dll" () AsLongPublicDeclareFunction MPUSBGetDeviceCount Lib"mpusbapi.dll" (ByValpVID_PID AsString) AsLongPublicDeclareFunction MPUSBOpen Lib"mpusbapi.dll" (ByVal instance AsLong, ByVal pVID_PID AsString, ByVal pEP AsString, ByVal dwDir AsLong, ByVal dwReserved AsLong) AsLongPublicDeclareFunction MPUSBClose Lib"mpusbapi.dll" (ByVal handle AsLong) AsLongPublicDeclareFunction MPUSBRead Lib"mpusbapi.dll" (ByVal handle AsLong, ByVal pData AsLong, ByVal dwLen AsLong, ByRef pLength AsLong,
ByVal dwMilliseconds AsLong) AsLongPublicDeclareFunction MPUSBWrite Lib"mpusbapi.dll" (ByVal handle AsLong, ByVal pData AsLong, ByVal dwLen AsLong, ByRef pLength AsLong,ByVal dwMilliseconds AsLong) AsLongPublicDeclareFunction MPUSBReadInt Lib"mpusbapi.dll" (ByVal handleAsLong, ByVal pData AsLong, ByVal dwLen AsLong, ByRef pLength AsLong, ByVal dwMilliseconds AsLong) AsLong
aqu aparecen 7 ,yo cont unas 10 en el cdigo fuente. parece que estas 7 son lasnecesarias para hacer transacciones a la funcin.
nota: funcin = dispositivo = mdulo USB del PIC, en adelante me referir a
dispositivo para no confundir cuando hable de funciones en C.
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
12/35
la api mas sencilla aqu, parecer ser la de mostrar la versin
veamos que dice la traduccin que nos pas Slalen:
MPUSBGetDLLVersion(Void)
Lee el nivel de revision del MPUSAPi.dll. Es un nivel de revision de32bits. Esta funcion no devuelve la version del codigo, no realiza nadacon el USB.
yo le agregara que devuelve un dato de 32 bits, la versin de la dll en formatoMMMMmmmm.
vamos agregar un procedimiento para ver que hace:
PrivateSub Command2_Click()Dim version_dll AsLong
version_dll = Hex(MPUSBGetDLLVersion)
MsgBox Str(version_dll)EndSub
Mostrar la versin de mpusbapi.dll
nos arroja 10000, y pienso que como hay 8 dgitos, ya que la versin es en hexa (8nibbles = 32bits) -> versin dll = 1.0.0.0.0
si quieren mas informacin acerca de estas funciones, visitar estas direcciones:
- La mpusbapi.dll desencadenada: PC PIC va USB en Delphi- Traduccin de mpusbapi.doc
de lo que si voy hablar es como podemos usar esas apis en VB.
veamos:
cuando arrancamos esta aplicacin, primero se debe ejecutar el form_load
PrivateSub Form_Load()OpenMPUSBDevice 'abre comunicaciones
EndSub
http://www.todopic.com.ar/foros/index.php?topic=13418.0http://slalen.ifastnet.com/index.php/mpusbapidll.htmlhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/version_dll.JPGhttp://www.todopic.com.ar/foros/index.php?topic=13418.0http://slalen.ifastnet.com/index.php/mpusbapidll.html -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
13/35
quin es openMPUSBDevice?
R: ste llama a MPUSBOpen:
Sub OpenMPUSBDevice()myOutPipe = MPUSBOpen(0, vid_pid, out_pipe, 0, 0) 'como
salidamyInPipe = MPUSBOpen(0, vid_pid, in_pipe, 1, 0) 'como
entradaEndSub
configura el conducto(pipe) de acceso a cada endpoint, uno de salida y uno de entrada.para outpipe tenemos operacin de escritura -> MP_WRITE=0 y para inpipe ->MP_READ=1. El resultado de esta llamada se guardar en my(In/Out)Pipe
si para ambos tenemos como resultado -1 -> entonces quiere decir que no se pudoestablecer el enlace lgico con el dispositivo.
INVALID_HANDLE_VALUE = -1
si observan el programa2 notaran que hay comprobaciones en casi todas partes,preguntando si hay enlace.
para terminar la aplicacin, debemos cerrar el enlace (igual como se hace en RS-232)mediante:
Sub CloseMPUSBDevice()MPUSBClose (myOutPipe)MPUSBClose (myInPipe)
EndSub
esto es parecido al sistema de mensajeria de windows, donde el resultado de una api, esutilizada por otra (handle) para ejecutar otros procesos.
nota: es bueno aadirle el mtodo debug.print a cada api para poder analizar cada lnea
ejecutada:
Sub OpenMPUSBDevice()myOutPipe = MPUSBOpen(0, vid_pid, out_pipe, 0, 0) 'como salidaDebug.Print"myOutPipe= " & myOutPipe
myInPipe = MPUSBOpen(0, vid_pid, in_pipe, 1, 0) 'como
entradaDebug.Print"myInPipe= " & myInPipe
EndSub
vamos a escribir un cdigo para abrir y cerrar un enlace virtual con el dispositivo. les
parece?
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
14/35
OptionExplicitPrivateDeclareFunction MPUSBOpen Lib"mpusbapi.dll" (ByVal instanceAsLong, ByVal pVID_PID AsString, ByVal pEP AsString, ByVal dwDir AsLong, ByVal dwReserved AsLong) AsLongPrivateDeclareFunction MPUSBClose Lib"mpusbapi.dll" (ByVal handle As
Long) AsLongConst INVALID_HANDLE_VALUE = -1Const MPUS_FAIL = 0Const MPUSB_SUCCESS = 1
Const vid_pid = "vid_04d8&pid_0011"' Vendor id (Microchip) yPeriferico idConst out_pipe = "\MCHP_EP1" ' endpoint 1Const in_pipe = "\MCHP_EP1" ' endpoint 1Const MP_WRITE = 0 '
Const MP_READ = 1Public myInPipe AsLong ' para guardar el manejadorPublic myOutPipe AsLong
PrivateSub cmdabrir_Click() ' abrir enlace o pipemyOutPipe = MPUSBOpen(0, vid_pid, out_pipe, 0, 0) 'como
salidaDebug.Print"myOutPipe= " & myOutPipe ' para monitoreo
If myOutPipe = INVALID_HANDLE_VALUE Then ' si es -1
lblpipeout = "Fallo el enlace de salida"
Elselblpipeout = "Enlace salida establecido" EndIf
myInPipe = MPUSBOpen(0, vid_pid, in_pipe, 1, 0) 'comoentrada
Debug.Print"myInPipe= " & myInPipe
If myInPipe = INVALID_HANDLE_VALUE Thenlblpipein = "Fallo el enlace de entrada"
Elselblpipein = "Enlace entrada establecido"
EndIfEndSubPrivateSub cmdcerrar_Click() ' cerrar enlace pipeDim resul_o AsLong: Dim resul_i AsLong
resul_o = MPUSBClose(myOutPipe)Debug.Print"MPUSBClose(myOutPipe)= " & resul_o
If resul_o = MPUSB_SUCCESS Thenlblpipeout.Caption = "Enlace salida cerrado"
Elselblpipeout.Caption = "Error al cerrar el enlace salida, puede
que este cerrado" EndIf
resul_i = MPUSBClose(myInPipe)Debug.Print"MPUSBClose(myInPipe)= " & resul_i
If resul_i = MPUSB_SUCCESS Then
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
15/35
lblpipein.Caption = "Enlace entrada cerrado" Else
lblpipein.Caption = "Error al cerrar el enlace entrada, puedeque este cerrado" EndIfEndSub
algunas pantallas de nuestro programilla abriendo y cerrando pipes
Casos de abrir y cerrar PiPES
Casos de abrir y cerrar PiPES
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/abrir_2.jpghttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/abrir_1.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
16/35
Casos de abrir y cerrar PiPES
Casos de abrir y cerrar PiPES
ya tenemos una idea de como se usa la api MPUSBOpen.
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/abrir_4.jpghttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/abrir_3.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
17/35
Estudio de mpusbapi.dll (parte III)
veremos las apis mas importantes de la biblioteca mpusbapi.dll. Me refiero a:
MPUSBRead
MPUSBWrite
- como hizo el programa1 para encender un led?R: en el botn verde, tenemos:
PrivateSub Command1_Click(Index AsInteger)Send_Buf(0) = 1 'Para que reconozca que se encienden o apagan
LedsSend_Buf(1) = IndexSend Send_Buf, 2
EndSub
aj ya empezaron las dudas, vamos a ver quien es Send_Buf:
Dim Send_Buf(0 To 2) AsByte...' Funcin enviar
Function Send(ByRef SendData() AsByte, bytes AsInteger) AsLong Dim SentDataLength AsLong Call MPUSBWrite(myOutPipe, VarPtr(SendData(0)), bytes,VarPtr(bytes), 1000) 'VarPtr()= puntero a la variableEndFunction
es lgico pensar que como se trabaja con bytes, entonces para varios datos es necesariocrear arrays de bytes. y eso es precisamente lo que hace Send_Buf()
aqu hay una sentencia curiosa VarPtr(), yo nunca la haba visto, adems no pertenece alVB en s, leyendo por aqu, por ac, consegu:
DeclareFunction VarPtrAny Lib"vb40032.dll"Alias"VarPtr" (lpObjectAs Any) AsLong
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
18/35
'The VarPtr-function retrieves the memory handle of an object.' lpObject' Handle that identifies the object
-ahh- conque viene del runtime!
hurgando en la biblioteca MSDN, aparecen tres mtodos NO documentados sobre usardireccionamiento en VB, VarPtr, ObjPtr y StrPtr
esto si es un descubrimiento para mi, el uso de punteros en basic (bajo ciertascondiciones).
volviendo a la api MPUSBWrite, el segundo argumento:
pData -> salida: puntero al buffer que contiene los datos que se van a escribir
para explicar un momento el uso del puntero en este caso, este argumento lo quenecesita es la direccin donde est alojado el dato que queremos enviar
el problema que tiene visual basic es que no podemos usar punteros, pero con el mtodovarptr podemos tomar dicha direccin, y esto no es lo mejor de todo, lase bien. Lomejor es que gracias a que en un array de bytes las direcciones de esos datos soncontiguos, entonces con solo tener la direccin del primer byte de datos es lo necesarioque debe tener la api para hacer el recorrido en memoria.
para demostrar esto que estoy diciendo, voy a escribir un cdigo donde:- guardar un dato (byte) en 2 variables
- tomar la direccin de esas 2 variables mediante varptr- luego llamando una api CopyMemory, recuperar el valor que hay enesas direcciones que vienen siendo el mismo dato.
' mediante el uso de Varptr y CopyMemory' Varptr(dato): devuelve la direccion (Long) donde se almacena lavariable dato' con CopyMemory podemos recuperar el dato en memoria a partir de sudireccion' por: Pedro - PalitroqueZ. 23-feb-2007 10:19AM
OptionExplicitPrivateDeclareSub CopyMemory Lib"kernel32"Alias"RtlMoveMemory"(pDst As Any, pSrc AsLong, ByVal ByteLen AsLong)Dim d(0 To 1) AsByte, dato(0 To 1) AsByte, r1 AsLong, r2 AsLongPrivateSub Command1_Click()
d(0) = 25 ' un valor cualquieraDebug.Print"d(0)= " & d(0)d(1) = 97 ' un valor cualquieraDebug.Print"d(1)= " & d(1)
r1 = VarPtr(d(0)) ' en r1 se guarda la direccion donde estaalmacenado d(0)Debug.Print"r1= " & r1
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
19/35
r2 = VarPtr(d(1))Debug.Print"r2= " & r2
' ahora se procede a recuperar el dato, usando CopyMemoryCopyMemory ByVal VarPtr(dato(0)), ByVal r1, 2
' debe usarse byval OBLIGATORIO para que se pueda copiar el dato envez de la direccion
' el ultimo argumento corresponde a la longitud del dato en bytes ' si se coloca 2, es para que tome la direccion del dato contiguo ' es decir, dato(1). ' como dato(0), dato(1) -> se almacenan en direcciones contiguas ' entonces CopyMemory almacenara el par de bytes de datos, endato(0) ' y dato(1) mediante sus direcciones respectivas
Debug.Print"dato(0)= " & dato(0)Debug.Print"dato(1)= " & dato(1)
MsgBox "se recuper d(0)=" & Str(dato(0)) & " y d(1)=" &Str(dato(1))Unload MeEndSub
una imagen del debugger:
Usando punteros en Visual Basic 6
as pues, donde veamos el varptr ya sabemos a que se est refiriendo, adems elargumento de la api tambin lo delata con la letra p ej: pData, pLenght
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/uso_varptr.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
20/35
esto es la parte complicada de entender el uso de la api, para MPUSBRead es similar yal revs, el segundo argumento es el puntero de una variable previamente declarada pornosotros para que se alojen los datos que vayan llegando del USB.
como vern esta es otra aplicacin del concepto del puntero, por un lado tenemos la
casilla(direccin de almacenamiento) y por el otro tenemos el valor del datoalmacenado.
el resto de los argumentos es fcil de entender, como la longitud del dato (en bytes).esto depende de como configuremos el envo desde el dispositivo
el tiempo en milisegundos: es para que la api no se quede en un bucle infinito si llegaraa ocurrir un problema
y por supuesto el pipe, o mejor dicho el handle del pipe, que se puede decir que es unpuntero representado en VB como un long (ver fuentes consultadas)
bueno volviendo al uso de la funcin Send
Send_Buf(0) = 1 'Para que reconozca que se encienden o apaganLeds
Send_Buf(1) = IndexSend Send_Buf, 2
esto interpretado desde el punto de vista del micro, es un paquete de datos, donde hay 2bytes. en el primer byte se guarda el modo (modo_led) y el en otro byte se guarda elparaml que es la accin para ambos leds (apagado, on, off -> led rojo y verde)
luego el array de bytes se enva a la funcin send
Function Send(ByRef SendData() AsByte, bytes AsInteger) AsLong Dim SentDataLength AsLong Call MPUSBWrite(myOutPipe, VarPtr(SendData(0)), bytes,VarPtr(bytes), 1000) 'VarPtr()= puntero a la variableEndFunction
observen el VarPtr(SendData(0)), es lo mismo que habl hace rato, se toma la direccindel primer byte es lo nico que necesita pData para tomar el resto del array de datos
el que falta, la suma:
Dim a AsByte 'buffer de datos intermedio
Send_Buf(0) = 0 'Para que reconozca que es una sumaa = CByte(sumando(0).Text) 'convierte el texto a byteSend_Buf(2) = aSend_Buf(0) = 0a = CByte(sumando(1).Text)Send_Buf(1) = aSend_Buf(0) = 0Send Send_Buf, 3 'enva los sumandos
recibir (a) 'recibe el resultadoresultado.Caption = CStr(rec) 'convierte el dato a string
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
21/35
el Send ya lo hablamos, falta la funcin recibir:
Dim SentDataLength AsLong Call MPUSBRead(myInPipe, VarPtr(s), 1, 1, 1000)
rec = s 'guardo el dato recibido en una variableintermedia
aqu sucede lo contrario, es decir, la api MPUSBRead necesita la direccin del byte spara almacenar el dato que viene del PIC (que en este caso es 1 byte de longitud).
esto fue el anlisis realizado al programa1 y programa2.
vamos a usar el estupendo SnoopyPro para ver los bferes del USB jijiji
abrimos y ejecutamos las siguientes acciones en secuencia:
1.- led rojo = ON2.- led verde = ON3.- apaga leds4.- 1 + 0 = 15.- 1 + 7 = 86.- 12 + 7 = 19
Capturas con SnoopyPro
a ver que tenemos all:
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy1.jpg -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
22/35
Transaccin Recibida
tenemos un paquete de 2 bytes, en el primer el modo = 1 (modo led). y en el segundoparaml = 2 (led rojo ON)
Transaccin Recibida
tenemos un paquete de 2 bytes, en el primer el modo = 1 (modo led). y en el segundoparaml = 1 (led verde ON)
Transaccin Recibida
tenemos un paquete de 2 bytes, en el primer el modo = 1 (modo led). y en el segundoparaml = 0 (led rojo y verde off)
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy5.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy4.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy3.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy2.JPG -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
23/35
Transaccin Recibida
tenemos un paquete de 3 bytes, en el primer el modo = 0 (modo suma). y en el segundoy tercer byte tenemos 0 y 1 que son los operandos de la suma. ojo vean que esto es un
paquete down , que transmite HOST -> PIC.
un poco mas abajo:
Contenido paquete
tenemos un paquete de PIC -> HOST de 1 byte y que trae? nada mas y nada menos queel resultado de la suma.
el par de sumas que faltan:
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy7.JPGhttp://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy6.JPG -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
24/35
analizando paquetes
analizando paquetes
observaciones:
- despus de haber visto varias veces el cdigo de Jaime hasta ahora es que me doycuenta que el led verde es RB6 y led rojo RB7 yo lo tena invertido. pero lo extrao de
todo es que con el programa PicUSBDelphi.exe de Diego se ejecuta OK con los ledsinvertido. ??
- faltara implementar un algoritmo de validacin, porque si ocurre un problema, hayque resetear tanto al programa como al pic para normalizar.
- tengo que instalar el driver wdmstub.sys cada vez que conecto el cable USB en unpuerto distinto, no se supone que esos conectores son compartidos?esto tambin sucede con la clase CDC.
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/snopy8.JPG -
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
25/35
Estudio de mpusbapi.dll (parte IV)
quisiera hacer unas observaciones, varios mensaje atrs hablando sobre la apiMPUSBGetDLLVersion() escrib:
cita:
nos arroja 10000, y pienso que como hay 8 dgitos, ya que la versin esen hexa (8 nibbles = 32bits) -> versin dll = 1.0.0.0.0
bueno, ahora no estoy tan seguro que eso sea cierto (despus de todo es una suposicin),ahora me baso en lo siguiente:
- que dicha api, devuelve un puntero que contiene la versin de la librera mpusbapi.dll
- si esto es cierto, entonces la versin correcta es 0.0.1.0
aqu est un adjunto con un programa en visual basic que hace lo que digo.
est planteado as al momento de escribir esto, pudindose cambiar por la versincorrecta posteriormente (dado el caso).
voy a tomar el ejemplo del CDC explicado con anterioridad y lo voy a modificar parausarlo con la librera mpusbapi.dll
- lo primero, hacer la deteccin del lado del dispositivo
- lo segundo hacer la deteccin del lado del Host
Deteccin del lado del dispositivo:
es de la misma forma que para la clase CDC estudiada, mediante elUSB_CON_SENSE_PIN
el cdigo con la modificacin:
/* ejemplo7_parte4.cse pretende hacer la deteccion de conexion al puerto USB, mediante la
mpusbapi.dllmostrando en una pantalla LCD 2x16 el estado.
Este codigo es un hibrido del cual se tomo partes de:
- PicUSB.c de J1M- RRCdcUSB de RedPic- probando_USB.c del ejemplo6_parte5 de PalitroqueZ
Pedro - PalitroqueZ 07-Mar-2007. Hora: 3:54 PM*/
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
26/35
#include #fusesXTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN#use delay(clock=48000000)
#define use_portb_lcd TRUE#define USB_HID_DEVICE FALSE //deshabilitamos el uso delas 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 thetx endpoint 1 buffer#define USB_EP1_RX_SIZE 1 //size to allocate for therx endpoint 1 buffer
#define USB_CON_SENSE_PIN PIN_E3#include //Microchip PIC18Fxx5x Hardware layer forCCS's PIC USB driver#include "PicUSB.h" //Configuracin del USB y los descriptorespara este dispositivo#include //handles usb setup tokens and get descriptorreports#include void mostrar_estado_usb();
void main(){ int envia[1]; int recibe[1];
envia[0]='a';usb_init_cs(); // inicializa el USB y lo desactivalcd_init(); // llamadas necesarias para iniciar la LCD
while(true){usb_task(); //habilita periferico usb e interrupcionesmostrar_estado_usb();
if(usb_enumerated()){// primer if if(usb_kbhit(1)){ // segundo if //si el endpoint de salida contiene datos del host
usb_get_packet(1, recibe,1); //cojemos el paquete de tamao 1bytes del EP1 y almacenamosen recibe if(recibe[0]=='a'){// tercer if
usb_put_packet(1, envia,1, USB_DTS_TOGGLE); //enviamos el paquete de tamao 1byte del EP1 al PC
lcd_gotoxy(1,1);lcd_putc("llego una a ");delay_ms(500);
}// fin del tercer if }// fin del segundo if }// fin del primer if
lcd_gotoxy(1,1);lcd_putc("otros procesos");delay_ms(500);
}// fin del ciclo while}
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
27/35
/************************************************// esta llamada imprime en la LCD los estados de conectado// y desconectado del USB dependiendo de la bandera// estado_usb//***********************************************/void mostrar_estado_usb(){
lcd_gotoxy(10,2);if(usb_attached()){lcd_putc(" USB:On");
}else{lcd_putc("USB:Off");
}// delay_ms(500);}
voy a hacer unas observaciones sobre este programa, porque pas un buen rato tratandode que funcionara.
- en usb_kbhit(1), el 1 es el endpoint de datos (el argumento es requerido).
- sustitu a usb_init por usb_init_cs porque?
R: aqu entra el simulador paso a paso del MPLAB.
la funcin:
void usb_init(void){usb_init_cs();
do{
usb_task(); }while(usb_state != USB_STATE_POWERED);}
se queda en un bucle eterno a menos que el dispositivo sea conectado, pero mi interes eshacer que el pic haga otras actividades independientemente si est presente no, elHOST.
usb_init_cs() -> inicializa el mdulo USB y lo desactiva, est bien as que se desactivepor defecto (menos consumo para el circuito).
para encender el modulo est usb_task() dentro del bucle eterno del while(true), en cadainstante l preguntar por el USB_CON_SENSE_PIN y dependiendo del Vusb en este
pin, l activar/desactivar.
ven lo importante que es el USB_CON_SENSE_PIN, basicamente es una deteccin porhardware, se est sensando si llega voltaje del HOST (Vusb).
- elimin la bandera estado_usb, porque es igual que preguntar por usb_attached(), meahorro 1 bit de memoria (que mezquino jaja). Adems que no hay que modificar eldriver original pic18_usb.h
- el resto del cdigo queda igual, solo ajustar los paquetes de datos a 1 byte, usando uneco. el HOST le enva un carcter (a) y el dispositivo se lo devuelve.
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
28/35
Estudio de mpusbapi.dll (parte V)
empezaremos hacer modificaciones al ejemplo de Slalen:
' este programa envia un caracter y recibe un eco del dispositivo
' para confirmacion.''' adaptacion del programa original de Slalen' Pedro-PalitroqueZ 07-Mar-2007 Hora: 7:51 PMOptionExplicitDim Send_Buf(0) AsByteConst verde = &HFF00&Const rojo = &HFF&PrivateSub cmdversiondll_Click()Dim version_dll AsLong, digitos(4) AsByte, cad AsString, t As
Integerversion_dll = VarPtr(MPUSBGetDLLVersion) 'toma el puntero de laversion For t = 0 To 3
digitos(t) = 0 ' limpiar variables Next t
CopyMemory ByVal VarPtr(digitos(0)), ByVal version_dll, 5 ' recupera de la memoria los digitos de la version y lo copia endigitos()
cad = "" For t = 0 To 3 ' concatena los digitos en una cadena
cad = cad & Str(digitos(t)) & "."
Next tlblversiondll.ForeColor = &HFFFF&lblversiondll.Caption = Left$(cad, Len(cad) - 1) ' muestra la
versionEndSubPrivateSub Command2_Click() Dim eco AsByte, dato AsLongTimer1.Enabled = FalseSend_Buf(0) = Asc("a") 'envia la "a"OpenMPUSBDevice 'abre comunicacionesSend Send_Buf, 1dato = recibir(eco)
If eco = 97 Thenlblrespuesta.Caption = "El dispositivo respondio Exitosamente"
Elselblrespuesta.Caption = "No hubo respuesta del Dispositivo"
EndIfCloseMPUSBDevice 'cierra comunicacionesTimer1.Enabled = True
EndSubPrivateSub Form_Load()Timer1.Interval = 50Timer1.Enabled = True
EndSubPrivateSub Form_Unload(Cancel AsInteger)
CloseMPUSBDevice 'cierra comunicaciones
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
29/35
EndSubPrivateSub Timer1_Timer()
OpenMPUSBDevice 'abre comunicaciones If (myOutPipe INVALID_HANDLE_VALUE) And (myInPipe INVALID_HANDLE_VALUE) Then
shpestado.FillColor = verde Elseshpestado.FillColor = rojo
EndIfCloseMPUSBDevice 'cierra comunicaciones
EndSub
como ven lo adapt para transferencias de paquetes de datos de 1 byte, y como siempremi empeo en agregarle un sensor de estado del dispositivo, muy similar que con laclase CDC: un timer abriendo y cerrando el pipe cada 50 mS y preguntando si huboenlace.
cabe decir que el cdigo del PIC es el mismo del ejemplo anterior y funciona igual.
en los ensayos en el protoboard
- reconexin de la extensin USB.
- abriendo y cerrando el programa en VB
- incluso se desconect/conect la alimentacin al PIC y los resultados fueronsatisfactorios.
Estudio de mpusbapi.dll (Aplicacin)
se acuerdan del ejemplo donde usamos el CAD y hacamos transferencias y otrasactividades? bien vamos a tomar ese ejemplo, pero con la biblioteca mpusbapi.dll y conlos conocimientos aprendidos en el tema Estudio de Grficos en VB vamos a visualizarlos datos obtenidos.
los paquetes de datos se mantienen en 1 byte, hice pruebas con 64 bytes, y losresultados fueron casi los mismos.
el cdigo del dispositivo:
/* ejemplo8_parte1.cadaptacin del ejemplo6parte6. transmision del resultado del CAD al
PCal puerto USB, mediante la mpusbapi.dllmostrando en una pantalla LCD 2x16 el resultado del CAD y el estado
USB.Este cdigo es un hbrido del cul se tom partes de:
- PicUSB.c de J1M- RRCdcUSB de RedPic- probando_USB.c del ejemplo6_parte5 de PalitroqueZ
Pedro - PalitroqueZ 08-Mar-2007. Hora: 9:01 AM
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
30/35
*/#include #DEVICE ADC=8 // cad a 8 bits#fusesXTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,N
OPBADEN#use delay(clock=48000000)#define use_portb_lcd TRUE#define USB_HID_DEVICE FALSE //deshabilitamos el uso delas 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 thetx endpoint 1 buffer
#define USB_EP1_RX_SIZE 1 //size to allocate for therx endpoint 1 buffer#define USB_CON_SENSE_PIN PIN_E3#define DERECHA 0#include //Microchip PIC18Fxx5x Hardware layer forCCS's PIC USB driver#include "PicUSB.h" //Configuracin del USB y los descriptorespara este dispositivo#include //handles usb setup tokens and get descriptorreports#include
void mostrar_estado_usb();void config_adcon2(short justificacion);int value;void main(){ int i; int envia[1]; int recibe[1];
set_tris_a(0x1); // Ra[0]=entradas, los demas=salida
usb_init_cs(); // inicializa el USB y lo desactivalcd_init(); // llamadas necesarias para iniciar la LCDsetup_adc_ports( AN0 || VSS_VDD ); // canal AN0, Vref+ = Vdd, Vref-
= Vssconfig_adcon2(DERECHA); // justificacin derecha, Tacq= 2Tad
while(true){
usb_task(); //habilita periferico usb e interrupcionesmostrar_estado_usb();envia[0]= read_adc();
for(i=0;i
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
31/35
printf(lcd_putc,"\n0x%Lx",envia[0]); // muestra el resultado del CAD en Hexa, linea2 LCD
if(usb_enumerated()){// primer if if(usb_kbhit(1)){ // segundo if //si el endpoint de salida contiene datos del host
usb_get_packet(1, recibe,1); //cojemos el paquete de tamao 1bytes del EP1 yalmacenamos en recibe if(recibe[0]=='a'){// tercer if
usb_put_packet(1, envia,1, USB_DTS_TOGGLE); //enviamos el paquete de tamao 1 bytes del EP1 al PC }// fin del tercer if }// fin del segundo if }// fin del primer if }// fin del ciclo while}/***********************************************************// esta llamada imprime en la LCD los estados de conectado
// y desconectado del USB dependiendo de la bandera// estado_usb//**********************************************************/void mostrar_estado_usb(){lcd_gotoxy(10,2);if(usb_attached()){lcd_putc(" USB:On");
}else{lcd_putc("USB:Off");
}// delay_ms(500);}//---------------------------------------------------------------------
--------------------// cumple la funcin de configurar el bit ADFM para hacer// la justificacin, tambin se incluye el retardo por hardware de Tacq// datos de entrada: bandera de justificacin// datos de salida: nada//-----------------------------------------------------------------------------------------void config_adcon2(short justificacion){
setup_adc(ADC_CLOCK_DIV_64 ); // reloj de conversin = Fosc / 64 if(justificacion){ #asm
bsf 0xFC0,7 // ADFM
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
32/35
la resolucin del CAD es a 8 bits y aunque el paquete de datos es de 1 byte, se debedeclarar las variables como tipo array:
int enva[1];
int recibe[1];
porque sino no les funcionar (comprobado)
del resto todo es igual como en el ejemplo mencionado anteriormente.
el programa del lado del HOST:
' programa para explotar el uso del picturebox realizando graficas en' tiempo de ejecucion.
' para una aplicacion practica se recibiran paquetes de 1 bytes' del dispositivo (18F4550) con el resultado del CAD a 8 bits y semostrara' la onda en el picturebox''' la parte del codigo de transferencia de datos por USB, pertenece aSlalen'' Saludos a foro TodoPic http://www.todopic.com.ar/foros/index.php'' por: Pedro - PalitroqueZ 10-Mar-2007 Hora: 09:34 PM
OptionExplicitDim cx AsInteger, cy AsIntegerDim cx1 AsInteger, cy1 AsIntegerDim i AsInteger, j AsLongDim x AsLong, y AsIntegerDim dato(1000) AsLongDim pcx AsLong, pcy AsLongDim fcx AsLong, fcy AsLongDim n AsInteger ' n define la base de tiempo o time-divisionDim Send_Buf(0) AsByteConst verde = &HFF00&
Const rojo = &HFF&Dim valor AsSingle, maximo AsIntegerDim te AsBytePrivateSub Form_Load()
valor = 0 'VScroll1.Value ' el resultado del CAD en un tiempo discreto
maximo = 255 'VScroll1.Max ' viene siendo el maximo numero de pasos del CAD (8 bits=255, 10bits=1023)
n = 30 ' wl time-division
cy = Picture1.ScaleHeight ' 117cx = Picture1.ScaleWidth ' 253
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
33/35
cy1 = Picture1.ScaleHeight ' 117cx1 = Picture1.ScaleWidth ' 253
pcx = Picture1.Widthpcy = Picture1.Height
fcx = Me.Widthfcy = Me.Height
ajustar_tiempo (n)
Timer1.Enabled = FalseTimer2.Enabled = FalseTimer3.Interval = 50Timer3.Enabled = True
'Timer3.Enabled = False
HScroll1.Value = nEndSub
PrivateSub Form_Resize()Timer1.Enabled = FalseTimer2.Enabled = False
Picture1.Height = Form1.Height / (fcy / pcy)Picture1.Width = Form1.Width / (fcx / pcx)
Picture1.ScaleHeight = Picture1.Height / (pcy / cy1)Picture1.ScaleWidth = Picture1.Width / (pcx / cx1)cy = Picture1.ScaleHeightcx = Picture1.ScaleWidthPicture1.Cls
x = -1: y = 0: i = 0: j = -1ajustar_tiempo (n)Timer1.Enabled = True
EndSubPrivateSub Form_Unload(Cancel AsInteger)
CloseMPUSBDevice 'cierra comunicacionesEndSubPrivateSub HScroll1_Change()
n = HScroll1.Valuelblconta.Caption = nForm_Resize
EndSubPrivateSub HScroll1_Scroll()
lblconta.Caption = HScroll1.ValueEndSubPrivateSub Timer1_Timer()
Label1.Caption = VScroll1.Value
dato(i + 1) = Int(cy - valor * (cy / maximo)) IfNot j > (cx - n) Then' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlackx = j
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
34/35
i = i + 1j = j + n
ElseTimer1.Enabled = False ' ya llego, deja de dibujarTimer2.Enabled = True '
EndIf
Label1.Caption = "CAD= " & Round(valor * (5 / maximo), 3) & " volts ->0x" & Hex(valor)EndSubPrivateSub Timer2_Timer()
Picture1.Clsx = -1j = -1
Label1.Caption = VScroll1.Value
'valor = VScroll1.Value If n > 1 Then
dato(Int((cx / n) + 2)) = Int(cy - valor * (cy / maximo))
Elsedato(Int((cx / n)) + 1) = Int(cy - valor * (cy / maximo))
EndIf For i = 0 To cx ' pregunta si i no ha llegado a cx
Picture1.Line (x, dato(i))-(j, dato(i + 1)), vbBlackx = jj = j + n ' para lograr el ajuste time-divisiondato(i) = dato(i + 1) ' rellenar el dato(n) : 0 < n < cx
Next iLabel1.Caption = "CAD= " & Round(valor * (5 / maximo), 3) & " volts
-> 0x" & Hex(valor)EndSub
Function ajustar_tiempo(time_division AsInteger) If time_division > 1 Then
Timer1.Interval = 3 * time_divisionTimer2.Interval = 3 * time_division
ElseTimer1.Interval = 1Timer2.Interval = 1
EndIfEndFunctionPrivateSub Timer3_Timer()
Send_Buf(0) = Asc("a")
OpenMPUSBDevice 'abre el pipe (si se puede)
If (myOutPipe INVALID_HANDLE_VALUE) And (myInPipe INVALID_HANDLE_VALUE) Then
shpestado.FillColor = verde Else
shpestado.FillColor = rojo EndIf
Send Send_Buf, 1recibir (te)
If rec = 0 Then
valor = 1 ' para ajustar el grfico Else
-
7/23/2019 71113661 Mis Primeros Pasos Con El 18F4550
35/35
valor = rec EndIf
CloseMPUSBDevice 'cierra comunicacionesEndSub
PrivateSub cmdayuda_Click()Dim mensaje AsStringmensaje = "Este programa recoge los datos enviado desde un" & vbCrLfmensaje = mensaje & "dispositivo (PIC18F4550) y grafica la sealcorrespondiente" & vbCrLfmensaje = mensaje & "al resultado de una conversion analogica-digital"& vbCrLfmensaje = mensaje & "a 8 bits de resolucin"MsgBox mensaje, vbInformation, "Informacion"EndSub
el Timer3_Timer() es primordial, porque cumple triple propsito:
enva el dato de confirmacin (el ECO). recibe el dato del dispositivo. sensa el estado de conexin del dispositivo, ya que ante cada ejecucin y transferenciaabre y cierra el pipe.
en base a mis experiencias, debo decir que trabajar con mpusbapi.dll como que es lamejor opcin, mucho mas rpido y prctico (conociendo la programacin). pero para nosubestimar a la clase CDC, entonces:
- de acuerdo a la situacin dada, se debe escoger que es conveniente: CDC mpusbapi.dll
- eso depender del programador que tendr que decidir cul es mejor.
http://www.unpocodelectronica.netau.net/images/contenidos/electronica/24-articulo/ejemplo_mpusbapi/ventanazo_final.JPG