9 Desarrollo del Software - Servidor de la Biblioteca de...

18
Diseño Integrado Universidad de Sevilla Pág. 111 9 Desarrollo del Software 9.1 Proceso de Desarrollo. El proceso de desarrollo de una aplicación basada en microcontroladores se compone de las siguientes etapas principales, las cuales se explican en más detalle en las siguientes sub-secciones. Desarrollo de software: Esta etapa corresponde a la escritura y compilación/ensamblaje del programa que regirá las acciones del microcontrolador y los sistemas periféricos conectados a este. Programación del microcontrolador: En esta etapa el código de máquina correspondiente al programa desarrollado en la etapa anterior se descarga en la memoria del microcontrolador. Prueba y verificación: Por último, el microcontrolador debe conectarse al circuito base y someterse a pruebas para verificar el funcionamiento correcto del programa. 9.1.1 Desarrollo del software. En esta etapa consiste en escribir y compilar/ensamblar el programa que determinará las acciones del microcontrolador y su funcionamiento. Existen distintas maneras de desarrollar el programa, dependiendo del lenguaje inicial que se utiliza para escribir el programa: Lenguaje Ensamblador - Lenguaje de Máquina/Código Objeto (.asm) ensamblador (.hex, .o, .bin, .coff) Lenguaje de Alto Nivel - Lenguaje Assembly - Lenguaje de Máquina/Código Objeto (.c, .cpp) compilador (.asm) ensamblador (.hex, .o, .bin, .coff) En la Fig. 85 se muestran las dos alternativas típicas que tiene el desarrollador para generar el código de máquina que es entendido por el microcontrolador.

Transcript of 9 Desarrollo del Software - Servidor de la Biblioteca de...

DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 111

99 DDeessaarrrroolllloo ddeell SSooffttwwaarree

9.1 Proceso de Desarrollo.

El proceso de desarrollo de una aplicación basada en microcontroladores se

compone de las siguientes etapas principales, las cuales se explican en más detalle en las siguientes sub-secciones.

• Desarrollo de software : Esta etapa corresponde a la escritura y

compilación/ensamblaje del programa que regirá las acciones del microcontrolador y los sistemas periféricos conectados a este.

• Programación del microcontrolador : En esta etapa el código de máquina correspondiente al programa desarrollado en la etapa anterior se descarga en la memoria del microcontrolador.

• Prueba y verificación : Por último, el microcontrolador debe conectarse al circuito base y someterse a pruebas para verificar el funcionamiento correcto del programa.

9.1.1 Desarrollo del software.

En esta etapa consiste en escribir y compilar/ensamblar el programa que

determinará las acciones del microcontrolador y su funcionamiento. Existen distintas maneras de desarrollar el programa, dependiendo del lenguaje inicial que se utiliza para escribir el programa:

• Lenguaje Ensamblador - Lenguaje de Máquina/Código Objeto (.asm) → ensamblador → (.hex, .o, .bin, .coff) • Lenguaje de Alto Nivel - Lenguaje Assembly - Lenguaje de Máquina/Código

Objeto (.c, .cpp) → compilador → (.asm) → ensamblador → (.hex, .o, .bin, .coff) En la Fig. 85 se muestran las dos alternativas típicas que tiene el desarrollador

para generar el código de máquina que es entendido por el microcontrolador.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 112 Universidad de Sevilla

Fig. 85 Alternativas para generar el código máquina

El método básico es escribir el programa en lenguaje de Ensamblador en un

archivo de texto con extensión .asm y luego utilizar un programa ensamblador para generar un archivo en lenguaje de máquina, también denominado código de máquina o código objeto (object code), compuesto por instrucciones en código binario que son directamente entendidas por la CPU del microcontrolador. El ensamblador normalmente genera un archivo con extensión .hex (por hexadecimal), .o (por objeto), .bin (por binario), ó .coff (common object file format) dependiendo del ensamblador. El lenguaje Ensamblador se compone de instrucciones mnemónicas de bajo nivel, es decir que están ligadas a las carácter místicas del microcontrolador y con un numero mínimo o nulo de abstracciones. Al carecer de abstracciones, el lenguaje Ensamblador es más difícil de emplear, requiere experiencia y un mayor tiempo de desarrollo. La ventaja es que el código de máquina generado a partir de un programa escrito en lenguaje de máquina es por lo general más eficiente, ya que el programa se desarrolla en un nivel cercano a las características del hardware.

Otra alternativa es emplear un lenguaje de alto nivel con una mayor cantidad

