71113661 mis primeros pasos con el 18f4550

Upload: luis-pariapaza-rumiche

Post on 11-Feb-2018

249 views

Category:

Documents


2 download

TRANSCRIPT

  • 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