El Software. 1. Compiladores de C para microcontroladores Avr Pág El Entorno de Desarrollo Software (EDS) Utilizado Pág.72

Capítulo 5 El Software Indice 1. Compiladores de C para microcontroladores Avr _______________________Pág. 69 1.1. Comparativa de Compiladores y Razon

11 downloads 73 Views 1MB Size

Story Transcript

Capítulo 5 El Software Indice 1. Compiladores de C para microcontroladores Avr _______________________Pág. 69 1.1. Comparativa de Compiladores y Razones de Elección

2. El Entorno de Desarrollo Software (EDS) Utilizado _______________________Pág.72 2.1. Descripción del EDS 2.2. Instalación del EDS 2.3. Utilización del EDS 2.4. Particularidades del código C para microcontroladores 2.5. Configuración y Utilización de periféricos 2.6. Proceso para la programación del microcontrolador

3. Módulos del programa del registrador ________________________________ Pág. 80 3.1. Enumeración de los Módulos del Programa 3.2. Configuración de los Pines de E/S de propósito general 3.3. Módulos de la Pantalla LCD 3.4. Salvado de datos en la Dataflash 3.5. La memoria EEprom 3.6. Conversión de Datos de 8 bits a 16 bits 3.7. Comunicación por el Puerto Serie a través de la UART 3.8. Modos de Ahorro de Energía 3.9. Captura de la señal analógica procedente del sensor

Resumen del Capítulo Este capítulo se centra a la parte en la que se invirtió más tiempo de ejecución en el proyecto, que es la parte de la programación del sistema electrónico de registro de datos. En él se comienza haciendo una comparación de los distintos compiladores de C para microcontroladores Avr de que se dispone en el mercado, y una vez elegido el Gnu-Gcc, se describe el entorno de desarrollo software utilizado, y se dice cómo instalarlo y utilizarlo eficientemente. Por último se describen los módulos que forman el programa del registrador de datos.

Capítulo 1

Motivaciones del Proyecto

1. Compiladores de C para microcontroladores Avr 1.1. Comparativa de Compiladores y Razones de Elección Dadas las características del código que de deseaba implementar (no requiere tiempo real y si versatilidad) de optó por utilizar un lenguaje de alto nivel C para la escritura del código del programa que correrá en el microcontrolador.. Dicho código es más versátil porque es más cómodo de programar y porque las modificaciones en él son más fáciles de realizar dado que es un lenguaje de más alto nivel. Una característica que hace que los microcontroladores Atmel estén especialmente indicados para su programación con el Lenguaje C es que están diseñados y optimizados para su programación en C, y por ello presenta características tales como 32 registros acumuladores de uso general que le dan una gran libertad a los compiladores de C a la hora de compilar el código de C a ensamblador. Esta característica es de vital importancia ya que A la hora de escoger un compilador disponemos de múltiples opciones disponibles: •

Codevision AVR



Gcc-Avr



ImageCraft Compiler



IAR Embedded Workbench



Otros

De estos 4 destacados el único que no es un producto comercial el es GCCAVR, que se trata de un programa bajo licencia de Software Libre y de Libre Distribución y uso. El resto son programas cuya licencia pueden llegar a costar en su configuración básica 1.200€, como es el caso del compilador IAR. Pasemos a enumerar las característica de cada uno de ellos:

CodeVision AVR El entorno IDE (Integrated Development Environment) es amigable y muy fácil de usar.

69

Capítulo 1

Motivaciones del Proyecto

Está basado en proyectos, e incluye un generador de código automático llamado Codewizard AVR que genera todo el código necesario para la inicialización de los periféricos internos de los microcontroladores AVR, así como de algunos periféricos externos (usando librerías que también incluye). Dichas librerías dan soporte a un gran número de aparatos frecuentemente usados como son pantallas LCD, Relojes de Tiempo Real RTC, sensores de temperatura, la UART, el SPI, etc... Codevision dispone también de un programa terminal que puede enviar y recibir archivos y también visualizar los datos recibidos o enviarlos en hexadecimal o ASCII.

GCC-AVR El compilador GNU para AVR es una versión del popular compilador GNU C a la plataforma AVR. Se ejecuta sobre MsDos o una consola MsDos bajo Windows32, o bajo Linux. GCC-AVR no dispone de un entorno IDE (Entorno de Desarrollo Interactivo) o las herramientas que acompañan a los otros compiladores. ES tan sólo un compilador C. Sin embargo, la Distribución WinAvr dispone de herramientas de este tipo, aunque no del IDE, ya que si bien el programa Programmers Notepad es un potente editor de código, no tiene la integración y especialización necesaria como para considerarlo un IDE propiamente. En cualquier caso este compilador dispone de una gran ventaja sobre el resto de compiladores, y es que es completamente gratis y su código fuente está disponible en sourceforge.com bajo licencia de software libre. GCC-AVR, como todos los compiladores GNU se suministra con el programa estándar de Unix make, usado para construir (build) los proyectos. Pero aunque un en este compilador no dispone de un IDE, el programa de Atmel AVR Studio v3.28 puede ser utilizado como IDE para cualquier compilador basado en línea de código, y dicho AVR Studio incluso dispone de resaltado de código. Esto soluciona el problema prácticamente, aunque sigue habiendo la necesidad de gestionar los archivos makefile, aunque la mayoría de los usuarios pueden hacerlo sin problemas. Es de resaltar que las actuales versiones de AvrStudio v4 en adelante no permiten la utilización de GCC, por tanto sólo se recomienda la versión v3.28. No obstante, aunque AvrStudio puede utilizarse para la edición del código, el citado Programmers Notepad tiene unas opciones de resalado de código más potentes.