de abstracciones, la cuales son más fáciles de usar y reducen los tiempos de desarrollo. Tal vez los lenguajes de alto nivel más comunes para la programación de controladores es el C y C++, pero también existen otros lenguajes variantes del BASIC y el Pascal. Una vez escrito el programa en el lenguaje de alto nivel, será necesario emplear un compilador para traducirlo, ya sea a lenguaje de Ensamblador o directamente a lenguaje de máquina. Es importante considerar que el código de Ensamblador generado por los compiladores tiende a ser más largo e ineficiente que aquel directamente desarrollado en lenguaje de Ensamblador. Esta desventaja puede ser critica en ciertas aplicaciones que requieren un programas compactos y de una alta velocidad de ejecución. Un vez que el compilador ha generado el código de Ensamblador (.asm), será necesario utilizar un ensamblador para generar el código binario de máquina.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 113

9.1.2 Programación del microcontrolador.

Este proceso corresponde a utilizar un programa en el PC que toma el código ensamblado (.hex, .o, .bin, .coff) para el microcontrolador específico, y lo envía mediante algún puerto (serial, paralelo, USB, etc.) a un dispositivo que lo escribe en la memoria del microcontrolador. Se acostumbra denominar programador tanto al software como al hardware involucrados para este propósito, lo cual puede prestarse a confusión. El software programador a veces recibe también el nombre de downloader, ya que su propósito es descargar o transferir desde el PC al microcontrolador el código ensamblado.

En la Fig. 86 se muestran las componentes involucradas en el proceso de

programación del microcontrolador. Es importante mencionar que no deben confundirse los términos desarrollo o programación del software y programación del microcontrolador, el primero se refiere a escribir el programa, mientras que el segundo se refiere transferir el código de máquina a la memoria del microcontrolador.

Fig. 86 Programación del microcontrolador.

9.1.3 Prueba y verificación.

Una vez programado el microcontrolador, se puede instalar en el circuito final para comprobar su adecuado funcionamiento. Existen herramientas de software que permiten simular el comportamiento de un microcontrolador, muy útiles cuando el programa alcanza cierta complejidad para resolver problemas en un circuito real.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 114 Universidad de Sevilla

9.2 Ciclo de diseño

En la Fig. 87 vemos el ciclo de diseño con el que vamos a trabajar, desde el diseño hasta el análisis del código depurado, siendo todo este proceso un ciclo que repetiremos hasta conseguir el resultado final.

CICLO DE DISEÑO:

Fig. 87 Ciclo de diseño

La primera fase es la edición del programa fuente , utilizando para ello el

editor MPLAB. Si pretendemos desarrollar el código de la aplicación en lenguaje de alto nivel, debeos utilizar un compilador como PCW de CCS.

Independientemente de que lenguaje utilizaremos para la construcción del

programa fuente, será necesario convertir dicho programa en lenguaje máquina que es el empleado por los microcontroladores PIC, utilizando el ensamblador MPASM que vienen incluido en el entorno de desarrollo integrado MPLAB IDE

Durante la fase de construcción, detectaremos los errores de sintaxis que se

hayan podido cometer en la edición del programa fuente, ya que automáticamente, el ensamblador o el compilador que estemos usando nos remarcará todas aquellas líneas que no sea capaz de traducir a código máquina. Una vez solucionados los problemas obtendremos el código máquina o hexadecimal, es decir, un archivo con extensión .HEX. El resto de los archivos suelen ser archivos auxiliares con información necesaria para la traducción, empleados por la herramienta de depuración, emulación o simulación.

Concluida la fase de construcción del proyecto llega la fase de construcción

del proyecto, comprobando que el código generado tiene el funcionamiento deseado, entrando en la fase de depuración del programa.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 115

Una vez tengamos el programa completamente construido y depurado, entramos en la fase final, de volcado sobre la memoria del PIC, terminando entonces la fase última de programación.

9.3 Manejo de las Aplicaciones.

9.3.1 Características de memoria e instrucciones para comenzar a programar

Con los ejemplos de las lecciones que Microchip proporciona de forma gratuita en su página web, podemos comenzar a entender el funcionamiento del dispositivo.

Como ya se ha comentado en la introducción de la memoria, los

microprocesadores poseen una distribución de la memoria que separa las aplicaciones de datos de las funciones de instrucción. Vemos estos aspectos de forma detallada:

ORGANIZACIÓN DE LA MEMORIA: Los microprocesadores se diseñan de forma que encontramos separada la

