Autor Tema: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC  (Leído 25179 veces)

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

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3145
MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« en: 05 de Febrero de 2011, 14:53:19 »
El problema de los ejemplos que vienen con las librerías de Microchip es que están pensados para funcionar en los demostradores de Microchip y esto supone que el código está tan plagado de excepciones que resulta difícil de leer.

Llevo unos días peleándome con la de USB para usar comunicación CDC y he decidido crear un ejemplo que sea la mínima expresión; es decir, sólo lo necesario para ver cómo funciona y luego poder ampliarlo a gusto.

El resultado se lo dejo a continuación, y me ha permitido establecer una comunicación CDC muy básica tanto con un 19f27j53 usando el oscilador interno como en un 18f2455 usando un cristal de 20MHz.

La siguiente en caer será la librería TCP/IP :mrgreen:


MPLAB C Compiler for PIC18 USB CDC barebones

Este desarrollo está basado en el ejemplo "USB Device - CDC - Basic Demo" de las librerías de aplicación de Microchip.
En el archivo adjunto encontrará todo el proyecto, además de los HEX para un 18f2455 y un 18f27j53.

REQUISITOS PREVIOS

1. Instalar MPLAB IDE: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en019469
2. Instalar la versión dgratuita educativa de MPLAB C Compiler for PIC18: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en536656
3. Instalar las Microchip Application Library: http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2680&dDocName=en547784

Por defecto, el compilador se instala en la carpeta MCC18 y, en su interior, se encuentra la subcarpeta h que contiene includes fundamentales.
Por defecto, la Application Library se instala en la carpeta Microchip Solutions v2010-10-19 y, en su interior, se encuentra la subcarpeta Microchip/Include que contiene includes fundamentales.


PASO A PASO
1. En primer lugar crearemos una carpeta para nuestro proyecto y colocaremos en ella los archivos del Stack USB que nos interesan. Cree una carpeta llamada, por ejemplo: USB-CDC.
2. El stack USB requiere que existan en la carpeta del proyecto los 3 siguientes archivos:
   * HardwareProfile.h: El stack está pensado para utilizarlo con los demostradores de Microchip, pero si vamos a usar un prototipo diferente tendremos que crear este archivo dentro de la carpeta con el contenido mínimo que se muestra a continuación:
Código: [Seleccionar]
#ifndef HARDWARE_PROFILE_H
    #define HARDWARE_PROFILE_H

    #define DEMO_BOARD USER_DEFINED_BOARD
    #define self_power          1
    #define USB_BUS_SENSE       1
#endif  //HARDWARE_PROFILE_H
  * usb_decriptors.c: Este archivo contiene el nombre con el que identificará nuestro dispositivo en el sistema y lo más cómodo es copiarlo directamente del ejemplo C:\Microchip Solutions v2010-10-19\USB Device - CDC - Basic Demo\CDC - Basic Demo - Firmware.
   * usb_config.h: Este archivo establece algunas constantes que condicionan el funcionamiento del stack y lo más cómodo es copiarlo directamente del ejemplo C:\Microchip Solutions v2010-10-19\USB Device - CDC - Basic Demo\CDC - Basic Demo - Firmware. Por defecto, viene configurado para usar el stack en modo interrupción, pero en este ejemplo se ha utilizado en modo polling porque es más sencillo. Por este motivo tenemos que realizar en este archivo la modificación que se indica a continuación (líneas 83 y 84):