70

Capítulo 1

Motivaciones del Proyecto

IAR Embedded Workbench V4.12 for Atmel AVR Sin duda es el compilador de más potencia, con más herramientas, más profesional y que genera un código más eficiente, aunque por supuesto también es más caro (1.200€ por licencia) • Posee un IDE con editor y herramientas de gestión del proyecto. • Genera un código muy optimizado que genera el mínimo número de instrucciones en ensambaldo una vez compilado, soportando C y C++ • Incorpora archivos de configuración de los periféricos para AVR Classic, Atmega, incluyendo sus periféricos internos •Con soporte para el depurador JTAG ICE mkll • Dispone de librerías de funciones en tiempo real • Depurador C-SPY con simulador AVR y soporte para Hardware de depuración de Sistemas en Tiempo real RTOS-aware. • Proyectos de ejemplo AVR y plantillas de código • Guías de usuario y ayuda online

ImageCraft C Compiler Es un compilador totalmente compatible con ANSI C. ImageCraft es una empresa muy asentada en el campo de los compiladores para arquitecturas con microcontroladores desde 1994 (tiene compiladores para Motorola 68HC11, Atmel AVR, PsoC, y otros) El entorno IDE es muy fácil de usar. Está orientado a proyectos, e incluye un generador de código automático llamado Application Wizard que genera el código de inicialización para los periféricos internos de los microcontroladores AVR. Así pose librerías que dan soporte a periféricos como UART, SPI, EEPROM y también a funciones de comprobación de la pila.

71

Capítulo 1

Motivaciones del Proyecto

2. El Entorno de Desarrollo Software (EDS) Utilizado 2.1. Descripción del EDS El entorno de desarrollo del AvrButterfly utilizando en compilador GNU GCC está formado básicamente por dos programas: La distribución WinAvr, que es una recopilación de programas de software libre diseñados para facilitar las tareas de programación y desarrollo de los microcontroladores Avr. Dicha distribución WinAvr incorpora además del compilador gcc de consola, un editor de texto especialmente diseñado para ayudar al programador y hacer el código más legible mediante su resaltado con colores. El programador vía puerto serie mprog.exe, que permite transferir el programa compilado, que se encuentra en un archivo llamado main.hex, a la memoria flash del microcontrolador utilizando únicamente un cable de tres líneas.

2.2. Instalación del EDS Instalación de WinAvr La distribución WinAvr surge como una iniciativa para impulsar el desarrollo de software libre en el campo del desarrollo de los microcontroladores Avr de Atmel, a la vez de facilitar a sus potenciales usuarios el conocer la existencia de tales herramientas, y no sólo las más famosas, y también facilitar su actualización. Es por ello que dicho paquete de software incorpora no sólo dichas herramientas, sino además unos ficheros de ayuda y de descripción de cada una de las utilidades. Por supuesto, el soporte técnico es mayor según la herramienta tenga más importancia. Como hemos dicho, WinAvr instala automáticamente Programmers Notepad como editor de código, por lo que tan sólo necesitaríamos configurarle unos detalles a este último para mejorar su rendimiento (y esta es una aportación original de este proyecto).

Instalación de mProg.exe La distribución WinAvr incorpora todo lo necesario para la programación de los microcontroladores Avr, incluyendo un programa similar al mprog.exe, pero dado que este último tiene un interfaz de ventanas de Windows, y el que

72

Capítulo 1

Motivaciones del Proyecto

trae la distribución es en modo comando, se prefirió la utilización del original de Atmel. Para cuya instalación hubo que instalar la suite de desarrollo de Atmel AvStudio, que lo incluye.

Configuración Óptima de Programmers Notepad Además con macros diseñadas para que pulsando un botón se

a) Configurar los estilos de texto para una fácil programación A la hora de programar el código que se desea desarrollar, Programmers Notepad 2 presenta una característica que hace el código mucho más legible que el editor Notepad de Windows, y aunque se necesitan unos minutos para configurar el entorno gráfico con este aspecto, merece la pena completamente. Para configurarlo es necesario ir a la Barra de Menús de "Programmers NotePad2" y elegir: ----->/Tools/Options/ ----------> Hacer Click en Styles/ -----------------> Base Style Settings: Font: Bitstream Vera Sans Mono Size: 10 (esta fuente de letra es altamente recomendable, al ser de libre distribución, y equiespaciada) ----------> Hacer Click en Styles/Schemes/ Style

Text Colour

BackGround

Default

Black

White(default)

Default WhiteSpace

Black

White (default)

Comment

Green

Comment Line

Green

Number

DarkGreen

KeyWord

Indigo

String

Dark Green

Character

Sea Green

Operator

Blue

Identifier

DarkGreen

PaleYellow

Doc Comments

Black

BrightGreen (fill to end of line)

UUID

BrightGreen

FontStyle

Bold & Italic Bold Bold

EndOfLineString

Preprocessor Verbatim

DarkRed

Coment Line Doc

Green

/** */ Bold

//

Bold

#define

Bold Lavender (fill to end of line)

///

Tabla 1: Configuración utilizada Estilos de Resaltado de Código del Programmers Notepad

-----------------> Seleccionar el esquema (Scheme): C/C++ e insertar posteriormente los siguientes valores:

b) Teclas de Acceso directo 73

Capítulo 1

Motivaciones del Proyecto

El programa Programmers NotePad tiene algunas teclas de acceso directo de gran utilidad, que merece la pena conocer cuando se emplea como sistema de desarrollo y por consiguiente vamos a utilizar exhaustivamente: Teclas Ctrl+F2

F2