memoria de datos de la memoria de programas, lo que permite una rápida ejecución ya que tendremos buses de datos y direcciones separados.

La Memoria de Datos esta formada con ‘file registers’. Las instrucciones que

necesitan acceder a estos datos utilizan 12 bits, por lo que sólo pueden direccional 4096 posiciones. Estos ‘file registers’ son agrupados en páginas de forma que podemos acceder a distintas páginas con dos bits más significativos del Registro BSR<3:0>. Para cargar un valor literal en el registro BSR se utiliza la instrucción MOVLB.

En la memoria de datos existen posiciones que actúan como Funciones

Especiales de Registro (SFRs), las cuales hacen posible la comunicación del programa con los periféricos, actuando como registros de control de la CPU. Comienzan desde la posición superior del Banco 15 y extendiéndose hacia las direcciones inferiores. Además, en la memoria de datos existen posiciones que están reservadas para el Registro de Propósito General (GPRs), donde se pueden almacenar las variables del programa. Los GPR comienzan desde la dirección inferior (0x000) del Banco 0 y se expansionan hacia direcciones superiores.

Para la programación y el uso del USB con el PIC18F2550 hemos de tener en

cuenta que los bancos de datos 4 y hasta el 7 serán los que asignemos como buffer para la comunicación con el USB. Este área será compartida entre el microcontrolador y el Motor de Interfaz USB Sucesivo (SIE) y será usada para transferir datos directamente entre los dos.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 116 Universidad de Sevilla

La Memoria de Programa es de tipo Flash y contempla un espacio de 2MB direccionable por byte a partir del Contador de Programa (PC) de 21 bites. Cada instrucción tiene una longitud de 16 bit y en consecuencia su dirección siempre debe de ser par.

La memoria Flash puede ser escrita, leída y borrada durante el

funcionamiento del dispositivo, siempre que sea correcta a VDD.

Fig. 88 Memoria de Programa

Fig. 89 Memoria de Datos.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 117

FORMATO DE LAS INSTRUCCIONES Todas las instrucciones se pueden ajustar a uno de los tres formatos que

especificamos a continuación: 1. Byte Instructions: Constituida por 7 bits para direcciones de datos, 1 bit

de destino y 6 bit de código. Los 7 bit de la dirección del dato, junto con los bits RP0 y RP1 del Registro de Estado forman un direccionamiento de 9 bits para el dato con el que se pretende trabajar. Los otros datos con los que realizar la operación se van a encontrar en el Registro de Trabajo (llamado W o Wreg). Después de realizar la operación, el bit de destino especifica donde debemos almacenar el resultado, si en el registro de trabajo o bien en el registro original del dato.

2. Bit Instruction: Opera sobre un bit especifico dentro del registro. Formada

por 7 bits para la dirección del dato, 3 bit numéricos y los restantes 4 bit para el código de la instrucción.

3. Literal Instructions: Contienen el valor del dato dentro de la propia

instrucción. Igual que antes el Registro de Trabajo nos indicará el valor del otro dato necesario en la instrucción.

Existen además 3 formas de declarar una variable: #define Length 0x00 ; Localizamos la variable en una dirección Length equ 0x00 ; Damos un valor inicial a la variable cblock 0x00 ; Comienza un bloque de variables Length ; Se almacena en la dirección 0x00 Width ; Se guarda en 0x01 Area:2 ; Ocupa dos bytes, 0x02 y 0x03 Girth ; Se queda en la posición 0x04 endc

9.3.2 Primeros pasos en la programación

La tarea aparentemente directa de simplemente conectar un LED a uno de los pines de salida del PIC para hacer encender una luz nos aporta los siguientes conocimientos:

• La capacidad de usar un ambiente de desarrollo; para cambiar el

código a lenguaje ensamblador conocido por el PIC • La capacidad de usar correctamente el programador del PIC para

cargar el código en el chip • Colocar el PIC en el modo correcto de operación • La escritura del código que pondrá en el pin de salida el nivel de señal

adecuado, alto o bajo, para hacer encender al LED.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 118 Universidad de Sevilla

Si conseguimos encender el LED, entonces sabremos que tenemos un entorno de trabajo, programador, ensamblador... que comprende la arquitectura y las instrucciones del PIC y que serán suficientes para comenzar a trabajar.

En las líneas siguientes podemos ver el código de nuestro primer programa.