Código: [Seleccionar]
#define USB_POLLING
//#define USB_INTERRUPT
3. Ejecutar MPLAB IDE.
4. Seleccionar Project>Project Wizard.
5. Seleccionar el microcontrolador. Este ejemplo ha sido probado conel PIC18f2455 y con el PIC18F27J53, pero en principio debería funcionar con todos. Pulsar Siguiente.
6. Seleccionar como Active Toolsuite "Microchip C18 Toolsuite". Pulsar Siguiente.
7. Pulsar el botón Browse para selecccionar la carpeta USB-CDC que creamos en el paso 1 y en la que hemos colocado ya los 3 archivos necesarios, y escribir un nombre para el proyecto, por ejemplo USB-CDC en el cuadro de texto Nombre. Pulsar Guardar y, a continuación, Siguiente.
7. Seleccionar los 3 archivos que ya hemos colocado en la carpeta USB-CDC y pulsar el botón Add para añadirlos al proyecto.
8. Además de estos 3 archivos, necesitamos 2 del stack: C:\Microchip Solutions v2010-10-19\Microchip\USB\usb_device.c y C:\Microchip Solutions v2010-10-19\Microchip\USB\CDC Device Driver\usb_function_cdc.c. Añádalos también pulsando el botón Add. Pulse el botón Siguiente y, a continuación, Finalizar.
9. Confirme el nombre que se propone para el Workspace pulsando Guardar.
10. Además de los 5 archivos que hemos incluido en el proyecto, el stack hace uso de un puñado de includes; pero en lugar de añadirlos vamos a indicarle a MPLAB dónde buscarlos. Seleccione Project>Build options>Project y, en el cuadro de diálogo que aparece, asegúrese de que está activa la ficha Directories.
11. Despliegue el cuadro de lista Show directories for y seleccione Include Search Path. Utilice el botón New para añadir las rutas C:\Microchip Solutions v2010-10-19\Microchip\Include y C:\MCC18\h.
12. Despliegue nuevamente el cuadro de lista Show directories for y seleccione Library Search Path. Si no está incluida la dirección C:\MCC18\lib, añádala pulsando el botón New.
13. Pulse el botón Aceptar.
14. Ya tenomos todo lo necesario para usar el stack USB en modo CDC, sólo nos queda crear el archivo main de nuestra aplicación. Seleccione File>New y, a continuación, File>Save As para guardar el archivo con el nombre main.c en la carpeta USB-CDC del proyecto. Seleccione Project>Add Files to Project y elija el archivo main.c para incluirlo también en el árbol del proyecto.
15. Escriba en el archivo main.c el código que se muestra a continuación. Las únicas precauciones son comentar/descomentar los pragmas que se deseen utilizar de la zona superior. El primer conjunto está pensado para utilizar el oscilador interno en un 18f27j53 (a pesar de que en principio no debería ser muy fiable, el caso es que funciona), y el segundo grupo está pensado para usar un cristal externo en un 18f2455. El código empieza con un USBDeviceInit que inicializa el dispositivo USB apoyándose en las tres funciones Callback que hay al final del código. A continuación simplemente se entra en un bucle infinito que llama en cada iteración a las funciones USBDeviceTasks() y ProcessIO. La primera debe llamarse periódicamente para poner a punto el estado de la comunicación USB y en ProcessIO en primer lugar se comprueba si el dispositivo está aún conectado ((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)), a continuación se comprueba si está listo para recibir/transmitir (USBUSARTIsTxTrfReady()) y, en caso afirmativo, se leen los nuevos caracteres que hayan podido llegar desde el ordenador por el USB getsUSBUSART(USB_Out_Buffer,64) y se los devolvemos al buffer de salida anteponiendo "Ha pulsado: " con  putsUSBUSART. Por último, llamamos a CDCTxService() que es la responsable de enviar el buffer por el puerto USB de vuelta al ordenador. Para probar el programa, compílelo con Project>Build all, grábelo en su dispositivo, conéctelo al ordenador, abra una sesión de HyperTerminal y conecte al puerto USB (generalmente aparecerá como COM4 o uno superior); todo lo que escriba le será devuelto anteponiento "Ha pulsado".
Código: [Seleccionar]
/** CONFIGURATION **************************************************/
//Descomente estos pragmas para usar el oscilador interno. Probado en un pic18f27j53
#pragma config WDTEN = OFF          
#pragma config CPUDIV = OSC1        
#pragma config CFGPLLEN = ON
#pragma config OSC = INTOSCPLL
#pragma config PLLDIV = 2
#pragma config XINST = OFF
//Descomente estos pragmas para usar un cristal externo de 20MHz. Probado en un pic18f2455
//#pragma config WDT = OFF          
//#pragma config CPUDIV = OSC1_PLL2      
//#pragma config FOSC = HSPLL_HS
//#pragma config PLLDIV = 5
//#pragma config XINST = OFF
//#pragma config USBDIV = 2
//#pragma config VREGEN = ON





/** I N C L U D E S **********************************************************/
#include "USB/usb.h"
#include "USB/usb_function_cdc.h"


/** V A R I A B L E S ********************************************************/
char USB_Out_Buffer[64];
char buffer[64];



/** P R I V A T E  P R O T O T Y P E S ***************************************/
void ProcessIO(void);



/** DECLARATIONS ***************************************************/
void main(void)
{  
    USBDeviceInit(); //usb_device.c.  Initializes USB module SFRs and firmware
     //variables to known states.

    while(1)
    {  
        USBDeviceTasks();
        ProcessIO();        
    }//end while
}//end main



/********************************************************************
 * Function:        void ProcessIO(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is a place holder for other user
 *                  routines. It is a mixture of both USB and
 *                  non-USB tasks.
 *
 * Note:            None
 *******************************************************************/