Acción Crea una marca de referencia para poder desplazar la pantalla a ese punto rápidamente (estas marcas de referencia no se guardan en ningún archivo, por lo que al salir del programa se desaparecen) Salta a la siguiente marca de referencia creada

Ctrl+Tab Cambia de una pestaña de código de una archivo a otra. F4

(hay que definirlo) Borra los archivos de salida de la compilación anterior

F5

(hay que definirlo) Guarda los archivos del proyecto definidos en el makefile y realiza la compilación de éstos, de acuerdo con los parámetros de makefile.

Tabla 2: Combinaciones de Teclas de Acción Directa en Programmers Notepad

2.3. Utilización del EDS Configurar el archivo makefile Para hacer una compilación del proyecto en el que trabajamos, es necesario crear y configurar adecuadamente un archivo llamado makefile, que se encuentra en el mismo directorio de nuestro proyecto, y que contiene la información general del proyecto, como es el modelo de microcontrolador para el que se va a compilar el proyecto, y los archivos de código *.c que lo conforman, además del main.c. Para facilitar esta tarea, WinAvr dispone de un programa especial de configuración de makefile, que permite su creación en un entorno de ventanas de Windows con cajas deslizantes de opciones, y espacios para rellenar con el listado de archivos del proyecto. No obstante, también se puede coger un archivo makefile de un proyecto y modificarlo, lo cual es bastante simple. A continuación se muestra un extracto del principio del archivo makefile, que es la parte más importante que hay que configurar: # # # # # # # # # # # # # # # # # # # #

-*- makefile -*On command line: make all = Make software. make clean = Clean out built project files. make coff = Convert ELF to AVR COFF (for use with AVR Studio 3.x or VMLAB). make extcoff = Convert ELF to AVR Extended COFF (for use with AVR Studio 4.07 or greater). make program = Download the hex file to the device, using avrdude. customize the avrdude settings below first!

Please

make filename.s = Just compile filename.c into the assembler code only To rebuild project do "make clean" then "make all".

# MCU name MCU = atmega169 # Output format. (can be srec, ihex, binary) FORMAT = ihex

74

Capítulo 1

Motivaciones del Proyecto

# Target file name (without extension). TARGET = main # List C source files here. (C dependencies are automatically generated.) SRC = $(TARGET).c SRC += timer0.c \ timer1_sound.c \ timer2_RTC.c \ powersave.c\ system_clock.c\ LCD_functions.c \ LCD_driver.c \ menu_date_time.c\ menu_comm.c \ menu_ADC_sensors.c\ usart.c \ eeprom.c \ dataflash.c \ button.c \ BCD.c \ conversions16b_8b.c\ ADC.c \ ram_atmega.c\ windspeed.c # Compiler flag to set the C Standard level. # c89 - "ANSI" C # gnu89 - c89 plus GCC extensions # c99 - ISO C99 standard (not yet fully implemented) # gnu99 - c99 plus GCC extensions CSTANDARD = -std=gnu99 [...]

Programar Código C usando Programmers Notepad a) Aspecto del Editor El editor dispone de una pestaña lateral en la que podemos agregar los archivos de que está compuesto el proyecto, tal y como podemos ver en la figura 1. Esta lista no tiene efectos a la hora de compilar , siendo únicamente válida la lisa de archivos que se encuentra en el archivo makefile, pero sí hace más fácil la edición de múltiples archivos, o la búsqueda de términos léxicos el todo el proyecto.

Figura 1: Aspecto del Entorno de Programación con Programmers Notepad

b) Resaltado de código 75

Capítulo 1

Motivaciones del Proyecto

Con el fin de hacer más cómoda la programación, Programmers Notepad posee un sistema de resaltado de código que es configurable por el usuario. En la página 5 se muestra la tabla 1, con los valores con los que hay que configurar el programa para que el código tenga el aspecto deseado. Así los comentarios tendrán diferente color según su contenido. Para ver los usos que se le da a cada color se recomienda ver el capítulo 6, “Listado de Código del Proyecto”.

c) Consejos para facilitar la programación Se pueden crear dentro de Programers Notepad unas teclas rápidas muy útiles, como son F4=make clean y F5=make all. También a la hora de probar partes del código, en lugar de borrarlo o comentar cada lína, se puede hacer lo siguiente: Crear una línea que empiece por //* y después del código que funciona (COD1) pero que queremos sustituir poner otra línea con /*/ Escribir el nuevo código(COD2) a partir de la línea siguiente y tras él crear una nueva línea con la cadena //*/. De esta forma, tal y como está escrito, COD1 será compilado, y COD2 está comentado. Y cuando queramos lo contrario, sólo tendremos que quitar el la primera barra inclinada de la primera línea para que COD2 se compile y COD1 se comente, como se puede ver en a figura 2.

Figura 2: Ejemplo de comentarios de código que sirve para activar partes de código que se quieren probar sin borrarlas

76

Capítulo 1

Motivaciones del Proyecto

2.4. Particularidades del código C para microcontroladores A continuación explicamos para qué sirven tres tipos de prefijos que se ponen en las definiciones de ciertas variables y que tienen repercusiones importantes en el resultado final e la implementación del código en ensamblador: const, volatile y static.

const La definición “const” sirve para definir una cadena de caracteres utilizando sólo memoria ROM del microcontrolador, en el caso del AtMega169, no memoria Rom, sin la memoria flash destinada al código de programa, que a todos los efectos cuando el programa está en funcionamiento es como si fuese memoria ROM. Esta definición tiene utilidad cuando se necesitan muchas cadenas de caracteres o tablas que nunca van a ser modificadas. En ese caso no hay necesidad de malgastar memoria RAM almacenando cadenas constantes. La forma más obvia de hacer esta declaración (aunque esta forma es incorrecta) sería: #include PGM_P array[2] PROGMEM = { "Foo", "Bar" }; int main (void) { char buf[32]; strcpy_P (buf, array[1]); return 0; }