;****************************************************************** ; ; PROYECTO FIN DE CARRERA ; PLACA DETECTOR DE MOVIMIENTO ; ENCENDER LED 1 ; ; Realizado: MARTA ARENAS MAS ; Fecha: 22-Mayo-2008 ; Versión: v1 ; ;****************************************************************** ; ; Ficheros Utilizados: P18F2550.INC ; 18F2550.LKR ; ;****************************************************************** LIST P=18F2550, F=INHX32 ; Procesador utilizado #include <P18F2550.INC> ; Incluir el fichero con símbolos y etiquetas ;****************************************************************** ORG 0x00 ; Inicio en el Vector de Reset goto INICIO ; Va a la primera instrucción del programa ORG 0x18 ; Salta los Vectores de Interrupción ;****************************************************************** ; Comienza el programa INICIO movlb B'00001111' ; Selecciono Registro del Banco 1 bcf TRISB,7 ; Configuro pin RB7 como Salida bsf PORTB,7 ; Enciende led conectado a RB7 LED 1 goto $ ; espera ahí end ;****************************************************************** ; Fin del programa END

Antes de programar el PIC con el código anterior es necesario informar al

MPLAB que desactive el “Watchdog” y de esta manera evitar que se produzca un reset del PIC y también hay que indicarle el tipo de oscilador que estamos utilizando, en nuestro caso un oscilador HS+PLL.

Para configurar estos bits tenemos que ir al menú de “Configura” y en la

pestaña de “Configure bits” podemos configurarlos.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 119

Este primer programa es mejorable tanto en extensión como en el uso de

instrucciones, pero como ya dijimos anteriormente su función era simplemente para aprender a programar con el software MPLAB y saber utilizar diferentes instrucciones en assembler, por eso no creímos necesario mejorarlo ya que no aportaba nada a nuestro proyecto.

9.4 Conexión PC - USB

USB es un bus punto a punto, con inicio en el HOST y destino en un dispositivo

o en HUB. El protocolo de comunicación se basa en el paso de testigo, donde el HOST proporciona el testigo al dispositivo seleccionado para la comunicación.

La conexión del USB pasa por la definición de un conjunto de descriptores que

defina el comportamiento del dispositivo que se pretende conectar y la utilización de un driver que configure el PC la comunicación establecida con ese dispositivo.

Como ya hemos comentado existen varias clases de descriptotes. Los que

vamos a destacar a la hora de definir y configurar un nuevo dispositivo USB son los descriptotes de dispositivo y de interfaz que contienen tres campos especialmente relevantes para su clasificación, el campo de Clase, subclase y protocolo. Estos son los campos usados por el sistema operativo para asociar un dispositivo o una interfaz a un driver genérico.

Una clase USB, como ya hemos indicado, es una agrupación de dispositivos

de características comunes, es decir, que utilizan una misma forma de comunicarse con el entorno. La clase de dispositivo permite conocer la forma en que la interfaz se comunica con el sistema, el cual puede localizar el driver que puede controlar la conectividad entre interfaz y el sistema. [11]

USB sólo permite al driver comunicarse con el periférico a través de las

tuberías (pipes) establecidas entre el sistema USB y los Endpoints del periférico. Los tipos de transferencia a través de las pipes dependen de los Enpoints y pueden ser: Bulk, Control, Interrupt e Isocronous.

Estos enlaces, que definen el ancho de banda, el tipo de transferencia, la

dirección, el flujo de datos y el tamaño del paquete de datos, se implementan en la inicialización del USB. Un Endpoint es un buffer dentro del dispositivo o el periférico donde se almacenan paquetes de información. Todos los dispositivos deben admitir al EP0, el cual recibe el control y las peticiones de estado durante la enumeración del dispositivo. Cuando se conecta un dispositivo al HOST se produce la enumeración, asignando la dirección y permitiendo la transferencia de datos.

En el sistema que diseñaremos existirá una librería ****.h en la que se

configura el dispositivo que vamos a emplear, es decir, se inicializan los descriptores necesarios para la configuración del USB.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 120 Universidad de Sevilla

En la librería de cabecera es necesario indicar: 1. En el descriptor de dispositivo existe un campo (bDeviceClass) que indica

si el dispositivo pertenece a una clase USB definida. En este caso, el campo presentará un valor entre 01h y FEh dependiendo de la clase a la que pertenezca. El valor FFh significa que la clase es específica de un vendedor y está definida por este. Algunos dispositivos especifican la clase en el descriptor de interface, para este tipo de dispositivos este campo será 00h y en el campo bInterfaceClass del descriptor de interfaz se indicará la clase a la que pertenece. No todos los dispositivos pertenecen a una clase.