void ProcessIO(void)
{  
    BYTE numBytesRead;

    // User Application USB tasks
    if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return;

    if(USBUSARTIsTxTrfReady())
    {
numBytesRead = getsUSBUSART(USB_Out_Buffer,64);
if(numBytesRead != 0)
{
strcpypgm2ram(buffer,(const rom far char *)"Ha pulsado: ");
strncat(buffer,USB_Out_Buffer,numBytesRead);
strcatpgm2ram(buffer,(const rom far char *)"\r\n");
putsUSBUSART(buffer);
}
}
    CDCTxService();
} //end ProcessIO





// ******************************************************************************************************
// ************** USB Callback Functions ****************************************************************
// ******************************************************************************************************
// The USB firmware stack will call the callback functions USBCBxxx() in response to certain USB related
// events.  For example, if the host PC is powering down, it will stop sending out Start of Frame (SOF)
// packets to your device.  In response to this, all USB devices are supposed to decrease their power
// consumption from the USB Vbus to <2.5mA each.  The USB module detects this condition (which according
// to the USB specifications is 3+ms of no bus activity/SOF packets) and then calls the USBCBSuspend()
// function.  You should modify these callback functions to take appropriate actions for each of these
// conditions.  For example, in the USBCBSuspend(), you may wish to add code that will decrease power
// consumption from Vbus to <2.5mA (such as by clock switching, turning off LEDs, putting the
// microcontroller to sleep, etc.).  Then, in the USBCBWakeFromSuspend() function, you may then wish to
// add code that undoes the power saving things done in the USBCBSuspend() function.

// The USBCBSendResume() function is special, in that the USB stack will not automatically call this
// function.  This function is meant to be called from the application firmware instead.  See the
// additional comments near the function.


/*******************************************************************
 * Function:        void USBCBCheckOtherReq(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        When SETUP packets arrive from the host, some
 * firmware must process the request and respond
 * appropriately to fulfill the request.  Some of
 * the SETUP packets will be for standard
 * USB "chapter 9" (as in, fulfilling chapter 9 of
 * the official USB specifications) requests, while
 * others may be specific to the USB device class
 * that is being implemented.  For example, a HID
 * class device needs to be able to respond to
 * "GET REPORT" type of requests.  This
 * is not a standard USB chapter 9 request, and
 * therefore not handled by usb_device.c.  Instead
 * this request should be handled by class specific
 * firmware, such as that contained in usb_function_hid.c.
 *
 * Note:            None
 *******************************************************************/
void USBCBCheckOtherReq(void)
{
    USBCheckCDCRequest();
}//end



/*******************************************************************
 * Function:        void USBCBInitEP(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called when the device becomes
 *                  initialized, which occurs after the host sends a
 * SET_CONFIGURATION (wValue not = 0) request.  This
 * callback function should initialize the endpoints
 * for the device's usage according to the current
 * configuration.
 *
 * Note:            None
 *******************************************************************/
void USBCBInitEP(void)
{
    CDCInitEP();
}



/*******************************************************************
 * Function:        BOOL USER_USB_CALLBACK_EVENT_HANDLER(
 *                        USB_EVENT event, void *pdata, WORD size)
 *
 * PreCondition:    None
 *
 * Input:           USB_EVENT event - the type of event
 *                  void *pdata - pointer to the event data
 *                  WORD size - size of the event data
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        This function is called from the USB stack to
 *                  notify a user application that a USB event
 *                  occured.  This callback is in interrupt context
 *                  when the USB_INTERRUPT option is selected.
 *
 * Note:            None
 *******************************************************************/
BOOL USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, WORD size)
{
    switch(event)
    {
        case EVENT_CONFIGURED:
            USBCBInitEP();
            break;      
        case EVENT_EP0_REQUEST:
            USBCBCheckOtherReq();
            break;      
        default:
            break;
    }      
    return TRUE;
}


/** EOF main.c *************************************************/

Metadatos para buscadores:

USB CDC Internal Oscillator
Microchip USB barebones
Basic example of Microchip USB CDC
« Última modificación: 06 de Febrero de 2011, 07:26:15 por jfmateos2, Razón: Me faltaba el USBDeviceTasks(); en el bucle principal »

Desconectado LABmouse

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3575
    • Juntos es mejor
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #1 en: 05 de Febrero de 2011, 15:16:16 »
Grandioso!,

Te voy a seguir pues esta semana debo enfrentarme a este mismo problema.