Pero el resultado de este código no es el que se buscaba. De esta forma (incorrecta) obtendríamos una tabla de cadenas de caracteres almacenada en ROM, y una cadena individual almacenada en RAM (en la sección .data de la memoria). Para obtener el resultado realmente buscado, se necesita un código así: #include const char foo[] PROGMEM = "Foo"; const char bar[] PROGMEM = "Bar"; PGM_P array[2] PROGMEM = { foo, bar }; int main (void) { char buf[32]; strcpy_P (buf, array[1]); return 0; }

donde PGM_P es una definición macro (macro definition) usada en lugar del siguiente código: PGM_P

== const prog_char *

Esta macro se usa para declarar una variable que es un puntero a cadena en el espacio de memoria destinada a memoria de programa: #define PGM_P const prog_char *

77

Capítulo 1

Motivaciones del Proyecto

volatile La definición de “volatile” se utiliza como prefijo para que el programa reconozca que esa variable será actualizada mediante una rutina de interrupción. Así, cuando se utiliza un optimizador, en un bucle como el siguiente: uint8_t flag; ... while (flag == 0) { ... }

el compilador tradicionalmente optimizaría el código de manera que ignoraría la condición dada por la bandera como siempre cierta, ya que daría igual, ya que analizando del código se observa que nada dentro del bucle puede cambiar el valor de la bandera. Para decirle al compilador qe es una variable que puede ser modificada fuera del ámbito del análisis de la ruta de código (por ejemplo mediante una rutina de interrupción), la variable debe ser declarada tal que así: volatile uint8_t flag;

static Las variables definidas como locales a una función desaparecen al final de la ejecución de dicha función. E manera que cuando se llama a esa función de nuevo, se crea un nuevo espacio de almacenamiento para esa variable y los valores son reinicializados. Así que si se pretende que el valor de una variable local se extienda y no se pierda de una llamada a otra de esa función a lo largo de un programa, se puede definir esa variable local como “static”. La inicialización de las variables static se hace sólo en la primera llamada a la función que las contiene, y ene l resto de llamadas no se hace, y conserva el valor de la última llamada. La diferencia respecto de las variables globales es que las static sólo pueden ser accedidas dentro del ámbito de la función que las llama, y por tanto otras funciones pueden tener el mismo nombre de variable, sin que se interfieran unas con otras. Además esta particularidad ayuda para la búsqueda de errores, ya que la variable no puede ser modificada fuera de esa función, y por lo tanto allí es donde debe buscarse dicho error. static char letra;

2.5. Configuración y Utilización de periféricos En entornos con IDE se dispone de generadores automáticos de código, lamentablemente en gcc no se dispone de tal facilidad, aunque sí pueden encontrarse librerías de inicialización y manejo e determinados periféricos, pero siempre se ha de mirar da hoja de catálogo del microcontrolador para configurarlo adecuadamente. No obstante en el presente proyecto se ha tenido especial cuidado en intentar hacer el proyecto lo suficientemente generalista como para que su código pueda ser reutilizado en otros proyectos con la placa AvrButterfly, y otras funcionalidades, razón por la cual se invirtió mucho tiempo es estructurar lo todo modularmente y por funcionalidades, tal y como se verá en el siguiente apartado.

78

Capítulo 1

Motivaciones del Proyecto

2.6. Proceso para la programación del microcontrolador Para programar el microcontrolador con el código de nuestro programa se debe compilar dicho código haciendo: •

make clean = Realiza una Limpieza de archivos de una construcción del proyecto anterior.



make all = Realiza una compilación del código del proyecto utilizando make.



En este punto, en el directorio del proyecto se han generados dos archivos que son los que habrían de transferirse al microcontrolador, y que son main.hex y main.eep, archivos de memoria de programa y de memoria EEprom respectivamente.



Para transferir dichos archivos hemos de ser muy meticulosos en el procedimiento, que que aunque es bastante simple, como se han de sincronizar el Pc con el AvrButterfly, hay que pulsar los botones en su momento justo. Por ello debemos poner especial en hacer lo siguiente: •

Alimentar con 3.3v la placa AvrButterfly



Pulsar el botón de Reset (si la placa ya estaba alimentada, si la acabamos de alimentar no es necesario)



Al mismo tiempo pulsar el botón Enter del Joystick (presionarlo hacia adentro) y Hacer doble click sobre el icono de mprog.exe (ejecutarlo).



Si esto se hizo correctamente, y el cable que une PC y AvrButterfly está bien construido, entonces en la pantalla del PC deberá aparecer la ventana del programa mprog.exe donde hay un espacio para elegir el archivo main.hex que se desea transferir.



Una vez elegido el archivo a transferir, sólo hay que pulsar el botón aceptar, para iniciar el borrado, la programación y la verificación de la correcta programación del sistema.



Concluida dicho proceso, el programa nos dirá si culminó satisfactoriamente. En cualquier caso hay que cerrar la ventana del programa para poder continuar, y hay que reinicializar el microcontrolador forzando un Reset.



Si todo se hizo correctamente, el sistema está programado.

79

Capítulo 1

Motivaciones del Proyecto

3. Módulos del programa del registrador 3.1. Enumeración de los Módulos del Programa El programa del registrador de datos consta de los siguientes módulos funcionales:



El Módulo Principal (es un programa que se ejecuta constantemente y que cada vez que acaba vuelve a empezar, y desde él se activa el funcionamiento de los restantes módulos de programa (subprogramas) que a continuación listaremos).



El Módulo de Manejo y especificación de las funcionalidades de los pines del microcontrolador y de la placa de desarrollo.



El Módulos de Menús de Carga de funciones e Interacción con el usuario



El Módulos de Gestión de Temporizadores, Reloj en Tiempo Real y modos de ahorro de energía

• •

El Módulos de Adquisición de Datos El Módulo de visualización de datos en el Display LCD de 6 dígitos del Butterfly



El Módulo USART



El Módulo de digitalización de señales analógicas



El Módulo de manejo del Joystick



El Módulos de Almacenamiento de Datos



El Módulo de manejo de la DataFlash



El Módulo de manejo de la EEprom



El Módulos Auxiliares de conversión de formato de datos



El Módulos de procesado estadístico de los datos del encoder (sensor de viento).

3.2. Configuración de los Pines de E/S de propósito general A la hora de codificar una nueva aplicación para el AvrButterfly es importante conocer qué pines están libres y pueden ser utilizados de propósito general. Esta característica, que parece una tontería, tienen especial importancia en la placa AvrButterfly porque la mayoría de sus pines se encuentran ocupados por la pantalla LCD de 22 pines, utilizando la funcionalidad del periférico interno del AtMega llamado LCDdriver . Por ello, el uso de esta pantalla utilizando dicho driver limita muchísimo las aplicaciones posibles con el AtMega. Y puede suceder que se desee utilizar un

80

Capítulo 1

Motivaciones del Proyecto

periférico interno del AtMega como el Comparador Analógico y no se puede porque los pines de entrada de dicho periférico estén siendo utilizados con otra funcionalidad.

Figura 3: Listado de pines y esquema de su distribución con su configuración

Por estos motivos se creyó de importancia el poder plasmar en el mismo código del programa, aunque sea como comentario, la situación del patillaje de la placa AvrButterfly. En la figura 3 se puede ver una captura de pantalla del aspecto del comentario que s encuentra en el archivo pin_management.h

3.3. Módulos de la Pantalla LCD Para el manejo de la pantalla LCD se utilizan dos archivos: El de más alto nivel es LCD_functions, que son unas funciones genéricas para cualquier pantalla LCD en modo alfanumérico. La funciones de más bajo nivel se encuentran el archivo LCD_Driver, que contiene funciones específicas para la pantalla LCD que posee de fábrica la placa AvrButterfly (en caso de poner otra pantalla habría que crear otras funciones).

Figura 4: Segmentos de la pantalla LCD que es posible activar

Con las funciones que tenían implementados los controladores de la pantalla LCD únicamente se podían activar los seis dígitos alfanuméricos que aparecen en la figura anterior, dado que los dígitos que están en blanco no están conectados físicamente al periférico DriverLCD. Sin embargo, pese a que la hilera de números y sus respectivos subrayados sí están conectados físicamente con dicho periférico, su activación no viene

81

Capítulo 1

Motivaciones del Proyecto

implementada en el programa controlador, por lo que se procedió a la elaboración de funciones que habilitasen dicha funcionalidad:

Figura 5: Intefaz entre Bits del Registro LCD y segmentos del LCD

Ello se consiguió manipulando los registros de los segmentos LCD y dándole valores a los bits que no se usaban siguiendo un método de prueba y error. Para ello se tuvo que hacer un estudio intensivo y algo de ingeniería inversa para conocer la funcionalidad de cada bit de dicho registro, que a continuación pasamos a describir:

Figura 6: Registro de los segmentos LCD (en el periférico driver LCD)

Dicho registro lo interpretaremos como una tabla cuyas filas las denominaremos por LCDDRxx, y cuyas columnas las llamaremos por un número de bit (de 0 a 7). Ahora se establecerá una correspondencia entre los bits de este registro y los segmentos de cada dígito del LCD (ver Figura 6): así pues las columnas 0, 1, 2 y 3 se corresponden con segmentos de los dígitos 0, 2 y 4, y las columnas 4, 5, 6 y 7 se corresponden con segmentos de los dígitos 1, 3 y 5.

82

Capítulo 1

Motivaciones del Proyecto

Por poner un ejemplo de correspondencia, podemos decir que los segmentos que se corresponden con el dígito 0 son: Fila

bit 3

bit 2

bit 1

bit 0

fila LCDDR1

SEG311(K)

SEG310(X)

SEG309(Y)

SEG308(A)

fila LCDDR6

SEG211(L)

SEG210(F)

SEG209(H)

SEG208(B)

fila LCDDR11

SEG111(L)

SEG110(E)

SEG109(G)

SEG108(C)

fila LCDDR16

SEG011(M)

SEG010(P)

SEG009(N)

SEG008(D)

Tabla 3: Ejemplo de correspondencia entre los segmentos del LCD del dígito 0 y los bits del registro de segmentos del LCD que le corresponden

Segmentos especiales del LCD Utilizando la información de la figura 6, y contrastándola con la de la Tabla 3, y utilizando un procedimiento que inicialmente fue a prueba y error, ya que en ninguna hoja de catálogo venía especificado que los segmentos X e Y se pudiesen utilizar, se definieron unos nuevos segmentos especiales gráficos del LCD como son los números y los subrayados del Display que incorpora el AvrButterfly.

Figura 7: Segmentos especiales del LCD

La información relativa a las máscaras y las funciones para la utilización de tales segmentos se puede encontrar en la sección de”Display LCD” del capítulo 6 “Listado de Código”. De esta forma de pueden activar o desactivar individualmente los siguientes segmentos: •