2. Si el periférico no pertenece a una clase ya definida o se le quiere asignar un driver específico (no genérico), los campos de clase, subclase y protocolo del descriptor de dispositivo o interfaz deben de valer FFh (clase específica de un vendedor) y en los campos del descriptor de dispositivo idVendor y idProduct se debe indicar tanto el identificador de vendedor y como el del producto. Cada fabricante tiene un identificador de vendedor único que debe incluir en el descriptor de dispositivo de sus productos. El identificador de producto lo decide el fabricante para identificar a los dispositivos. Estos dos valores se deben incluir también en un fichero INF que el sistema operativo utilizará para decidir que driver debe asignar al periférico en función de estos dos valores.

Cuando el sistema operativo enumera un nuevo dispositivo USB, el Administrador de Dispositivos compara los datos de todos los ficheros INF con la información de los descriptores obtenida del dispositivo durante la enumeración. Para evitar tener que leer todos los INF cada vez que se detecta un nuevo dispositivo, Windows tiene una base de datos de información sobre drivers con información obtenida de los ficheros INF. [10]

El periférico que se va a desarrollar no pertenece a ninguna clase genérica, así

que habrá que indicar el driver que se le quiere asignar. El driver que se utilizará será un driver USB de propósito general para Windows suministrado por Microchip (mchpusb.sys). Así mismo, Microchip proporciona un identificador de vendedor (0x04D8) que puede ser utilizado en productos desarrollados con microcontroladores PIC.

Respecto a los puntos finales, además del EP0 (que siempre se utiliza), se

necesitará otro más para pasar los datos del periférico al Host. La dirección de los datos será de entrada y el tipo de transferencia que utilizado será tipo bulk, masiva. Utilizaremos el EP1, que es bidireccional y tiene tres modos de comunicación, bulk, Interrupción o isócrona.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 121

9.5 Creación del fichero INF.

Cuando el sistema operativo detecta un nuevo periférico USB, intenta determinar qué driver debe utilizar para comunicarse con el dispositivo y una vez determinado, cargar el driver seleccionado. Esto lo lleva a cabo el Administrador de Dispositivos, que utiliza instaladores de clase y dispositivo y archivos INF para encontrar el driver adecuado para cada dispositivo.

El Administrador de Dispositivos además de ser el responsable de instalar,

configurar y desinstalar dispositivos, también se encarga de añadir información sobre cada dispositivo en el registro del sistema, el cual contiene información sobre el hardware y el software instalados en el sistema.

Los instaladores de clase y dispositivo son DLLs. Windows tiene una serie de

instaladores por defecto que el Administrador de Dispositivos utiliza para localizar y cargar drivers para dispositivos pertenecientes a clases soportadas por el sistema operativo.

El archivo INF es un fichero de texto que contiene información que ayuda a

Windows a identificar el dispositivo. Este archivo indica al sistema operativo que drivers debe utilizar y que información debe almacenar en el registro. [10]

La información en un archivo INF está dividida en secciones. Cada sección

puede ser identificada porque su nombre está entre corchetes. Las principales secciones son:

• Versión : Especifica el sistema operativo para el que está destinado el fichero INF.

Para dispositivos que utilizan WDM (Windows Driver Model) drivers, el valor puede ser $Windows 98$, $Windows NT$ o $Chicago$, independientemente del sistema operativo que esté instalado en el ordenador. En esta sección se indica también el nombre de la clase de los dispositivos instalados con este fichero así como un identificador de clase que es utilizado por el registro del sistema para identificar a los dispositivos pertenecientes a esta clase.

• ClassInstall : En esta sección se indica si se ha de instalar una nueva clase. El Administrador de Dispositivos únicamente procesa la sección si una clase de dispositivo aún no está instalada en el sistema. Aquí será donde indicaremos el icono, el nombre y la descripción de la clase así como el nombre del archivo DLL (tempusbci.dll) que instalará la nueva clase en el Administrador de Dispositivos.

• Manufacturer : Esta sección contiene el identificador de vendedor y de producto, que en nuestro caso se corresponde con (USB\ VID_04D8 & PID_0011). Cuando el Administrador de Dispositivo encuentra una coincidencia entre estos valores y los identificadores obtenidos del dispositivo durante la enumeración, sabe que ha encontrado el archivo INF correcto.

• DestinationDirs : Indica el directorio o directorios donde se copiarán los ficheros.

• Strings : Define las cadenas referenciadas en las otras secciones.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 122 Universidad de Sevilla