SALUDOS!


Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #2 en: 05 de Febrero de 2011, 15:18:58 »
Magnífico trabajo, Juanfe. Ya lo he descargado por si algún día me fuera necesario. Muchas gracias

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #3 en: 05 de Febrero de 2011, 16:53:22 »
Muy buen adelanto   :-/ Ahora, cuando dices que por polling es más sencillo, lo dices por la sintaxis para usar interrupciones, o sea el tema de ubicar las funciones en los vectores adecuadamente? Porque lo que es la librería de usb, usar polling o interrupción, es llamar a USBDeviceTasks(), en un bucle infinito o en una ISR de alta prioridad, nada más  ;-)


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado J1M

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1960
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #4 en: 05 de Febrero de 2011, 17:03:45 »
El TCPIP ya está dominado! A ver si el Lunes saco un huequito y pongo un paso a paso tan dpm como este.

Enhorabuena por la 'domada'! ;D

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3145
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #5 en: 05 de Febrero de 2011, 17:06:31 »
Suky, me refería a que es más sencillo para los que tenemos aún poca experiencia y no estamos  muy desenvueltos con el tema de las interrupciones, pero efectivamente es también  sencillo:  basta con mantener el define  USB_Interrupt y llamar aUSBDeviceTasks en el código de gestión de la interrupción de alta prioridad.
En este ejemplo pretendía poner el código mínimo imprescindible para poder ver funcionar el USB-CDC y, a partir de aquí, todo es construir...


******Cogno J1M, entonces ni me pongo con ello. Ahora mismo te iba a escribir para que me asesorases por dónde empezar.

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3145
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #6 en: 06 de Febrero de 2011, 07:27:46 »
Disculpen, había una errata en el código (faltaba el USBDeviceTasks(); en el bucle principal).

Ya está corregido en el hilo inicial.

Desconectado jorgejg

  • PIC12
  • **
  • Mensajes: 96
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #7 en: 24 de Agosto de 2011, 11:19:46 »
Seguí los pasos al pie de la letra y al conectar a la PC me sale la ventana emergente del lado derecho inferior de la pantalla diciendo "No se reconoce el dispositivo USB ..." pero ayer al menos me salia una ventana del windows pidiendo drivers para instalar, yo le daba siguiente pero no instalaba y finalmente no podia instalar los controladores.

Como podria solucionar esto?

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #8 en: 24 de Agosto de 2011, 12:26:31 »
Cuando pide los driver selecciona la carpeta que se encuentra junto a los ejemplos, creo que se llama inf. El problema puede ser el hardware, si estas utilizando el mismo ejemplo, revisa las conexiones si utilizas un protoboard.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado jorgejg

  • PIC12
  • **
  • Mensajes: 96
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #9 en: 24 de Agosto de 2011, 18:59:31 »
Tenias razón, seleccioné el inf y ahora si instaló bien y comunicó bien con el hypert. gracias Suky y jfmateos por el aporte. Trataré de modificar el programa para lo que necesito, gracias.

Desconectado IngRandall

  • PIC18
  • ****
  • Mensajes: 383
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #10 en: 11 de Abril de 2012, 13:37:21 »
Tengo una duda acerca de como funciona ese stack por interrupciones, osea no se si se puede que sea así como el uart que cuando llega el dato se genera la interrupción y el va y la atiende.

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #11 en: 11 de Abril de 2012, 22:27:18 »
El resultado se lo dejo a continuación, y me ha permitido establecer una comunicación CDC muy básica tanto con un 19f27j53 usando el oscilador interno como en un 18f2455 usando un cristal de 20MHz.

No encuentro el 19F en microchip. Como consigo este uC?








Fuera de bromas, te ha quedado estupendo. Se agradece enormemente!  :mrgreen:

Desconectado jfmateos2

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3145
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #12 en: 12 de Abril de 2012, 02:07:33 »
Es una errata jeremylf, me refería al 18f27j53

Desconectado rohood

  • PIC10
  • *
  • Mensajes: 1
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #13 en: 01 de Mayo de 2012, 12:18:21 »
A que velocidad se debe configurar el hyperterminal, por ahi lei que eso depende del driver y que esta por defecto a 9600, no estoy seguro porque no me funciona, el codigo simulado en ISIS recibe pero no transmite, y sera que se puede cambiar la velocidad determinada por el driver.

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: MPLAB C Compiler PIC18: Lo básico de la librería USB-CDC
« Respuesta #14 en: 01 de Mayo de 2012, 14:16:16 »
En las propiedades del driver podes ver a que velocidad está configurado. También podes cambiarlo.


Saludos!
No contesto mensajes privados, las consultas en el foro