los números 1,2 4, 5, 9 y 10,



los subrayados 1,2,3,4,9,10, y



el número 3 conjuntamente con el subrayado 5.

Nuevos Caracteres LCD Además, utilizando las posibilidades que permitían los segmentos alfanuméricos del LCD, se diseñaron nuevo caracteres para mostrar mejor la información de pantalla. Así se crearon “m” , “/” y “s” para la información en m/s. Y unos caracteres que simulan un rotor en movimiento para dar sensación de captura de datos. Los resultados de estas definiciones se pueden ver en la tabla 4 de la página 16, en la que a partir de los segmentos de cada dígito del LCD, y haciendo una combinación de éstos combinándola en una máscara, se logran diseñar estos nuevos caracteres especiales.

83

Capítulo 1

Simbolo

Motivaciones del Proyecto

Máscara

{MPND}

{LEGC}

{JFHB}

{KXYA}

*

0xEAA8

1110

1010

1010

1000

/

0x4008

0100

0000

0000

1000

\

0x8020

1000

0000

0010

0000

m

0x2F00

0010

1111

0000

0000

s

0x9800

1001

1000

0000

0000

_

0x1000

0001

0000

0000

0000

JPM

0xC080

1100

0000

1000

0000

GNK

0x2208

0010

0010

0000

1000

HPL

0x4820

0100

1000

0010

0000

GJM

0x8280

1000

0010

1000

0000

HKN

0x2028

0010

0000

0010

1000

JLP

0x4880

0100

1000

1000

0000

KGM

0x8208

1000

0010

0000

1000

NLH

0x2820

0010

1000

0010

000

Tabla 4: Nuevos caracteres alfanuméricos creados especialmente para este proyecto

84

Capítulo 1

Motivaciones del Proyecto

Por último en lo relativo al LCD se describen las funciones que se tienen en sendos archivos de programación del LCD: Funciones deLCDDriver.h – Manejador del Display específico que incorpora el AvrButterfly LCD_Init(); Inicializa la pantalla LCD y prepara para su uso LCD_WriteDigit(2); Escribe un carácter en uno de los seis dígitos del LCD //SIGNAL(SIG_LCD)--> LCD Interrupt Routine LCD_Num1_On(); LCD_Num1_Off(); LCD_Led1_On(); LCD_Led1_Off()

// ENCIENDE el Numero_1 del LCD // ENCIENDE el Led_1 del LCD

Funciones de LCDFunctions.h – Funciones genéricas para cualquier Display con caracteres alfanuméricos. void LCD_put_u8b (unsigned char data); void LCD_put_u16b (unsigned int data); void LCD_puts_f(const char *pFlashStr, char scrollmode); void LCD_puts(char *pStr, char scrollmode); void LCD_putc(uint8_t digit, char character); Cuando se carga en ellos nuevos datos, sólo cambiarán los bytes especificados para que se sobreescriban, no viéndose afectados los restantes bytes por dicha acción. void void void void char

LCD_UpdateRequired(char update, char scrollmode); LCD_Clear(void); LCD_Colon(char show); LCD_FlashReset(void); SetContrast(char input);

Se evita hacer una descripción pormenorizada de las unciones debido a que en el listado de código del programa, en el capítulo 6, se comenta exhaustivamente el código diciendo en el encabezado de cada función cual es su funcionalidad.

85

Capítulo 1

Motivaciones del Proyecto

3.4. Salvado de datos en la Dataflash Descripción del Funcional de la Dataflash La placa de desarrollo AvrButterfly incorpora como ya hemos mencionado un dispositivo de memoria externa no-volátil con capacidad de 512KBytes y con comunicación a través del puerto SPI con el AtMega. A la hora de implementar el software especial Figura 8: Dataflash AT45DB041B montada en la Placa AvrButterfly de manejo de este dispositivo externo es necesario saber algunas particularidades de su construcción herdware que a continuación se exponen: El AT45DB041B incorpora dos buffers bidireccionales para expedir el flujo de datos hacia y desde el dispositivo. 0 0

Página 2047

Buffer #2

Buffer #1

dato8b Buffer Write Byte

Buffer_to_Page

0

Página 0

dato8b

SPI

Page_to_Buffer Buffer Read Byte 263 263 263

8bits 8bits

2 buffers sRAM

2048 páginas Flash

263 263

263

8bits

Figura 9: Funciones de almacenamiento y estructura de la memoria DataFlash

Cada buffer tiene una longitud de 264Bytes (la misma longitud que las páginas en que está dividida la memoria). Estos buffers son memoria static RAM (volátil) y confieren una especie de memoria caché durante una operación de programación o borrado. Por lo tanto a la hora de almacenar o recuperar datos de la memoria Dataflash no-volátil, dicha información pasará por uno de estos buffers antes de transferirse al AtMega por el interfaz SPI. Por ello se crearon tres capas de manejo cuyas funcionalidades son: •

la capa 1 que maneja el interfaz SPI,



la capa 2 que gestiona la transferencia de datos entre el AtMega y uno de los buffers, y la transferencia entre uno de los buffers y el banco e memoria Dataflash.



La capa 3 que maneja la Dataflash como si se tratase de una pila de almacenamiento de información en paquetes de 8 bits con índices totalmente transparente al usuario, que se limita únicamente a enviar o recibir datos, y la gestión de páginas es completamente automática.

86

Capítulo 1

Motivaciones del Proyecto