9.6 Creación de una nueva clase.

El último paso ha sido la edición del Driver suministrado por Microchip de tal forma que apareciera en el Administrador de Dispositivos una nueva clase con un icono personalizado.

El periférico desarrollado no pertenece a ninguna de las clases USB definidas,

así que lo que debemos crear una nueva clase que aparezca en el Administrador de Dispositivos con un icono personalizado. Para esto, ha sido necesario crear una DLL que exporte ese icono. Se necesita para ello el DDK (Driver Development Kit Windows_Server_2003_sp1_ddk) de Microsoft:. Esta herramienta incluye muchos ejemplos y se ha utilizado uno de ellos para crear la DLL. El ejemplo utilizado se llama Toaster y es un ejemplo genérico sencillo con código comentado que puede ser usado para aprender a escribir drivers, filtros, ficheros INF o cómo instalar una clase o un paquete. La dirección en la que encontramos este fichero, una vez instalado el DDK de la página principal de Micrsoft, es la siguiente:

C:\WINDDK\3790.1830\src\general\toaster\classinstaller. Incluye varios directorios que contienen todos estos ficheros, aunque el único

interesante para nosotros es el directorio classinstaller. Dentro de este directorio sustituiremos el icono del ejemplo por el que nosotros vayamos a utilizar, en este caso el icono se llama icon.ico, y el fichero tostrcls.def lo sustituiremos por otro llamado picusbci.def que contendrá el siguiente código:

LIBRARY PICUSBCI EXPORTS

PicUSBClassInstaller El resto de ficheros del directorio no hace falta sustituirlos pero si que es

necesario realizar algunos cambios en ellos (básicamente es cambiar el nombre de la clase utilizada en el ejemplo por el que utilizaremos nosotros y que es PicUSBClassInstaller). De esta forma, en el fichero sources habrá que poner la línea TARGETNAME=picusbci, y en classinst.c habrá que sustituir el nombre, quedando de la siguiente forma:

DWORD CALLBACK PicUSBClassInstaller(

IN DI_FUNCTION InstallFunction, IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL )

En la plantilla de recursos classinst.rc se tiene que cambiar por una parte el

icono que se utilizará y por otra, en la información de la versión, se incluye información sobre la descripción de la clase, el nombre del fabricante y el nombre del fichero resultante encargado de realizar la instalación de la clase en el Administrador de Dispositivos (archivo DLL).

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 123

Cuando se han realizado todos estos cambios se procede a crear el archivo DLL que necesitamos. Para ello en la línea de comandos del DDK se ejecuta build –cZ toaster. Con este comando se crearán todos los ficheros .sys, .exe y .dll del proyecto Toaster, incluyendo el archivo DLL necesario para instalar la clase y que se llama picusbci.dll. De todos los ficheros creados este será el único que nos servirá y permitirá que al conectar el periférico al ordenador.

Debemos entonces modificar el archivo .inf suministrado por Micrchip, para que

lea la dll creada por la DDK. El driver en sí lo suministra Microchip y no debemos modificarlo, aunque podría estudiarse, ya que existen limitaciones de velocidad en el driver que proporciona y no acepta la velocidad completa de los dispositivos USB, sin embargo es un estudio complejo que no es necesario en el proyecto.

9.7 Resultado de la comunicación USB - PC

Cuando se conecta el dispositivo al ordenador, Windows muestra el mensaje Nuevo Hardware Encontrado. Si el periférico nunca ha sido enumerado en el sistema, el sistema operativo necesita localizar un driver para él. Al ser la primera vez que se conecta el dispositivo y no ser de una clase genérica, Windows no encontrará un archivo INF que pueda utilizar para asignarle un driver y lanzará el Asistente para Agregar Nuevo Hardware donde se puede indicar la localización del archivo INF necesario para la instalación del periférico.

Una vez localizado, se carga el driver indicado, se añade el periférico en el

Administrador de Dispositivos y se indica al usuario que la instalación del dispositivo ha finalizado de forma correcta. En el Administrador de Dispositivos se puede ver también la descripción del dispositivo y el fabricante, obtenidos del archivo INF.

Fig. 90 Nuevo Hardware USB funcionando correctamente.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 124 Universidad de Sevilla

Durante esta operación, se ha copiado el fichero INF (PicUSB.inf) en el

directorio \windows\inf, el driver suministrado por Microchip (mchpusb.sys) en \windows\system32\drivers y el instalador de clase (picusbci.dll) en \windows\system32, de forma que la próxima vez que se conecte el dispositivo, el ordenador lo reconocerá sin necesidad de indicar ningún dato.