En la Tabla 5 se muestra las definiciones de las funciones de manejo de la Dataflash separadas por capas, en las que se puede apreciar los parámetros necesarios para la utilización de cada una. ///Funcions Layer3:______________________________________________________ unsigned char DF_Write8 (unsigned char BufferNo ,unsigned int *TopBuf ,unsigned int *PageNum ,unsigned char Data ); unsigned char DF_Read8 (unsigned char BufferNo ,unsigned int *PageNum ,unsigned int *TopBuf ,unsigned int PageNumLP, unsigned int TopBufLP ,unsigned char *Data ); ///Funcions Layer2:______________________________________________________ void Buffer_To_Page (unsigned char BufferNo ,unsigned int PageAdr ); void Page_To_Buffer (unsigned int PageAdr ,unsigned char BufferNo ); void Buffer_Write_Byte (unsigned char BufferNo ,unsigned int IntPageAdr ,unsigned char Data ); unsigned char Buffer_Read_Byte (unsigned char BufferNo ,unsigned int IntPageAdr ); ///Funcions Layer1:______________________________________________________ void DF_SPI_init (void); unsigned char DF_SPI_RW (unsigned char output ); unsigned char Read_DF_status (void);

Tabla 5: Definiciones de las funciones de manejo de la Dataflash separadas por capas

Funciones de Escritura y Lectura Como ya hemos mencionado, las funciones de la capa 3 hacen una gestión integral del almacenamiento y restaurado secuencial de datos en el dispositivo de almacenamiento no volátil. Estas funciones DF_Write8() y DF_Read8() almacenan o leen un Byte de información y preparan el sistema para que próxima vez que sean llamadas se se coloque la información en el Byte que secuencialmente se encuentra después, aunque se cambie del Byte último de una página de memoria al primer Byte de la siguiente página. Pero los datos de memoria que se guardarán en este proyecto (y en general) serán de 16bits (2Bytes), y no de 8bits(1Byte) , por lo que se crearon unas funciones auxiliares que se utilizan en varias funciones de periféricos del código dedicadas a la conversión de datos de 8bits a datos de 16bits, y viceversa. Estas funciones de describen en el siguiente apartado (Conversión de Datos de 8 bits a 16 bits) de la pág. 22. Con lo cual para almacenar en memoria un dato de 16bits, sólo habría que llamar previamente a una de estas funciones y

Encapsulado de los datos para su almacenamiento A la hora de escribir los datos en la memoria Dataflash d almacenamiento masivo no-volátil, se hace necesario un sistema que los ordene. Afortunadamente tanto el proceso de lectura como el de escritura son secuenciales (siempre se escribirán o leerán los datos de menor a mayor dirección de memoria), lo que facilita considerablemente la labor. Por otro lado, aunque gracias a esta característica el problema se reduce, hay que considerar los distintos datos que se escribirán en dicha memoria, y que una vez escritos, al leerse debe saberse qué significan los bits que se tienen, es decir, se debe tener capacidad para interpretar los datos tras ser recuperados. Por ello se desarrolló la idea de almacenar los datos en paquetes o contenedores de información, cada uno de ellos con un código gracias al cual se conoce implícitamente su contenido y su longitud. Así pues, para esta aplicación se diseñaron 4 tipos de contenedores: Los que fijan una referencia temporal “fecha” (se escribe uno al día y tienen una longitud de 2Bytes) Fecha [2B]

0

1

2

3

4

0

1

-

-

-

5

6

7

8

9

10

11

12

13

14

Mes y dia (mes12,dia30=1230) [11b]

87

15

Capítulo 1

Motivaciones del Proyecto

Los que fijan una referencia temporal horaria y registran la temperatura ambiente “Hora_Temp”(se escriben 24 al día y tienen una longitud de 2Bytes) Hora Temp[2B]

0

1

2

1

0

crc

3

4

5

6

7

8

Hora(0h,23h) [5b]

9

10

11

12

13

14

15

Temperatura(-25º,+60º) [8b]

Los que fijan una referencia temporal implícita y registran los datos estadísticos eólicos correspondientes a un período de 10 minutos (la media, varianza y valor máximo d la velocidad del viento en ese período), recibe el nombre de “Datos” (se escriben 144 al día y tienen una longitud de 4Bytes) 0

1

Datos [4B]

1

2

3

4

5

6

7

crc

1

8

9

10

11

12

13

Media [9b]

... varianza [9b]

14

15

Varian..

Valor_pico [9b]

Por último hay un paquete de datos que se ha dejado reservado para almacenar datos varios, y para futuras mejoras del sistema. Especial [2B]

0

1

0

0

2

3

4

5

6

7

8

9

10 11 12 13 14 15

op op

Para el correcto manejo de todos estos paquetes, se crearon unas funciones de escritura y lectura que gestionan la memoria Dataflash en forma de paquetes, y sin las cuales, el contenido de dicha memoria se convierte en una ristra de Bytes sin sentido. Dichas funciones se encuentran en el archivo df_encapsulation.c //Funciones de ayuda a la escritura en el Paquetes DataFlash___________________ unsigned char DF_Write_Logs (uint16_t Data16_Mean, uint16_t Data16_Vari, uint16_t Data16_Peak); unsigned char DF_Write_Hour (void); unsigned char DF_Write_Date (void); unsigned char DF_Write_Wind (uint16_t Data16_Wind); //Paquete Especial unsigned char DF_Read_Logs (uint16_t *Data16_Mean, uint16_t *Data16_Vari, uint16_t *Data16_Peak, uint8_t *vhora, uint8_t *vtemperat, uint8_t *DataType);

Las cuatro primeras funciones son de escritura de paquetes en la Dataflash, y las tres es una función de lectura que extrae los datos del los paquetes interpretándolos, devolviendo como salida el tipo de datos leído, y actualizando los parámetros de salida con los datos extraídos, de manera que según fuese el tipo de contenedor de datos se actualizan unos parámetros u otros, y después con una condición “if” se procesan únicamente lo datos que se extrajeron.

Capacidad de Almacenamiento de Datos Eólicos Para determinar dicha capacidad, se han de hacer unos cálculos sencillos que pasamos a enumerar: Cada 10 minutos se almacena en memoria Dataflash un contenedor de datos[4B], por lo que cada día se registran:

4

Bytes Contenedores horas Bytes ⋅6 ⋅24 =576 Contenedor Hora dia dia

Cada hora se guarda un contenedor de hora y de temperatura [2B]

88

Capítulo 1

Motivaciones del Proyecto

2

Bytes Contenedores horas Bytes ⋅1 ⋅24 =24 Contenedor Hora dia dia

Cada día se almacena un contenedor registrando la fecha[2B]

2

Bytes Contenedor Bytes ⋅1 =2 Contenedor dia dia

Luego cada día se almacenan:



contenedores Bytes =576482=628 día día

Con lo que como la memoria Dataflash tiene 4Mbits de capacidad

4 Mbits = 512 KBytes bits 8 Byte puede almacenar

512 KBytes = 815 dias de capacidad =más de 2 años de capacidad Bytes 628 dia Además el intervalo de registro de los valores estadísticos de la media y la varianza puede ser con figurable: Intervalo de Registro

Bytes/dia

Cada 10 minutos 576+48+2

628 Bytes/dia

Capacidad 815 dias = 2 años y 2 meses

Cada 5 minutos

(2*576)+48+2 1205 Bytes/dia

424 días = 1 años y 2 meses

Cada 2 minutos

(4*576)+48+2 2354 Bytes/dia

217 días =

7 meses

Tabla 6: Capacidades de Almacenamiento de Datos Eólicos según el período estadístico elegido.

3.5. La memoria EEprom Se trata de otro tipo de memoria no volátil, pero a diferencia de la DataFlash, esta memoria es un dispositivo interno en el AtMega. Para su utilización se ha estructurado en dos capas: La capa 1 posee las funciones más básicas de manejo de la transmisión de la información a la EEprom, y son de bajo nivel. La capa 2 utiliza las funciones de la capa 1 para realizar tareas más complejas, como la gestión da datos del número de página inicial, final y último utilizado de la DataFlash, • • •

DFSave_CtrlInfo () DFSave_FP_Info

()

DFLoad_CtrlInfo ()

y la gestión de varios arrays de información de longitud configurable destinados a guardar textos editables con el joystick del sistema como son el nombre del emplazamiento donde se situará al registrador de datos, un número de teléfono de asistencia técnica, o el nombre de la empresa instaladora. • •

EE_Save_TableUint() EE_Load_TableUint()

89

Capítulo 1

Motivaciones del Proyecto

En la Tabla 7 se adjunta un Listado de funciones de manejo de la EEprom ubicadas en el archivo eeprom.h /// Function Prototypes:_(CAPA 2)__________________________________________ unsigned char EEPROM_Read_Str(unsigned int EE_Start_adr, char *pBufferRam, char RAM_Max_num_bytes ); void EEPROM_Write_Str (char *pBufferRam, unsigned int EE_Start_adr, char EE_Max_num_bytes); /// Funciones de Manejo de la informacion de control de la DataFlash mediante la EEPROM__(CAPA 2)__________________________________________________________ void DFSave_CtrlInfo (unsigned int TopBufLP, unsigned int LastPage ); void DFSave_FP_Info (unsigned int void DFLoad_CtrlInfo (unsigned int unsigned int

FirstPage); *TopBufLP, unsigned int *FirstPage);

*LastPage,

void EE_Save_TableUint(unsigned int *TablaUint, uint8_t iMax_Tabla); void EE_Load_TableUint(unsigned int *TablaUint, uint8_t iMax_Tabla); /// Function Prototypes Special for atMega169:___(CAPA 1)__________________ uint8_t EEPROM_Read8b (const uint16_t *addr); void EEPROM_Write8b (uint16_t *addr, uint8_t val); Tabla 7: Listado de funciones de manejo de la EEprom ubicadas en el archivo eeprom.h

3.6. Conversión de Datos de 8 bits a 16 bits En distintas funciones del programa se hace necesaria la transferencia, visualización o almacenamiento de datos de 16bits, mientras que la arquitectura del Avr es de 8bits, y por tanto las funciones estándar están adecuadas a ese ancho de datos. Por ello se hicieron necesarias estas dos funciones : Conv16b_to_2x8b() convierte un dato de 16bits en dos datos de 8bits

haciendo una copia del de 16bits, desplazando los bits de una copia 8 posiciones hacia el bit menos significativo, y haciendo un “cast” de ambas variables a 8bits. El diagrama conceptual del proceso se muestra en la Figura 10.

Data16

up

Data16

down

Aux16

up

down

igual

up

down

>>8

up

up

cast down cast

up

Figura 10: Conversión de un Dato de 16bits (2Bytes) a dos datos de 8bits (1Byte)

Conv2x8b_to_16b() convierte dos datos de 8bits haciendo en un dato de 16bits tomando ambos datos, haciéndole un “cast” a ambos a “int”, desplazando el bit superior 8 posiciones hacia el bit más significativo, sumando de forma lógica ambas variables de 16bits. El diagrama conceptual del proceso se muestra en la Figura 11.

90

Capítulo 1

down8b cast 0000

Motivaciones del Proyecto

Mask 0x00FF

down

0000

down

OR

up8b cast 0000

up

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.