9.8 Migración RS232 a USB

La interfaz RS232 está desapareciendo de los ordenadores personales y esto supone un problema, ya que muchas de las aplicaciones que se realizan con microcontroladores utilizan este bus para la comunicación con el PC. La solución ideal es migrar todo el protocolo de comunicación a tecnología USB, sin embargo, esto lleva consigo el inconveniente de tener que rediseñar todo el software para que soporte un nuevo tipo de transferencia de datos.

Para hacer la transición de forma cómoda, lo más conveniente es emular un

RS232 con el USB, con la ventaja de que el PC verá la comunicación USB como una conexión COM RS232 y no requerirá cambios en el software existente.

Otra ventaja es que se utilizan drivers suministrados por Windows, como el

usbser.sys ó el ccport.sys, fácilmente accesibles. Para realizar la comunicación de esta forma debemos acudir a la definición de

clase de dispositivo USB, campo del descriptor de dispositivo. Microchip estable la especificación Clase de Dispositivo de Comunicación (CDC) que define algunos modelos de comunicación, incluyendo la comunicación serie, que se apoya en el driver usbser.sys de Windows.

Para la especificación CDC USB se necesitan dos intefaces USB, primero la

interfaz Communication Class, utilizando Endpopint de entrada de Interrupción y después la interfaz Data Class usando un Endpoint de Salida masiva de datos y un Endppoint de Entrada masiva de datos. Esta interfaz es la utilizada para transferir datos que normalmente deberían ser transmitidos por RS232.

El archivo necesario para definir la interfaz lo proporciona Microchip de forma

gratuita en su página web y es el llamado mchpcdc.inf, con el el PC será capaz de reconocer el dispositivo y asociarle le driver necesario para su configuración, control y manejo.

Tanto este fichero como el fichero de cabecera ****.h donde se definen la

interfaz que debe de adoptar el dispositivo son necesarios para la conexión del USB CDC al ordenador. El resultado, una vez configurado el dispositivo y obtenido el archivo. Inf y driver de la configuración, tras pasar el asistente de Hardware de Windows es el que se muestra a continuación:

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 125

Fig. 91 Nuevo Hardware USB CDC funcionando correctamente

9.9 El Compilador y las librerías

El compilador utilizado para crear el programa e el PIC es el PCWH de la empresa CCS, como ya hemos comentado.

La decisión de utilizar un compilador se realizó debido a las ventajas que

supone programar en lenguaje C, además de incluir ayudas gracias al uso de librerías con las que se facilita la tarea de programación de la aplicación, incorporando funciones para el manejo de las aplicaciones como el USB, o el Convertidor A/D. Las librerías imprescindibles para la generación de la aplicación son:

• 18F2550.h: Fichero de cabecera estándar para dispositivos PIC18F2550. Librería con las direcciones de los pines del PIC 18F2550 y la definición de constantes esenciales para programar este controlador.

• pic18_usb.h : Capa hardware de los dispositivos PIC18Fxx5x. Librería

que incluye las funciones y constantes necesarias para la comunicación USB con los microcontroladores de la familia 18Fxx5x.

• usb.c: Manejador de peticiones USB estándar. Otra librería con más

funciones generales sobre la comunicación USB, maneja las interrupciones USB y el USB Setup Requests en Endpoint 0.

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 126 Universidad de Sevilla

• usb.h : Librería con el prototipo de funciones, definiciones y variables globales USB, utilizadas en el driver USB.

• Usb_cdc.h : Driver que permite utilizar una clase de dispositivo CDC

USB, emulando un dispositivo RS232 y lo muestra como un Puerto COM en Windows.

Para que la conversión A/D se realice de forma correcta es necesario añadir en

el fichero 18F2550.h la directiva #device PIC18F2550 ADC=10. Esta directiva indica el número de bits que debe devolver la fución read_adc(). Es necesario indicarlo ya que, en caso contrario, sólo nos devolvería los 8 bits más significativos de la conversión A/D (registro ADRESH). En la conversión A/D se utiliza justificación a izquierdas, por lo que, de los 10 bits resultantes de la conversión, los 8 más significativos se almacenarán en el registro ADRESH, mientras que los 2 bits menos significativos se almacenarán en los bits más significativos del registro ADRSL.

9.10 Funciones Utilizadas en la aplicación del microcontrolador

Indicamos en este apartado algunas de las funciones que se utilizan en el

compilador CCS para manejar los recursos que nos ofrece el PIC

9.10.1 Manejo del Convertidor A/D

Las funciones más importantes de configuración y control del Convertidor A/D

• Setup_port_A(AN0_TO_AN” | VSS_VDD): Los pines 0,1 y2 del Puerto A se establecen como entradas analógicas, y las tensiones de referencia son las que entran en el PIC por los pines VDD y VSS.

• Setup_adc(ADC_CLOCK_INTERNAL): Configuración del uso de reloj

del PIC.

• Set_adc_channel(1): Indicarle el canal donde debe recibir la información.

• Set_tris_A(0b00000111): Configuración de la entrada del Puerto A

• Read_adc(): Pasamos a la lectura del valor convertido, almacenándolo

en una variable que puede ser un entero.

CAPITULO 9

Desarrollo Software DDiisseeññoo IInntteeggrraaddoo

Universidad de Sevilla Pág. 127

9.10.2 Manejo del USB

Las funciones más importantes para el manejo del USB, son entre otras:

• usb_init(): Inicializa el hardware USB. Espera en un bucle infinito hasta que el periférico USB es conectado al bus (aunque eso no significa que haya sido enumerado por le PC). Habilita y utiliza la interrupción USB.

• usb_task(): Si se utiliza una detección de conexión para la inicialización,

entonces se debe llamar periódicamente a esta función para controlar el pin de detección de la conexión. Cuando el PIC es conectado o desconectado del bus, esta función inicializa el periféric USB o resetea el USB snack y el periférico.

• usb_enumerated(): Devuelve un TRUE si el dispositivo ha sido

enumerado por el PC y, en este caso, el dispositivo entra en modo de operación normal y puede enviar y recibir paquetes de datos.

• usb_wait_for_enumerated(): Se encarga de mirar el estado de la

conexión, asegurando la correcta inicialización del mismo.

• usb_cdc_putc(c): Coloca un carácter en el buffer de transmisión; en el caso de que este lleno esperará a que pueda enviarlo.

• usb_put_packet(1, envia, 1, USB_DTS_TOOGGLE ): Coloca paquetes

de bytes en el buffer para que el PC lo recoja. En este caso, enviamos el paquete de tamaño 1 byte utilizando la variable envia que es la que contiene el byte a enviar.

9.11 Aplicación del Microcontrolador.

El programa que se ejecutará en el microcontrolador tiene como objetivo el envío de datos a través del módulo de comunicación USB. Su funcionalidad será bastante intuitiva utilizando las funciones descritas anteriormente.

En primer lugar será necesario establecer las palabras de configuración del

dispositivo, sabiendo el modo en el que vamos a desarrollar la aplicación y la clase de dispositivo que usaremos en la comunicación con el USB. Las opciones adecuadas:

• Oscilador en modo HSPLL con los valores pre y post-escala adecuados para

obtener una frecuencia interna de 48MHz necesaria para la comunicación con USB de alta velocidad.

• Habilitación del regulador interno del módulo USB • Deshabilitación del Wachdog Timer que no vamos a utilizar en el proyecto

CAPITULO 9

DDiisseeññoo Desarrollo Software IInntteeggrraaddoo

Pág. 128 Universidad de Sevilla

El programa, al conectar el periférico al host y llegarle alimentación, hará que se encienda un LED. Una vez alimentado se procederá a la inicialización de los registros USB, tras lo cual comenzará el proceso de enumeración del dispositivo USB por parte del host. Si este finaliza correctamente se apagará el LED que estaba encendido y se encenderá un segundo LED, indicando que todo esta listo para comenzar y esperando en esta situación durante tres segundos, tiempo en el que deberemos establecer la comunicación con la aplicación desarrollada en el PC para recibir los datos leídos desde el dispositivo.

Tras la inicialización del USB se configurarán los registros del convertidor A/D y

se comenzará con la lectura consecutiva de las señales analógicas procedentes de las entradas AN0, AN1 y AN2 y el envío de los resultados obtenidos por el módulo USB. La conversión y el envío de datos se realiza insertando un retraso de 0.5ms entre cada conversión y envío, lo que permite controlar que las conversiones y los envíos se realicen de forma ordenada.

¿Dispositivo Enumerado?

Fig. 92 Diagrama de Flujo del programa del Microcontrolador

LED ON Inicialización registros USB

Enumeración

LED1 OFF / LED2 ON Configuración modulo A/D

Conversión A/D Transmisión de datos