Sistemas Digitales FreeRTOS en ATMEGA32 Portaci´on, on, Drivers y Simulaci´on on de Tareas
Nicol´ as as Ilich Samus Profe Profeso sor: r: Jos´ Jos´e Ju´ Juarez ´arez
Universidad Nacional de Quilmes 10 de Febrero de 2012
´ Indice general
Licenciamiento
3
I
4
Port ortaci aci´ on de FreeRTOS a ATMEGA32
1. Portaci´ Portaci´ on de FreeRTOS 1.1. port.h . . . . . . . . . . 1.2. portmacro.h . . . . . . 1.3.. Creaci 1.3 Creaci´´on del Port . . .
a ATMEGA32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2. Portaci´ Portaci´ on de la librer´ıa lib 2.1. Registros . . . . . . . . . . 2.2. Bits . . . . . . . . . . . . . 2.3. Interrupciones . . . . . . .
II
serial.c de FreeRTOS a ATMEGA32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Crea Creaci ci´ ´ on de un Proyecto en AVR Studio 5 con FreeRTOS
3. Creaci Creaci´ o ´n de un Proyecto en AVR Studio 5 con 3.1. Software necesario . . . . . . . . . . . . . . . . . . 3.2. Nuevo proyecto . . . . . . . . . . . . . . . . . . . . 3.3. Incluir FreeRTOS . . . . . . . . . . . . . . . . . . 3.4. Configuraci Configuraci´´on del proyecto . . . . . . . . . . . . .
III
FreeRTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
6 6 6 6
7 . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
Driv Driver erss y Sim Simulac ulaci´ i´ on de Tareas
8 8 8 9 10
12
4. Introducci´ Introducci´ on 5. Sistemas con FreeRTOS 5.1. LCD . . . . . . . . . . . . . . . . 5.1.1. 5.1.1. Tareas de demostr demostraci´ aci´ on . 5.1. 5.1.2. 2. C´ odigo Fuente . . . . . . 5.2. Teclado Matricial Hexadecimal 5.2.1. 5.2.1. Tareas de demostr demostraci´ aci´ on . 5.2. 5.2.2. 2. C´ odigo Fuente . . . . . . 5.3. Conver Conversor sor Anal´ ogico Digital . . 5.3.1. 5.3.1. Tareas de demostr demostraci´ aci´ on . 5.3. 5.3.2. 2. C´ odigo Fuente . . . . . . 5.4. Puerto Serie . . . . . . . . . . . . 5.4.1. 5.4.1. Tareas de demostr demostraci´ aci´ on . 5.4. 5.4.2. 2. C´ odigo Fuente . . . . . . 5.5. Leds y Botones . . . . . . . . . .
5 5 5 5
13 . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
.. . . . . . . . . . . . . . . . . . . . . . . . .
Ap´ endice
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
.. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
14 14 14 15 18 18 18 21 21 22 24 26 26 28
30
A. Librer´ıa para Display LCD 30 A.1. l cd cd lib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 A.2. l cd cd lib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1
´ Indice general
Licenciamiento
3
I
4
Port ortaci aci´ on de FreeRTOS a ATMEGA32
1. Portaci´ Portaci´ on de FreeRTOS 1.1. port.h . . . . . . . . . . 1.2. portmacro.h . . . . . . 1.3.. Creaci 1.3 Creaci´´on del Port . . .
a ATMEGA32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
2. Portaci´ Portaci´ on de la librer´ıa lib 2.1. Registros . . . . . . . . . . 2.2. Bits . . . . . . . . . . . . . 2.3. Interrupciones . . . . . . .
II
serial.c de FreeRTOS a ATMEGA32 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Crea Creaci ci´ ´ on de un Proyecto en AVR Studio 5 con FreeRTOS
3. Creaci Creaci´ o ´n de un Proyecto en AVR Studio 5 con 3.1. Software necesario . . . . . . . . . . . . . . . . . . 3.2. Nuevo proyecto . . . . . . . . . . . . . . . . . . . . 3.3. Incluir FreeRTOS . . . . . . . . . . . . . . . . . . 3.4. Configuraci Configuraci´´on del proyecto . . . . . . . . . . . . .
III
FreeRTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
6 6 6 6
7 . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
Driv Driver erss y Sim Simulac ulaci´ i´ on de Tareas
8 8 8 9 10
12
4. Introducci´ Introducci´ on 5. Sistemas con FreeRTOS 5.1. LCD . . . . . . . . . . . . . . . . 5.1.1. 5.1.1. Tareas de demostr demostraci´ aci´ on . 5.1. 5.1.2. 2. C´ odigo Fuente . . . . . . 5.2. Teclado Matricial Hexadecimal 5.2.1. 5.2.1. Tareas de demostr demostraci´ aci´ on . 5.2. 5.2.2. 2. C´ odigo Fuente . . . . . . 5.3. Conver Conversor sor Anal´ ogico Digital . . 5.3.1. 5.3.1. Tareas de demostr demostraci´ aci´ on . 5.3. 5.3.2. 2. C´ odigo Fuente . . . . . . 5.4. Puerto Serie . . . . . . . . . . . . 5.4.1. 5.4.1. Tareas de demostr demostraci´ aci´ on . 5.4. 5.4.2. 2. C´ odigo Fuente . . . . . . 5.5. Leds y Botones . . . . . . . . . .
5 5 5 5
13 . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
.. . . . . . . . . . . . . . . . . . . . . . . . .
Ap´ endice
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . .
.. . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
. . . . . . . . . . . . .
14 14 14 15 18 18 18 21 21 22 24 26 26 28
30
A. Librer´ıa para Display LCD 30 A.1. l cd cd lib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 A.2. l cd cd lib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
1
B. Librer´ıa para Teclado Matricial Hexadecimal 39 B.1. keypad lilib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 B.2. keypad lilib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 C. Librer´ıa ıa para Conversor Anal´ ogico Digital 41 C.1. adc lib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 C.2. adc lib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 D. Librer´ıa para Puerto Serie 43 D.1. l ib ib se serial.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 D.2. l ib ib se serial.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 E. Librer´ıa para LEDs 55 E.1. led lib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 E.2. led lib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 F. Librer´ıa para Botones 56 F.1. boton lilib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 F.2. boton lilib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Bibliograf´ıa
57
2
Licencias
FreeRTOS en ATMEGA32 por Nicol´as as Ilich Samus se encuentra bajo una Licencia Creative Commons Atribuci´ on-NoComercial-CompartirDerivadasIgual 3.0 Unported a excepci´on on-NoComercial-CompartirDerivadasIgual on de los l os Ap´ A p´endiend ices A y D los cuales est´an an licenciados de forma independiente al presente trabajo.
3
Parte I
Portaci´ on on de FreeRTOS a ATMEGA32
4
Cap´ıtulo 1 Portaci´ on de FreeRTOS a ATMEGA32
La portaci´ on a ATMEGA32 se realiz´o a partir del port que FreeRTOS dispone para el ATMEGA323.
1.1.
port.h
Se analiz´o el archivo port.h y se obtuvieron las siguientes conclusiones: No fue necesario cambiar ninguno de los par´ametros a continuaci´on ya que ambos microcontroladores comparten las mismas definiciones. / * S ta r t t a sk s w it h i n te r ru p ts e n ab l es . * / #define p or tF LA GS _I NT _E NA BL ED ( ( po rt ST AC K_ TY PE ) 0 x80 ) / * H ar dw ar e c on st an ts f or t im er 1 . * / #define p or tC LE AR _C OU NT ER _O N_ MA TC H ( ( u n s ig n e d c h ar ) 0 x 0 8 ) #define port PRESCALE_64 ( ( u n s i gn e d c h ar ) 0 x 0 3 ) #define p ortCLO CK_PRES CALER ( ( u n s ig n e d l o ng ) 64 ) #define p or t C OM P A RE _ M AT C H _A _ I NT E R RU P T _E N A BL E ( ( u n s i gn e d c h ar ) 0 x 1 0 )
Como los dos microcontroladores poseen los mismos registros (R0-R31) y se encuentran en las mismas posiciones de memoria, tampoco fue necesario redefinir las funciones portSAVE CONTEXT(), portRESTORE CONTEXT() ni *pxPortInitialiseStack().
1.2.
portmacro.h
Se analiz´o el archivo port.h y se obtuvieron las siguientes conclusiones: En este archivo estan las definiciones de los tipos de datos del port, en el se realiza un mapeo entre los tipos de datos estandar de C y aquellos m´as apropiados en el microcontrolador portado. Tambi´ en se encuentran las definiciones de las funciones portENTER CRITICAL(), portEXIT CRITICAL(), portDISABLE INTERRUPTS() y portENABLE INTERRUPTS() entre otras. Todas estas funciones estan escritas totalmente en assembler debido a su interacci´on directa con el microcontrolador. As´ı como con el archivo port.h, no fue necesario cambiar nada ya que todos los microcontroladores AVR de la l´ınea ATMEGA poseen el mismo set de instrucciones y sus arquitecturas son de 8bits por lo que los tipos de datos tambi´en son coincidentes.
1.3.
Creaci´ on del Port
Para dejar expl´ıcito que estamos trabajando con un ATMEGA32 en vez de un ATMEGA323 se gener´ o una nueva carpeta dentro de freeRTOS/Source/portable/GCC llamada ATMEGA32 y se copiaron all´ı los archivos port.h y portmacro.h correspondientes al ATMEGA323.
5
Cap´ıtulo 2 Portaci´ on de la librer´ıa lib serial.c de FreeRTOS a ATMEGA32
Cuando se intent´o utilizar la librer´ıa para comunicaci´on serie provista por FreeRTOS surgi´o la necesidad de portar la misma para ATMEGA32 debido a que los nombres de los registros, los bits y las interrupciones para manejar la USART son distintos en el ATMEGA323. A continuaci´on se detallan los cambios realizados a lo largo del c´odigo.
2.1.
Registros
Se reemplazaron los siguientes registros. UCSR0B por UCSRB. UCSR0A por UCSRA.
2.2.
Bits
Se reemplazaron los siguientes bits. UBRR0L por UBRRL. UBRR0H por UBRRH. UCSR0C por UCSRC. UDR0 por UDR. UDRE0 por UDRE. RXC0 por RXC.
2.3.
Interrupciones
Se agregaron dos condicionales para usar las interrupciones propias del ATMEGA32. USART Receive Complete: # i f d e f i ne d ( _ _ A V R _ A T m e g a 3 2 _ _ ) I SR ( U S AR T _ RX C _v e ct ) #endif
USART Data Ready: # i f d e f i ne d ( _ _ A V R _ A T m e g a 3 2 _ _ ) I S R ( U S A R T _ UD R E _ v ec t ) #endif
6
Parte II
Creaci´ on de un Proyecto en AVR Studio 5 con FreeRTOS
7
Cap´ıtulo 3 Creaci´ on de un Proyecto en AVR Studio 5 con FreeRTOS
En esta secci´on se describen los pasos a seguir para generar un proyecto desde cero en AVR Studio 5 que incluya las librer´ıas de FreeRTOS manteniendo la organizaci´ on de archivos con la que FreeRTOS es distribuido.
3.1.
Software necesario Atmel AVR Studio 5 FreeRTOS Versi´on 7.1.0 (Ultima versi´on disponible a la fecha)
3.2.
Nuevo proyecto
Una vez instalado AVR Studio, lo ejecutamos y nos encontramos con la pantalla de bienvenida.
Figura 3.1: Pantalla de bienvenida. 1. Hacemos click en New Project para crear un nuevo proyecto. Seleccionamos C Executable Project , completamos el campo Name con el valor deseado y finalmente hacemos click en OK.
8
Figura 3.2: Nuevo proyecto. 2. Seleccionamos el dispositivo que sera nuestro target en el proyecto. En este caso seleccionamos el ATMEGA32 y terminamos haciendo click en OK.
Figura 3.3: Selecci´on del dispositivo target.
3.3.
Incluir FreeRTOS
Para incluir los archivos de FreeRTOS en nuestro proyecto debemos hacer lo siguiente: 1. Copiar el archivo FreeRTOSConfig.h ubicado en el directorio donde descomprimimos FreeRTOS y dentro de este en Demo\AVR ATMega323 WinAVR a la raiz de nuestro proyecto, en este caso: C:\Documents and Settings\Administrador\Escritorio\drivers sidi\AVRGCC1\AVRGCC1 2. Crear una carpeta llamada FreeRTOS en la raiz de nuestro proyecto y copiar en ella la carpeta Source , excluyendo la carpeta portable . 3. Crear la carpeta portable en Source . 4. Crear las carpetas GCC y MemMang dentro de portable . 5. Crear la carpeta ATMEGA32 y copiar los archivos port.c y portmacro.h correspondientes al ATMEGA32 [?, Ver el apunte “Portaci´on de FreeRTOS de ATMEGA323 a ATMEGA32”]. 6. En la carpeta MemMang copiar el archivo heap 1.c incluido en FreeRTOS .
9
7. Crear una carpeta llamada Drivers en la ra´ız de nuestro proyecto. Ser´a donde guardemos las librer´ıas que utilicemos y/o creemos para manejar los distintos perif´ericos del microcontrolador o dispositivos externos. 8. Modificar el archivo portable.h ubicado en nuestro proyecto en la carpeta FreeRTOS\Source\include en la linea 74. Donde dice ATMega323 poner ATMEGA32 . 9. Ahora, devuelta en AVR Studio hacemos click en “Show all Files” en el “Solution Explorer”
10. Inclu´ımos las carpetas FreeRTOS y Drivers y el archivo FreeRTOSConfig.h en el proyecto. Cabe aclarar que cada vez que se agreguen archivos por fuera de AVR Studio ser´a necesario seguir este procedimiento.
3.4.
Configuraci´ on del proyecto
Ahora vamos a configurar el proyecto para que luego pueda compilarse correctamente. 1. Hacemos click derecho sobre el proyecto y luego en propiedades.
2. Ingresamos a la solapa Toolchain.
10
3. En la Secci´ on Symbols agregamos dos entradas: F CPU=8000000 : Establece la velocidad del cristal que utilizaremos. En este caso se us´o 8Mhz y no 16Mhz ya que como se simul´o con Proteus Isis mayor velocidad implicaba mayor consumo de CPU y la p´erdida de rendimiento era considerable. GCC MEGA AVR : FreeRTOS necesita este par´ametro para saber que est´a trabajando con un AVR y as´ı aplicar configuraci´on dependiente de la arquitectura.
4. En la Secci´ on Directories agregamos 4 entradas como paths relativos: El directorio ra´ız. include donde se encuentran los headers de FreeRTOS. ATMEGA32 donde se encuentran los archivos propios de puerto. Drivers donde se encuentran las librer´ıas de los perif´ericos y dispositivos.
5. En la Seccion Optimization seleccionamos Optimize for size -Os 6. Por u ´ ltimo, en el archivo FreeRTOSConfig.h que copiamos desde el directorio de la Demo inclu´ıda con FreeRTOS debemos modificar el par´ametro configUSE IDLE HOOK para que sea cero en nuestro primer proyecto a menos, claro, que lo vayamos a usar. Asimismo algunas caracter´ısticas del sistema vienen deshabilitadas por default y en caso de ser necesarias en el proyecto deben habilitarse primero. En lo descrito anteriormente se intent´o conservar la estructura de las carpetas de FreeRTOS dentro del proyecto para no perder la idea general propuesta por los desarrolladores y, en caso de tener que trabajar con una arquitectura distinta o en proyectos ya establecidos, no haya que interpretar la misma nuevamente.
11
Parte III
Drivers y Simulaci´ on de Tareas
12
Cap´ıtulo 4 Introducci´ on
Se desarrollaron cuatro implementaciones distintas de FreeRTOS con tareas de demostraci´on de las caracter´ısticas del sistema (ejecuci´on de tareas en tiempo real, el uso de sem´aforos, colas y colas binarias), del uso de los perif´ ericos del microcontrolador (USART, los puertos de entrada/salida y los conversores anal´ogico/digitales) y del manejo de dispositivos como el display LCD y el teclado matricial de 4x4. Los sistemas fueron implementados para funcionar con un reloj de 8Mhz, se opt´o por esta velocidad ya que a 16Mhz la PC en la que se realiz´o la simulaci´on perd´ıa la caracter´ıstica de tiempo real. Esto fue reportado por el simulador y verificado con una tarea simple de generaci´on de forma de onda. Por otro lado, se pens´o en realizar todas las simulaciones a 1Mhz para obtener un buen rendimiento, pero por ser un numero muy bajo iban a existir importantes limitaciones en cuanto a la frecuencia del tick de FreeRTOS. Con la elecci´on de trabajar a 8Mhz se pudo configurar una frecuencia de tick de 1Khz, la cual fue apropiada para mantener los requerimientos de todos los sistemas propuestos.
13
Cap´ıtulo 5 Sistemas con FreeRTOS
5.1.
LCD
En esta demostraci´on se plantea un sistema compuesto de un generador de onda cuadrada, el cual se inicia y se detiene por medio de un pulsador. Se utiliz´o un display LCD para reportar la cantidad de tareas del sistema y el estado de la tarea encargada de generar la onda cuadrada. Se opt´ o por usar el driver LCD lcd lib.c desarrollado por el sitio Scienceprog.com el cual es distribuido bajo la GNU Public License . Al mismo se le agreg´o el m´etodo LCDInt162String() para visualizar variables de punto fijo de 16bits con un sufijo, esto fue necesario para visualizar los valores adquiridos por el conversor anal´ogico digital y no desperdiciar memoria RAM con el uso de variables del tipo float .
5.1.1.
Tareas de demostraci´ on
Se implementaron tres tareas de demostraci´on. vLEDFlaskTask(): Se encarga de generar una forma de onda cuadrada de 10Hz. vLCDUpdateTask(): Es la encargada de inicializar y actualizar el m´odulo LCD con la cantidad de tareas en ejecuci´on y el estado de la tarea vLEDFlashTask . vToggleTask(): Es la encargada de revisar el estado del pulsador y suspender o reanudar seg´un corresponda a la tarea vLEDFlashTask() luego de la inicializaci´on. A continuaci´on se puede ver la simulaci´on en Proteus Isis del c´odigo compilado del ejemplo.
Figura 5.1: Simulaci´on en Proteus Isis. 14
Figura 5.2: Analizador l´ogico de Proteus Isis reportando los 10Hz requeridos. En la demostraci´on puede verse que el LCD reporta cuatro tareas independientemente de que vLEDFlashTask() se encuentre suspendida o no, esto es debido a que la tarea suspendida no fue eliminada ya que no se llam´o a vTaskDelete(). Tambi´ en se debe tener en cuenta la existencia de la tarea idleTask . Adem´ as el Analizador L´ogico reporta con una resoluci´on de 25µs el cumplimiento del requerimiento de frecuencia sobre el pin PD0 .
5.1.2.
C´ odigo Fuente
El c´odigo fuente del driver LCD utilizado en esta demostraci´on se encuentra en el Ap´endice A, E y F. tasks.c En este archivo se definen las tareas del RTOS. /* * t as k s .c * * C r ea d o : 2 6 /0 1 /2 0 12 2 0 :4 2 :2 5 * A ut o r : n i ko s am u s */ #include
//FreeRTOS #include " F r e e R T O S . h " #include " t a s k . h " //Drivers #include " l c d _ l i b . h " #include " l e d _ l i b . h " #include " b o t o n _ l i b . h " //Header #include " t a s k s . h " / / T ar ea e n ca r ga d a d e g e ne r ar l a o nd a c u ad r ad a d e 1 0 Hz // TICK TAREA TOGGLE
15
// 1000 / 50 / 2 = 10 Hz void vLEDFlashTask( void * p v P a r am e t e rs ) { p o r t T ic k T y p e x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount(); LEDInit(); for ( ;; ) { LEDToggle(0); vTaskDelayUntil (&xLastWakeTime ,xFrequency ); } } / / T ar ea e n ca r ga d a d e a c tu a li z ar e l L CD void vLCDUpdateTask( void * p v P a r am e t e r s ) { / / C ad e na s a l ma c en a da s e n R OM s t a ti c c o n st u i nt 8 _ t t i t ul o [ ] P R O GM E M = " F r ee R TO S & D r iv e rL C D " ; s t a ti c c o n st u i nt 8 _ t s i di [ ] P R O GM E M = " S i s t e m as D i g i ta l e s " ; s t a ti c c o n st u i nt 8 _ t t a r ea s [ ] P R O GM E M = " T A R E A S : "; s t a ti c c o n st u i nt 8 _ t s t r VL E D [ ] P R O GM E M = " v L E D F l a s h T a s k : "; / / Ar ma do d e l a b as e d e t ie mp o p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 00 ; xLastWakeTime=xTaskGetTickCount(); unsigned p o r t B A S E_ T Y P E u x T as k s ; / / I n i c i a li z a c i on d e l L C D LCDinit(); LCDclr(); LCDcursorOFF(); C o p y S tr i n g t o LC D ( t i t ul o , 0 , 0 ) ; C o p y S tr i n g t o LC D ( s i di , 0 , 1 ) ; C o p y S tr i n g t o LC D ( t a r ea s , 0 , 2 ) ; C o p y S tr i n g t o LC D ( s t r V LE D , 0 , 3 ) ; / / E je c ut a r s i em p re q ue l a t ar ea e st e e n t i em p o d e e j ec u ci o n for (;;){ / / O bt e ne r c a nt i da d d e t ar e as y v i su a li z ar l as uxTasks=uxTaskGetNumberOfTasks(); LCDGotoXY(13,2); LCDsendChar(uxTasks+48); LCDGotoXY(15,3); / / Si l a t ar ea e st a s us pe nd id a m os tr ar " S US P " y s i e st a c or ri en do " RUN" if ( x T a s k I s T a s kS u s p e n de d ( x L E D F l a s h T a s k Ha n d l e r ) ) { LCDstring( " S U S P " ,4); } else { LCDstring( " RU N " ,4); } vTaskDelayUntil (&xLastWakeTime ,xFrequency ); } } / / Ta re a q ue m on it or ea e l p ul sa do r y c am bi a e l e st ad o d e l a t ar ea vLEDFlashTask void vToggleTask( void * p v P a r a me t e r s ) { / / B as e d e t i em p o p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 2 00 ; xLastWakeTime=xTaskGetTickCount(); unsigned portBASE_TYPE; / / I n i c i al i z a r b o t on
16
BOTONInit(); / / E je c ut a r s i em p re q ue l a t ar ea e st e e n t i em p o d e e j ec u ci o n for (;;){ if ( B O T O N C h e c k P i n ( 0 ) ) { / / Ca mb ia r el e st ad o d e l a t ar ea s eg un s u e st ad o a ct ua l if ( x T a s k I s T a s kS u s p e n de d ( x L E D F l as h T a s k Ha n d l e r ) ) { vTaskResume(xLEDFlashTaskHandler); } else { vTaskSuspend(xLEDFlashTaskHandler); } vTaskDelayUntil (&xLastWakeTime ,xFrequency ); / / D eb o un c e : N o s e gu i r h as ta q ue s e d e te c te e l f l an c o b aj o while ( B O T O N C h e c k P i n ( 0 ) ) { } } } }
main.c En este archivo se inicializa el RTOS y se instancian las tareas. /* * m ai n .c * D e mo s tr a ci o n d e D r iv e r L CD * C r ea d o : 0 2 /0 2 /2 0 12 1 7 :2 2 :0 9 * A ut o r : n i ko s am u s */ #include #include #include #include
"FreeRTOS.h" "task.h" "tasks.h"
/ * P r io r id a de s d e l as T a re a s */ #define m a in L C D_ T OG G L E_ T A SK _ PR I O RI T Y #define m a in L C D_ U PD A T E_ T A SK _ PR I O RI T Y #define m a in L C D_ F L AS H _T A S K_ P R IO R I TY
( t s k ID L E_ P RI O R IT Y ) ( t s k ID L E_ P RI O R IT Y ) + 1 ( t s k I DL E _P R IO R I TY ) + 2
p o r t SH O R T m a in ( void ){ / / C re a ci o n d e l a t ar e a d e a c tu a li z ac i on d el L CD xTaskCreate( vLCDUpdateTask ,( s i g ne d c h ar *) " L C D " , configMINIMAL_STACK_SIZE , N UL L , m a i n L CD _ U P D A TE _ T A S K_ P R I O RI T Y , N U LL ) ;
/ / Cr ea ci on d e la t ar ea q ue g en er a l a o nd a c ua dr ad a xTaskCreate( vLEDFlashTask ,( s i g ne d c h ar *) " L E D F l a s h " , configMINIMAL_STACK_SIZE , N UL L , m a i n L CD _ F L A SH _ T A S K_ P R I O RI T Y , & x L E D F l a s h T as k H a n d le r ) ;
/ / C re a ci o n d e l a t ar e a q ue c a mb ia e l e s ta d o d e v L ED F la s hT a sk xTaskCreate( vToggleTask ,( s i g ne d c h ar *) " T o g g l e T a s k " , configMINIMAL_STACK_SIZE , N UL L , m a i n L CD _ T O G G LE _ T A S K_ P R I O RI T Y , N U LL ) ;
/ / I n i c ia r e l S c h e du l e r vTaskStartScheduler(); / / N un ca s e d eb e l l eg a r a qu i while (1){ }
17
return 0; }
5.2.
Teclado Matricial Hexadecimal
Se implement´ o un sistema muy simple en el que se actualiza el LCD con la tecla presionada en el teclado hexadecimal. Este driver fue desarrollado desde cero e incluye una ´unica funci´on KEYPADGetTeclaPresionada(), que es la encargada de recorrer y verificar el estado de las teclas del teclado matricial y devolver aquella que haya sido presionada. Se simul´o el c´odigo compilado del ejemplo sobre Proteus Isis utilizando el LCD y una variaci´on del teclado KEYPAD-SMALLCALC modificado para que en vez de s´ımbolos de calculadora muestre los 16 caracteres de la base hexadecimal.
Figura 5.3: Teclado Hexadecimal en Proteus Isis.
5.2.1.
Tareas de demostraci´ on
Se implementaron dos tareas de demostraci´on. vLCDUpdateTask(): Es la encargada de inicializar y actualizar el modulo LCD con la tecla presionada, enviada desde la tarea vKEYPADReadTask . a trav´es de una cola. vKEYPADReadTask(): Se encarga de monitorear el teclado y de poner en la cola de comunicaci´on entre tareas el caracter asociado a la tecla presionada para su posterior visualizaci´on.
5.2.2.
C´ odigo Fuente
El c´odigo fuente de los drivers utilizados en esta demostraci´on se encuentran en los Ap´endices A y B.
18
tasks.c En este archivo se definen las tareas del RTOS. /* * t as k s .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :1 0 :5 0 * A ut o r : n i ko s am u s */ #include //RTOS #include " F r e e R T O S . h " #include " t a s k . h " #include " q u e u e . h " //Drivers #include " l c d _ l i b . h " #include " k e y p a d _ l i b . h " //Tareas #include " t a s k s . h " static x Q u e u e H an d l e x Q u e u eK e y P r es s ; / * T ar e a d e l e ct u ra d el t ec la do , p ar a c o mu n ic a rs e c on l a t ar ea d e a c tu a li z ac i on d el L CD s e u t il i za u na c ol a * / void vKEYPADReadTask( void * p v P a r am e t e r s ) { / / E je c ut a r t a re a 2 0 v e ce s p or s e gu n do p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount();
u i n t 8_ t i n t T ec l a ; / / C re a ci o n d e l a c ol a d e c o mu n ic a ci o n e n tr e t ar e as xQueueKeyPress=xQueueCreate(1, sizeof ( u in t8 _t ) ) ; / / E je c ut a r s i em p re q ue l a t ar ea e st e e n t i em p o d e e j ec u ci o n for (;;){ / / O b t e ne r t e cl a p r e s io n a d a intTecla=KEYPADGetTeclaPresionada(); / / Si n o s e r ec ib e u n e sp ac io ( n in gu na t ec la ) , e nv ia r a l f in al d e l a cola if ( i n t T e c l a ! = 0 x 2 0 ) { x Q u e u e Se n d T o Ba c k ( x Q u eu e K ey P r es s , & i n t Te c la , 0 ) ; vTaskDelayUntil (&xLastWakeTime ,xFrequency ); } } } / / T ar ea d e i n ci a li z ac i on y a c tu a li z ac i on d el L CD , m u es t ra l a u l ti m a t e c la p r e s io n a d a void vLCDUpdateTask( void * p v P a ra m e t e rs ) { / / E je c ut a r t a re a 2 0 v e ce s p or s e gu n do p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount(); s t a ti c c o n st u i nt 8 _ t S T R _ SI D I [ ] P R O GM E M = " S i st e ma s D i gi t al e s " ; s t a ti c c o n st u i nt 8 _ t S T R _ T IT U L O [ ] P R O GM E M = " F re eR TO S & K ey pa d " ; s t a ti c c o n st u i nt 8 _ t S T R _ TE C L A [ ] P R O GM E M = " T EC L A P R ES I ON A DA : " ; u i n t 8_ t i n t T e cl a P r e s io n a d a ;
19
/ / I n i c i al i z a r L C D LCDinit(); LCDclr(); LCDcursorOFF(); / / C a d e na s e s t a ti c a s C o p y S tr i n g t o LC D ( S T R _ SI D I , 0 , 0 ) ; C o p y S tr i n g t o LC D ( S T R _ T IT U L O , 0 , 1 ) ; C o p y S tr i n g t o LC D ( S T R _ TE C L A , 0 , 3 ) ; / / E je c ut a r s i em p re q ue l a t ar ea e st e e n t i em p o d e e j ec u ci o n for (;;){ / / Si h ay a lg un e le me nt o e n l a co la , v is ua li za rl o e n l a p os ic io n (19,3) if ( x Q u e u eR e c e i ve ( x Q u eu e K e yP r e ss , ( void * ) & i n t Te c la P re s io n ad a , 0 )!=pdFAIL){ LCDGotoXY(19,3); LCDsendChar(intTeclaPresionada); } vTaskDelayUntil (&xLastWakeTime ,xFrequency ); }
}
main.c En este archivo se inicializa el RTOS y se instancian las tareas. /* * m ai n .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :0 2 :3 3 * A ut o r : n i ko s am u s */ #include //FreeRTOS #include " F r e e R T O S . h " #include " t a s k . h " #include " q u e u e . h " //Header #include " t a s k s . h " / * P r io r id a de s d e l as T a re a s */ #define m ai nL CD _U PD AT E_ TA SK _P RI OR IT Y #define m ai nK EY PA D_ RE AD _T AS K_ PR IO RI TY
( t sk ID LE _P RI OR IT Y ) ( t sk ID LE _P RI OR IT Y )
p o r t SH O R T m a in ( void ) { / / C r e ar t a re a : v K E Y P A DR e a d T as k m a y or p r i o ri d a d x T a s kC r e a t e ( v K E YP A D R ea d T a sk , ( s i gn e d c h ar * ) " K E Y P A D " , configMINIMAL_STACK_SIZE , NULL , mainKEYPAD_READ_TASK_PRIORITY , NULL );
/ / C r e ar t a r ea : v L C D U pd a t e T as k x T a s kC r e a t e ( v L C DU p d at e T as k , ( s i g ne d c h ar * ) " L C D " , configMINIMAL_STACK_SIZE , NULL , mainLCD_UPDATE_TASK_PRIORITY , NULL );
/ / I n i c ia r e l S c h e du l e r vTaskStartScheduler(); / / N un ca s e d eb e l l eg a r a qu i
20
while (1){ } return 0; }
5.3.
Conversor Anal´ ogico Digital
Se implement´ o un sistema encargado de tomar muestras de las tres primeras entradas del conversor anal´ogico digital (PORTA) y visualizar sus valores en el LCD. Se configur´o el conversor para utilizar una resoluci´ on de 10 bits. Para la visualizaci´on adecuada de los valores de la conversi´on, es decir, su conversi´on de valores entre 0 y 1024 a valores entre 0 y 5V se us´o la funci´on LCDInt162String() que utiliza c´alculos de punto fijo. Este driver fue desarrollado desde cero, dispone de las funciones ADCInit() que es la encargada de inicializar el perif´erico y ADCGetSample(pin adc) que es la que realiza y devuelve la conversi´on. Se simul´o el c´odigo compilado del ejemplo utilizando Proteus Isis. Se conectaron tres potenci´ometros a las tres primeras entradas del PORTA y a los valores de referencia de alimentaci´on (VCC y GND). Tambi´en se incorpor´ o un LCD para visualizar el resultado de las conversiones.
Figura 5.4: Conversor Anal´ogico/Digital en Proteus Isis.
5.3.1.
Tareas de demostraci´ on
Se implementaron dos tareas de demostraci´on. vLCDUpdateTask():Se encarga de inicializar y actualizar el modulo LCD con los valores de las conversiones realizadas por vADCSampleTask . vADSampleTask(): Esta tarea realiza las conversiones anal´ogico/digitales. Hace uso de una cola para comunicarlas a la tarea de visualizaci´on vLCDUpdateTask() y tambi´ en de un sem´ aforo para 21
indicar que se encuentra realizando una conversi´on. Si se implementara otra tarea que hiciera uso del conversor ADC esta podr´ıa chequear, antes de intentar una conversi´on, que el sem´aforo se encuentre libre y tomarlo para no “pisarse“ con la primer tarea.
5.3.2.
C´ odigo Fuente
El c´odigo fuente de los drivers utilizados en esta demostraci´on se encuentra en los Ap´endices A y C. tasks.c En este archivo se definen las tareas que del RTOS. /* * t as k s .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :1 0 :5 0 * A ut o r : n i ko s am u s */ #include //RTOS #include " F r e e R T O S . h " #include " t a s k . h " #include " q u e u e . h " #include " s e m p h r . h " //Drivers #include " l c d _ l i b . h " #include " a d c _ l i b . h " //Tareas #include " t a s k s . h " / / C ol a d e c o mu n ic a ci o n e nt r e t a re as static x Q u e u e H an d l e x Q u e u eA D C S a m pl e ; / / S em a fo r o p ar a t om a r c o nt r ol d el A DC static x S e m a p h o r e H an d l e x S e m a p ho r e A D C Sa m p l e ; / * Ta re a d e m ue st re o d el A DC , s e c om un ic a c on la t ar ea de a ct ua li za ci on d el L CD p or m ed io d e u na c ol a y u sa un s em af or o p ar a i nd ic ar q ue e st a u s an d o e l A DC * / void vADCSampleTask( void * p v P a r am e t e r s ) { / / Ej ec ut ar 1 /3 d e t ar ea 2 0 v ec es p or s eg un do a lg o c om o t ar ea : 6 ,3 v e ce s p or s e gu n do . p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount(); A D C S am p l e A D C M ue s t r a ; / / E nu m p ar a n o u sa r n u me r os m a gi c os enum intEntradas{iADC0,iADC1,iADC2,iADC3,iADC4,iADC5,iADC6,iADC7}; / / I n ic i al i za c io n d e v a ri a bl e s y D r iv e rs vSemaphoreCreateBinary(xSemaphoreADCSample); xQueueADCSample=xQueueCreate(3, sizeof ( A DC Sa mp le ) ) ; ADCInit(); for (;;) { / / L ec t ur a d e l os p r im e ro s 3 A DC d el m i cr o c on t ro l ad o r fo r ( u i n t 8 _t i n t I np u t = i A D C 0 ; i n tI n pu t < i A D C 3 ; i n t I np u t + + ) { / / I nt e nt o t om a r e l s e ma f or o p ar a g an a r a c ce s o a l A DC if ( x S e m a p h o r e A D C S a m p l e ! = N U L L ) { if (xSemaphoreTake (xSemaphoreADCSample ,(portTickType ) 10)==pdTRUE ){ / / T om a d e l a m u es t ra ADCMuestra=ADCGetSample(intInput);
22
/ / E nv i o a l a c ol a d e c o mu n ic a ci o n e n tr e t a re a s x Q u e ue S e n d ( x Q u eu e A D CS a m p le , & A D C M ue s t ra , 0 ) ; / / D e v u el v o e l s e m af o r o xSemaphoreGive(xSemaphoreADCSample); } } / / I n cl u ye n do e l d e la y e n tr e c o nv e rs i on e s a u me n ta m u ch i si m o e l r en di mi en to ya q ue s e p ue de b or ra r a lg un e le me nt o de l a c ol a a l l l a ma r a v L C D U pd a t e T as k ( ) e n tr e c o n v er s i o n es vTaskDelayUntil (&xLastWakeTime ,xFrequency ); }
} } / / T ar ea d e i n ci a li z ac i on y a c tu a li z ac i on d el L CD c on l os v a lo r ea d a d q u ir i d o s p o r v A D C S am p l e T as k ( ) void vLCDUpdateTask( void * p v P a r am e t e r s ) { / / E je c ut a r t a re a 1 00 v ec e s p or s e gu n do p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 1 0; s t a ti c c o n st u i nt 8 _ t S T R _ T IT U L O [ ] P R O GM E M = " FreeRTOS & ADC "; s t a ti c c o n st u i nt 8 _ t S T R _A D C [ ] P R O GM E M = " Ch : V al or : "; A D C S am p l e a d c S am p l e ; xLastWakeTime=xTaskGetTickCount();
/ / I n i c i al i z a r L C D LCDinit(); LCDclr(); LCDcursorOFF(); / / C a d e na s e s t a ti c a s C o p y S tr i n g t o LC D ( S T R _ T IT U L O , C o p y S tr i n g t o LC D ( S T R _ AD C , 0 , C o p y S tr i n g t o LC D ( S T R _ AD C , 0 , C o p y S tr i n g t o LC D ( S T R _ AD C , 0 ,
0, 0); 1); 2); 3);
/ / E je c ut a r s i em p re q ue l a t ar ea s e e n cu e nt r e e n t i em p o d e e j ec u ci o n for (;;){ / / Si h ay u na c o nv e rs i on A DC e n l a c ol a , v i su a li z ar l a if ( x Q u e u eR e c e i ve ( x Q u e ue A D C Sa m p l e , ( void * ) & a dc Sa mp le , 0 ) != pdFAIL){ / / Vi su al iz ar e l p in e n e l q ue s e r ea li zo l a c on ve rs io n . LCDGotoXY(3,adcSample.Pin+1); LCDsendChar(adcSample.Pin+48); / / V i su a li z ar e l v a lo r d e l a c o nv e rs i on a j us t ad o p ar a q ue l a r e pr e se n ta c io n c o in c id a c on e l r a ng o d el c o nv e rs o r . LCDGotoXY(11,adcSample.Pin+1); adcSample.Value=adcSample.Value*50000/1024; LCDInt162String( adcSample.Value ,1, V ) ; } vTaskDelayUntil (&xLastWakeTime ,xFrequency ); }
'
'
}
main.c En este archivo se inicializa el RTOS y se instancian las tareas. /* * m ai n .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :0 2 :3 3
23
* A ut o r : n i ko s am u s */ #include //FreeRTOS #include " F r e e R T O S . h " #include " q u e u e . h " #include " t a s k . h " //Header #include " t a s k s . h "
/ * P r io r id a de s d e l as T a re a s */ #define m ai nA DC _R EA D_ TA SK _P RI OR IT Y #define m ai nL CD _U PD AT E_ TA SK _P RI OR IT Y p o r t SH O R T m a in ( void ){ x T a s kC r e a t e ( v A D CS a m pl e T as k , c o n f i gM I N I MA L _ S T AC K _ S I ZE , x T a s kC r e a t e ( v L C DU p d at e T as k , configMINIMAL_STACK_SIZE , );
( t sk ID LE _P RI OR IT Y ) +1 ( t sk ID LE _P RI OR IT Y )
( s i g ne d c h ar * ) " K E Y P A D " , N UL L , m a i n AD C _ R E AD _ T A S K_ P R I O RI T Y , N U LL ) ; ( s i g ne d c h ar * ) " L C D " , NULL , mainLCD_UPDATE_TASK_PRIORITY , NULL
/ / I n i c ia r e l S c h e du l e r vTaskStartScheduler(); / / N un ca d eb e l le g ar a qu i while (1){ } return 0; }
5.4.
Puerto Serie
En esta demostraci´on se estableci´o una comunicaci´on entre la PC y el microcontrolador de modo tal que al iniciarse, el microcontrolador salude a la PC con el mensaje: ”Demostracion del puerto serie con FreeRTOS“, luego cada vez que la PC env´ıe una cadena, el microcontrolador le responder´a con tres mensajes: ”Recibiendo cadena“. Un echo de la cadena enviada. ”Cadena recibida“. Y escribir´a una l´ınea con el mensa je en el display LCD. Se opt´ o por usar el driver para puerto serie lib serial.c distribu´ıdo como parte de FreeRTOS . Esta librer´ıa se distribuye bajo la licencia GNU Public License con la excepci´on FreeRTOS descrita en el Ap´endice D. Para la demostraci´on del puerto serie en Porteus Isis se us´o el conector COMPIM (Comm Port Physical Interface Model) conectado al puerto virtual COM4 creado con el software Virtual Serial Port Emulator en modalidad connector . Este puerto serie puede ser abierto dos veces, es decir, dos aplicaciones distintas pueden abrirlo simult´aneamente para generar una comunicaci´on entre ellas. En este caso, las aplicaciones fueron Terminal.exe y Proteus Isis.
24
Figura 5.5: Simulaci´on en Proteus Isis en comunicaci´on con la terminal.
Figura 5.6: Terminal conectada al puerto serie virtual compartido.
25
5.4.1.
Tareas de demostraci´ on
Se implementaron dos tareas de demostraci´on. vLCDUpdateTask(): Es la tarea encargada de inicializar, y actualizar el modulo LCD con la cadena recibida por vSERIALCommTask(). vSERIALCommTask(): Esta tarea se encarga de recibir la cadena enviada por la PC a trav´es del puerto serie y transmitirla a la tarea vLCDUpdateTask() por medio de una cola.
5.4.2.
C´ odigo Fuente
El c´odigo fuente de los drivers utilizados en esta demostraci´on se encuentra en los Ap´endices A y D. tasks.c En este archivo se definen las tareas del RTOS. /* * t as k s .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :1 0 :5 0 * A ut o r : n i ko s am u s */ #include //RTOS #include " F r e e R T O S . h " #include " t a s k . h " #include " q u e u e . h " //Drivers #include " l c d _ l i b . h " #include " l i b _ s e r i a l . h " //Tareas #include " t a s k s . h " / * C ol a d e c o mu n ic a ci o n e nt r e t a re as * / static x Q u e u e H a nd l e x Q u e u eS e r i a l Co m m ; / * M a ne j ad o r d el p ue r to s e ri e . R e qu e ri d o p or e l d r iv e r */ x C o m P or t H a n dl e x S e r ia l P o r t ; / / T ar ea d e r e ce p ci o n d e c a ra c te r es p or e l p u er t o s e ri e ; / / Lo s g ua r da e n u na c ol a p ar a c o mu n ic a rl o s a l a t ar e a d e a c tu a li z ac i on d el L CD . void vSerialCommTask( void * p v P a r am e t e r s ) { / / E je c ut a r l a t ar e a 2 0 v ec e s p or s e gu n do . p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount(); u i n t 8_ t c R x e dC h a r ; / / D ri v er U S AR T : B a ud i os ( 57 6 00 p or r e st r ic c io n d e I si s ) , T a ma n o d e l a c ol a de e nv io , T am an o d e l a c ol a d e r ec ep ci on / / I n i c ia r D r i ve r S e ri e x S er i al P or t = x S er i a lP o r tI n i tM i n im a l ( 5 76 00 , 8 0 , 1 6) ;
/ / C re ar u na c ol a p ar a 1 6 c a ra c te r es xQueueSerialComm=xQueueCreate(16, sizeof ( u i nt 8 _t ) ) ; //Bienvenida avrSerialPrint_P(PSTR( " \ r D em o st r ac i on d el p ue r to s e ri e c on F r ee R TO S \ r " )); / / E je c ut a r s i em p re q ue l a t ar ea e st e e n t i em p o d e e j ec u ci o n
26
for (;;){ / / R e c i bi r c a r a ct e r i n i ci a l while ( x S er i al G et C ha r ( x Se r ia l Po r t , & c R xe d Ch ar , x N oB l oc k ) ) { / / Si s e r e ci b e u n c a ra c te r m a nd a r m e ns a je avrSerialPrint_P(PSTR( " \ r R e c i b i en d o c a d en a \ r " )) ; / / D e v o lv e r e l c a r ac t e r avrSerialWrite(cRxedChar); / / Po ne r e l c ar ac te r e n l a c ol a p ar a m os tr ar lo e n e l L CD x Q u e ue S e n d ( x Q u e ue S e ri a l C om m , & c R x e dC h ar , 0 ) ; / / R ec i bi r e l r es t o d e l os c a ra c te r es while ( x S er i al G et C ha r ( x Se r ia l Po r t , & c R xe dC ha r , x N oB l oc k ) ) { / / D e v o lv e r e l c a r ac t e r avrSerialWrite(cRxedChar); / / Po ne r el c ar ac te r e n l a c ol a p ar a m os tr ar lo en e l L CD x Q u e ue S e n d ( x Q u eu e S e ri a l Co m m , & c R x e dC h ar , 0 ) ; } / / M en s aj e d e f in d e t r an s mi s io n avrSerialPrint_P(PSTR( " \ r C a d e na r e c ib i d a \ r " )) ; } vTaskDelayUntil (&xLastWakeTime ,xFrequency ); } } / * T ar ea d e a c tu l iz a ci o n d el L CD , l ee l a c ol a d e c o mu n ic a ci o n e nt r e t ar ea s y e sc ri be u na l in ea e n e l L CD . N o s e s ol uc io no i n te n ci o n al m en t e e l p r ob l em a d e l a d e li m it a ci o n d e l as l in e as r ec ib id as e n l a c ol a p ar a m os tr ar el e fe ct o d e l a i nt er ru pc io n d e l a t ar ea v L CD U pd a te T as k c u an do a un q u ed a n c a ra c te r es p or r e ci b ir y s e a gr eg an n ue vo s a l f in al d e l a c ol a */ void vLCDUpdateTask( void * p v P a ra m e t e rs ) { / / E je c ut a r l a t ar e a 2 0 v ec e s p or s e gu n do . p o r t T ic k T y pe x L a s t Wa k e T i me ; const p o r t Ti c kT y pe x F re q ue n cy = 5 0; xLastWakeTime=xTaskGetTickCount();
s t a ti c c o n st u i nt 8 _ t S T R _ T IT U L O [ ] P R O GM E M = " static u i n t 8_ t c h a r S er i a l R X ; static u i n t 8 _ t i n t C o lu m n a L cd = 0 , i n t F i l a L cd = 1 ;
f ree RTO S & S er ial " ;
/ / I n i c i al i z a r L C D LCDinit(); LCDclr(); LCDcursorOFF(); / / C a d e na s e s t a ti c a s C o p y S tr i n g t o LC D ( S T R _ T IT U L O , 0 , 0 ) ; / / E je c ua r s i em p re q ue l a t ar e a e st e e n t i em p o d e e j ec u ci o n for (;;){ LCDGotoXY(0,intFilaLcd); intColumnaLcd=3; / / Mi en tr as h al la c ar ac te re s e n l a c ol a y no s e s up er e e l l ar go d e l a l in e a , v i s u a li z a r l os . while ( x Q u e u eR e c e i ve ( x Q u e ue S e r ia l C om m , ( void * ) & c h a r Se r i al R X , x N o Bl o c k ) ! = p d F A IL & & i n t Co l u mn a L cd < 2 0) { LCDsendChar(intFilaLcd+48); LCDstring( " : " ,2); LCDsendChar(charSerialRX); intColumnaLcd++; / / Mi en tr as h al la c ar ac te re s en l a c ol a y n o s e s up er e e l l ar go d e
27
l a l in ea , v i su a li z ar l os . while ( x Q u e u eR e c e i ve ( x Q u e ue S e r ia l C om m , ( void * ) & c h a r Se r i al R X , x N o Bl o c k ) ! = p d F A IL & & i n t Co l u mn a L cd < 2 0) { LCDsendChar(charSerialRX); intColumnaLcd++; } / / Si s e e nc ue nt ra e n l a u lt im a f il a v ol ve r a l a s eg un da if ( i n t F i l aL c d > 2) { intFilaLcd=1; } else { intFilaLcd++; }
} vTaskDelayUntil (&xLastWakeTime ,xFrequency ); } }
main.c En este archivo se inicializa el RTOS y se instancian las tareas. /* * m ai n .c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :0 2 :3 3 * A ut o r : n i ko s am u s */ #include #include #include #include #include
"FreeRTOS.h" "task.h" "tasks.h" "queue.h"
/ * P r io r id a de s d e l as T a re a s */ #define m a i n S E R IA L _ C O M M _T A S K _ P R IO R I T Y ( t s k I D L E _ P RI O R I T Y ) + 1 #define m a in L C D_ U PD A T E_ T A SK _ PR I O RI T Y ( t s k ID L E_ P RI O R IT Y ) p o r t SH O R T m a in ( void ){ x T a s kC r e a t e ( v S e ri a l C om m T a sk , ( s i gn e d c h ar * ) " S E R I A L " , configMINIMAL_STACK_SIZE , NULL , mainSERIAL_COMM_TASK_PRIORITY , NULL ); x T a s kC r e a t e ( v L C DU p d at e T as k , ( s i g ne d c h ar * ) " L C D " , configMINIMAL_STACK_SIZE , NULL , mainLCD_UPDATE_TASK_PRIORITY , NULL );
/ / I n i c ia r e l S c h e du l e r vTaskStartScheduler(); / / N un ca s e d eb e l l eg a r a qu i while (1){ } return 0; }
5.5.
Leds y Botones
Se escribieron dos peque˜ nas y muy b´asicas librer´ıas para la depuraci´on y la interacci´on con el microcontrolador. Se decidi´o darles esta entidad y no simplemente intercalar el c´odigo que ejecutan dentro de las tareas y/o los drivers para mantener un c´odigo prolijo y segmentado seg´ un su funci´on. Ser´ıa bueno en un futuro combinar ambas librer´ıas y generar una que sea capaz de configurar libremente todos los pines de un
28
puerto como entradas o salidas. La librer´ıa led lib.c s´olo dispone de dos m´etodos; LEDInit() para inicializar el puerto al que se encuentran conectados los leds y LEDTogle(nro pin) que invierte el valor actual del pin seleccionado. La librer´ıa boton lib.c tambi´en dispone de dos m´etodos BOTONInit() que inicializa el puerto y BOTONCheckPin(nro pin) que devuelve el valor actual del pin seleccionado. Estas librer´ıas se encuentran disponibles en los Ap´endices E y F.
29
Ap´ endice A Librer´ıa para Display LCD
A.1.
lcd lib.h
//****************************************************************** // // File N ame : lcd_lib.h // Title : 8 and 4 bit LCd i nterface // A ut ho r : S ci en ce pr og . co m - C op yr ig ht ( C) 2 00 7 // Created : 2007 -03 -29 // Revised : 2007 -08 -08 // Version : 1.0 / / T ar ge t M CU : A tm el A VR s er ie s // / / T hi s c od e i s d is tr ib ut ed u nd er t he G NU P ub li c L ic en se / / w hi c h c an b e f ou n d a t h tt p : // w w w . gn u . or g / l ic e ns e s / gp l . tx t // //******************************************************************* '
'
#ifndef LIB_LCD_H_ #define LIB_LCD_H_ #include #include " h a r d w a r e C o n f i g . h " / / Un co mm en t t hi s i f L CD 4 b it i nt er fa ce i s u se d //****************************************** #define LCD_4bit //*********************************************** #define #define #define #define #define #define #define #define #define #define #define
LCD_RS LCD_RW L C D_ E 2 LCD_D0 LCD_D1 LCD_D2 LCD_D3 LCD_D4 LCD_D5 LCD_D6 LCD_D7
0 / / de fi ne M CU p in c on ne ct ed t o L CD R S 1 / / de fi ne M CU p in c on ne ct ed t o L CD R / W / / de fi ne M CU p in c on ne ct ed to L CD E 0 / / de fi ne M CU p in c on ne ct ed t o L CD D 0 1 / / de fi ne M CU p in c on ne ct ed t o L CD D 1 2 / / de fi ne M CU p in c on ne ct ed t o L CD D 1 3 / / de fi ne M CU p in c on ne ct ed t o L CD D 2 4 / / de fi ne M CU p in c on ne ct ed t o L CD D 3 5 / / de fi ne M CU p in c on ne ct ed t o L CD D 4 6 / / de fi ne M CU p in c on ne ct ed t o L CD D 5 7 / / de fi ne M CU p in c on ne ct ed t o L CD D 6
#define L D P c o n f i g LC D _ D A T A_ P O R T d a ta p i ns #define L C P c o n f i g LC D _ C O N T RO L _ P O R T c o n t ro l p i ns #define L D D R c o n f i g LC D _ D A T A_ R E G p or t c o nn e ct e d t o L CD d at a p in s
/ / d ef i ne MC U p or t c o nn e ct e d t o L CD
/ / d ef i ne M CU p or t c o nn e ct e d t o L CD
/ / d ef i ne MC U d i re c ti o n r e gi s te r f or
30
#define L C D R c o n f i g L CD _ C O N T RO L _ R E G / / d ef i ne M CU d i re c ti o n r e gi s te r f or p or t c o nn e ct e d t o L CD c o nt r ol p in s #define LCD_CLR 0 / / D B0 : c l ea r d i sp l ay #define LCD_HOME 1 // D B 1 : r e tu r n t o h om e p o si t io n #define LCD_ENTRY _MODE 2 // D B 2 : s et e nt r y m od e #define LCD_ENTRY_INC 1 / / D B1 : i n c r em e n t #define LCD_ ENTRY_SHIFT 0 / / D B2 : s h i ft #define LCD_ON_CTRL 3 / / DB 3 : t ur n l cd / c u rs o r o n #define LCD_ON_DI SPLAY 2 // D B 2 : t ur n d i sp l ay o n #define LCD_ON_CURSOR 1 // D B 1 : t ur n c u rs o r o n #define LCD_ON_BLINK 0 // D B 0 : b l i n ki n g c u r so r #define LCD_MOVE 4 // D B 4 : m o ve c u r so r / d i s p l a y #define LCD_MOVE_DISP 3 // D B 3 : m ov e d i sp l ay ( 0- > m ov e c u rs o r ) #define LCD_MOVE_ RIGHT 2 // D B 2 : m ov e r i gh t ( 0- > l ef t ) #define LCD_FUNCTION 5 / / D B5 : f u nc t io n s et #define L CD _F UN CT IO N_ 8B IT 4 // D B 4 : s et 8 B IT m od e ( 0 - >4 B IT m od e ) #define L C D _ F U N C TI O N _ 2 L IN E S 3 // D B 3 : t wo l in e s ( 0 - > on e l in e ) #define L C D _ F U N C TI O N _ 1 0 DO T S 2 // D B 2 : 5 x 1 0 f on t ( 0 - >5 x 7 f on t ) #define LCD_CGRAM 6 / / DB 6 : s et C G R AM a dd re ss #define LCD_DDRAM 7 / / DB 7 : s et D D R AM a dd re ss / / r e ad i ng : #define LCD_BUSY 7 / / DB 7 : L CD i s b us y #define LCD_LINES 4 / / v i s ib l e l i n es #define L CD _L IN E_ LE NG TH 20 / / l in e l e ng t h ( i n c h ar a ct e rs ) / / c u rs o r p o si t io n t o D D RA M m a pp i ng #define L C D_ LI N E0 _D DR A MA DD R 0 x 00 #define L C D_ LI N E1 _D DR A MA DD R 0 x 40 #define L C D_ LI N E2 _D DR A MA DD R 0 x 14 #define L C D_ LI N E3 _D DR A MA DD R 0 x 54 / / p r og r es s b ar d e fi n es #define P R O G R E S S P I XE L S _ P E R_ C H A R 6 void LCDInt162String( uint16_t ,uint8_t ,uint8_t); void LCDsendChar(uint8_t); / / fo rm s d at a r ea dy t o s en d to L CD void LCDsendCommand(uint8_t); // f or ms d at a r ea dy t o s en d t o L CD void LCDinit( void ); / / I n i t i al i z e s L C D void LCDclr( void ) ; / / C l e ar s L C D void LCDhome( void ); / / LC D c u rs o r h om e void L C D s t r in g ( u i n t 8 _ t * , u i n t8 _ t ) ; / / O ut p ut s s tr i ng t o L C D void LCDGotoXY (uint8_t , uint8_t); / / Cu rs or t o X Y p os it io n void CopyStringtoLCD( const u i n t 8_ t * , u i nt 8 _t , u i n t8 _ t ) ; / / c o p ie s f l a sh s tr in g to L CD a t x , y void LCDdefinechar( const u i n t8 _ t * , u i n t 8 _t ) ; / / w ri te c ha r t o L CD C G RA M void LCDshiftRight(uint8_t); / / s hi f t b y n c h ar a ct e rs R ig h t void LCDshiftLeft(uint8_t); // s h if t b y n c h ar a ct e rs L ef t void LCDcursorOn( void ) ; / / U n de r li n e c ur s or O N void LCDcursorOnBlink( void ); / / U n de r li n e b l in k in g c u rs o r O N void LCDcursorOFF( void ); / / C u r so r O F F void LCDblank( void ) ; / / LC D b la n k b ut n ot c l ea r ed void LCDvisible( void ); / / L C D v i s ib l e void LCDcursorLeft(uint8_t); / / Sh if t c ur so r l ef t b y n void LCDcursorRight(uint8_t); / / sh if c ur so r r ig ht b y n / / d i sp l ay s a h o ri z on t al p r og r es s b ar a t t he c u rr e nt c ur s or l o ca t io n / / < p ro gr es s > i s t he v al u e t he b a rg r ap h s h ou ld i n di c at e / / < m ax pr og re ss > i s t he v al ue a t t he e nd o f t he b ar gr ap h / / < l en gt h > i s t he n u mb e r o f L CD c h ar a ct e rs t ha t t he b a rg r ap h s h ou l d cover / / a da p te d f ro m A VR L IB - d i sp l ay s p r og r es s o nl y f or 8 b it v a ri a bl e s void L C D p r og r e s s Ba r ( u i n t 8 _ t p r og r es s , u i n t 8_ t m a x pr o g re s s , u i n t8 _ t length);
31
#endif / * L I B_ L CD _ H_ * /
A.2.
lcd lib.c
//***************************************************************** // // File N ame : lcd_lib.c // Title : 8 and 4 bit LCd i nterface // A ut ho r : S ci en ce pr og . co m - C op yr ig ht ( C) 2 00 7 // Created : 2007 -03 -29 // Revised : 2007 -08 -08 // Version : 1.0 / / T ar ge t M CU : A tm el A VR s er ie s // / / T hi s c od e i s d is tr ib ut ed u nd er t he G NU P ub li c L ic en se / / w hi c h c an b e f ou n d a t h tt p : // w w w . gn u . or g / l ic e ns e s / gp l . tx t // //***************************************************************** #include #include #include #include #include " l c d _ l i b . h " '
'
/ * M et od o p ar a e sc ri bi r u n n um me ro d e 1 6 b it s c om o c ad en a * A ut or : ni ko sa mu s */ void LCDInt162String( uint16_t intValor ,uint8_t intFixedPoint ,uint8_t charSuffix) { u i n t 8_ t d m i l es i m a s = 0 , m i l e si m a s = 0 , c e n t e si m a s = 0 , d e c i ma s = 0 , u n i d a d es = 0 ; while (intValor >10000){ i n t V al o r - = 1 0 0 0 0 ; dmilesimas++; } while (intValor >1000){ i n tV a lo r -= 1 0 00 ; milesimas ++ ; } while (intValor >100){ i n tV a lo r -= 1 00 ; centesimas++; } while (intValor >10){ i n tV a lo r -= 1 0; decimas++; } while (intValor >1){ i n tV a lo r -= 1 ; unidades++; } if ( i n t F i x e d P o i n t = = 0 ) { L C D s e n d C h a r ( 0 ) ; L C D s e n d C h a r ( , ) ;} if (milesimas!= x ) { L C D s e n dC h a r ( d m i l e s im a s + 4 8) ; } '
'
'
'
if ( i n t F i x e d P o i n t = = 1 ) { L C D s e n d C h a r ( , ) ;} if (milesimas!= x ) { L C D s e n d Ch a r ( m i l e s i m as + 4 8) ; } '
'
'
'
32
'
'
if ( i n t F i x e d P o i n t = = 2 ) { L C D s e n d C h a r ( , ) ;} if (centesimas!= x ) { L C D s e n d Ch a r ( c e n t e s i ma s + 4 8) ; } '
'
'
'
if ( i n t F i x e d P o i n t = = 3 ) { L C D s e n d C h a r ( , ) ;} if (decimas!= x ) { L C D s e n d Ch a r ( d e c i m as + 4 8) ; } '
'
'
'
if ( i n t F i x e d P o i n t = = 4 ) { L C D s e n d C h a r ( , ) ;} if (unidades!= x ) { L C D s e n d Ch a r ( u n i d a d es + 4 8) ; } '
'
'
'
if ( c h a r S u ff i x ! = 0 x F F ) { L C D s e nd C h a r ( c h a r S uf f i x ) ; } } const u i nt 8 _ t { 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 0 , 0 x1F , p r o gr e s s 0 x0 3 , 0 x07 , 0 x1 8 , 0 x1C , arrow };
L c d C u st o m C h ar [ ] P R O GM E M = / / d ef i ne 8 c u st om L CD c h ar s 0 x00 , b l o ck 0 x10 , b l o ck 0 x18 , b l o ck 0 x1C , b l o ck 0 x1E , b l o ck 0 x1F , b l o ck 0 x0F , 0 x1E ,
0 x0 0 , 0 x00 , 0 x00 , 0 x1 F , 0 x0 0 , // 0. 0 /5 f ul l
0 x1 0 , 0 x10 , 0 x10 , 0 x1 F , 0 x0 0 , // 1. 1 /5 f ul l
0 x1 8 , 0 x18 , 0 x18 , 0 x1 F , 0 x0 0 , // 2. 2 /5 f ul l
0 x1 C , 0 x1C , 0 x1C , 0 x1 F , 0 x0 0 , // 3. 3 /5 f ul l
0 x1 E , 0 x1E , 0 x1E , 0 x1 F , 0 x0 0 , // 4. 4 /5 f ul l
0 x1 F , 0 x1F , 0 x1F , 0 x1 F , 0 x0 0 , // 5. 5 /5 f ul l
0 x1 F , 0 x0F , 0 x07 , 0 x0 3 , 0 x0 0 , / / 6 . r ew in d a rr ow 0 x1 F , 0 x1E , 0 x1C , 0 x1 8 , 0 x 00 / / 7 . f a st - f o rw a rd
void L C D s e n dC h a r ( u i n t 8 _t c h ) {
/ / S en d s C ha r t o L CD
#ifdef LCD_4bit / /4 b it p ar t LDP=(ch&0b11110000); LCP|=1<
33
LCP&=~(1<
34
LCDdefinechar((LcdCustomChar+ch),chn++); ch=ch+8; }
#else / /8 b it p ar t _delay_ms(15); LDP=0x00; LCP=0x00; LDDR|=1<
35
void LCDhome( void ) / / LC D c u rs o r h om e { LCDsendCommand(1<
36
u i n t1 6 _ t i ; a=(char_code <<3)|0x40; for ( i =0 ; i < 8 ; i + +) { pcc=pgm_read_byte(&pc[i]); LCDsendCommand(a++); LCDsendChar(pcc); } } void L C D s h i ft L e f t ( u i n t 8_ t n ) / / S cr o l n o f c h a r ac t er s R ig h t { for ( u i n t 8 _t i = 0 ; i < n ; i + +) { LCDsendCommand(0x1E); } } void L C D s h i ft R i g h t ( u i n t 8_ t n ) // S c ro l n o f c h ar a ct e rs L ef t { for ( u i n t 8 _t i = 0 ; i < n ; i + +) { LCDsendCommand(0x18); } } void LCDcursorOn( void ) / / d i sp l ay s L CD c u rs o r { LCDsendCommand(0x0E); } void LCDcursorOnBlink( void ) / / d i sp l ay s L CD b l in k in g c u rs o r { LCDsendCommand(0x0F); } void LCDcursorOFF( void ) / / t ur ns O FF c u rs o r { LCDsendCommand(0x0C); } void LCDblank( void ) / / b l a nk s L C D { LCDsendCommand(0x08); } void LCDvisible( void ) / / S h o ws L C D { LCDsendCommand(0x0C); } void L C D c u r so r L e f t ( u i n t 8_ t n ) // M o ve s c u rs o r b y n p o is i ti o ns l ef t { for ( u i n t 8 _t i = 0 ; i < n ; i + +) { LCDsendCommand(0x10); } } void L C D c u r s o rR i g h t ( u i n t 8_ t n ) / / M ov e s c u r s or b y n p o is i ti o ns l ef t { for ( u i n t 8 _t i = 0 ; i < n ; i + +) { LCDsendCommand(0x14); } } / / a d a p te d f r o m A V RL I B void L C D p r og r e s s Ba r ( u i n t 8 _ t p r og r es s , u i n t 8_ t m a x pr o g re s s , u i n t8 _ t length) { u i nt 8 _t i ;
37
u i n t1 6 _ t p i x e l pr o g r e ss ; u i nt 8 _t c ; // // // // //
d ra w a p r og r es s b ar d i sp l ay i ng ( p r o gr e ss / m a xp r og r es s ) s t ar t in g f ro m t he c u rr e nt c u rs or p o si t io n w it h a t ot al l en gt h of " l en gt h " c ha ra ct er s * ** n ot e , L CD c ha rs 0 -5 m us t b e p ro gr am me d a s t he b ar c ha ra ct er s char 0 = empt y ... char 5 = full
/ / t ot a l p i xe l l en g th o f b a rg r ap h e q ua l s l e ng t h * PROGRESSPIXELS_PER_CHAR; / / p ix el l en gt h o f b ar i ts el f i s p i x e l pr o g r e ss = ( ( p r o g re s s * ( l e n g th * P R O G R E S S P I X E L S _P E R _ C H AR ) ) / maxprogress );
/ / p ri n t e x ac t ly " l e ng th " c h ar a ct e rs for ( i = 0; i < l e ng t h ; i + +) { / / c he ck i f t hi s i s a f ul l b lo ck , o r p ar ti al o r e mp ty / / ( u 16 ) c as t i s n ee de d t o a vo id s ig n c om pa ri so n w ar ni ng if ( ( ( i * ( u i n t1 6 _ t ) P R O G R E S S P IX E L S _ P E R_ C H A R ) + 5 ) > p i x e lp r o g r es s ) { / / t hi s i s a p ar ti al o r e mp ty b lo ck if ( ( ( i * ( u i n t1 6 _ t ) P R O G R E S S P I XE L S _ P E R_ C H A R ) ) > p i x e lp r o g r es s ) { / / t hi s is a n e mp ty b lo ck / / u se s p ac e c h ar a ct e r ? c = 0; } else { / / t hi s is a p ar ti al b lo ck c = p i xe l pr o gr e ss % P R OG R E SS P I XE L S _P E R_ C H AR ; } } else { // t hi s is a f ul l b lo ck c = 5; } / / w ri t e c h ar a ct e r t o d i sp l ay LCDsendChar(c); } }
38
Ap´ endice B Librer´ıa para Teclado Matricial Hexadecimal
B.1.
keypad lib.h
/* * k e yp a d_ l ib . h * * C r ea t ed : 0 3 /0 2 /2 0 12 2 0 :1 2 :1 8 * A ut ho r : ni ko sa mu s */ #ifndef KEYPAD_LIB_H_ #define KEYPAD_LIB_H_ u n s i gn e d i n t KEYPADGetTeclaPresionada( void ); #endif / * K E YP A D_ L IB _ H_ * /
B.2.
keypad lib.c
/* * k e yp a d_ l ib . c * * C r ea d o : 0 3 /0 2 /2 0 12 2 0 :1 2 :0 5 * A ut o r : n i ko s am u s * */ #include #include #include #include
"keypad_lib.h" "hardwareConfig.h"
u n s i gn e d i n t KEYPADGetTeclaPresionada(){ u i n t 8_ t i n t N um e r o = 0 x 2 0 ; / / E nu m p ar a e v it a r n u me r os m a gi c os enum intElementos{ELE_0,ELE_1,ELE_2,ELE_3,E_FIN}; / / Px 0 , Px1 , P x2 y P x3 F il as : e nt ra da s e n a lt o ( p ul lu p a ct iv ad o ) / / Px 4 , Px5 , P x6 y P x7 C ol um na s : s al id as e n b aj o c o n f i g KE Y P A D _P O R T | = 0 x 0 F ; for ( u i nt 8 _t i n tC o lu m na = E L E _0 ; i n tC o lu m na ! = E _ FI N ; i n tC o lu m na + + ) { / / Po ng o e n b aj o t od os l os p in es configKEYPAD_REG&=(0x00); / / P on go e n a lt o l a c o lu m na s e le c ci o na d a / * C ol u mn a 0 : 0 00 1 0 00 0 C o lu m na 1 : 0 01 0 0 00 0
39
C o lu m na 2 : 0 10 0 0 00 0 C o lu m na 3 : 1 00 0 0 00 0 * / c on fi g KE YP AD _R EG | = ( 0 X 10 < < i n tC ol um na ) ; fo r ( u i nt 8 _t i n tF i la = E L E _0 ; i n tF i la ! = E _ FI N ; i n tF i la + + ) { / / Le o l a f il a s e le c ci o na d a / * F il a 0 : x xx x 0 00 1 F il a 1 : x xx x 0 01 0 F il a 2 : x xx x 0 10 0 F il a 3 : x xx x 1 00 0 * / if ( !( c o n f ig K E YP A D_ P IN & ( 0 x 01 < < i n tF i la ) ) ) { / / Ca lc ul o e l e nt er o ( de 0 a 1 5) i n t N um e r o = i n t C o l um n a + i n t F il a * 4 ; // Si e st a e nt re 10 y 15 a si gn o el c ar ac te r a sc ii e nt re A y F if (intNumero <0x9){ intNumero+=48; } e ls e i f(intNumero >0x9 && intNumero <0x10){ // Si e st a e nt re 0 y 9 a si gn o el c ar ac te r a sc ii e nt re 0 y 9 intNumero+=55; } return ( i n t N u m e r o ) ; } } } return 0 x 2 0 ; / / E sp a ci o . N o s e p r es i on o n i ng u na t e cl a }
40
Ap´ endice C Librer´ıa para Conversor Anal´ ogico Digital
C.1.
adc lib.h
/* * a d c_ l ib . h * * C r ea t ed : 0 4 /0 2 /2 0 12 2 0 :5 9 :0 0 * A ut ho r : ni ko sa mu s */ #ifndef ADC_LIB_H_ #define ADC_LIB_H_ / / E st r uc t ur a d e d at o s d e l a c o nv e rs i on t y p e de f s t r uc t { u i n t 8_ t P i n ; u i n t1 6 _ t V a l ue ; }ADCSample; void ADCInit( void ); A D C S am p l e A D C G e tS a m p l e ( u i n t8 _ t ) ; u i n t 16 _ t A D C G e tC o n v e r si o n ( void ) ; #endif / * A D C_ L IB _ H_ * /
C.2.
adc lib.c
/* * a d c_ l ib . c * * C r ea t ed : 0 4 /0 2 /2 0 12 2 0 :5 8 :3 4 * A ut ho r : ni ko sa mu s */ #include #include #include //Drivers #include " a d c _ l i b . h " //Configuracion #include " h a r d w a r e C o n f i g . h " / * I n i c i a li z a c i on d e l A D C * / void ADCInit( void ){ c o n f i gA D C _ P OR T & = ( 0 x 0 0 ) ;
41
c on fi gA DC _R EG & = (0 x 00 ) ; / / F ue n te d e v o lt a je e x te r na A DM UX & = (0 < < RE FS 1 ) | ( 0 << R EF S0 ) ; / / N o i n c ia r c o nv e r si o n , n o a u to t r ig g er , F L AG i n t er r u pc i o n , i n t e r ru p c i on d e s h a bi l i t a da A DC SR A & = ~ (1 < < A DS C ) | ~ (1 < < A DA TE ) | ~ (1 < < A DI F ) | ~ (1 < < A DI E ) ; / / H a bi l it a r A DC , P r ee s ca l er = 1 28 A DC SR A | = (1 < < AD EN ) | (1 < < A DP S2 ) | ( 1< < A DP S1 ) | (1 < < AD PS 0 ) ;
} / * To ma l a m ue st ra d el A DC y g en er a u n p ul so e n u n L ED p ar a c on tr ol * / A D C S am p l e A D C G e tS a m p l e ( u i n t8 _ t i n t In p u t ) { A D C S am p l e a d c s Sa m p l e ; u i n t 8_ t t m p = A D MU X ; / / S et e ar l a e n tr a da q ue q u er e mo s e n e l m u lt i pl e xo r tmp &= ~0 x1F ; t mp | = i n tI n pu t ; A D MU X = t mp ; / / I n i c ia r c o n v er s i o n A DC SR A |= 1 << A DS C; / / Po ne r e l n um er o d e e nt ra da e n la e st ru ct ur a d e d at os adcsSample.Pin=intInput; / / E sp e ra r a l f in d e c o nv e rs i on while ( A D CS R A & ( 1 < < AD SC ) ) { _delay_us(30); } / / Po ne r e l v al or d e l a c on ve rs io n e n l a e st ru ct ur a d e d at os adcsSample.Value=ADC; / / D ev o lv e r e s tr u ct u ra d e d at o s return adcsSample; }
42
Ap´ endice D Librer´ıa para Puerto Serie
D.1.
lib serial.h
/* F r ee R TO S V 7 . 0. 1 - C o py r ig h t ( C ) 2 01 1 R ea l T im e E n gi n ee r s L td .
********************************************************************* * * * FreeRTOS tutorial books are available in pdf and paperback . * * Co mp le te , re vi sed , an d ed it ed p df r ef er en ce m an ua ls a re a ls o * * available . * * * * Pu rc ha si ng Fr ee RTO S d oc um en ta ti on will not only help you , by * * ensuring you get running as quickly as possible and with an * * in - depth k now le dg e of how to use FreeRTOS , it will also help * * the F re eR TO S pr oj ec t to c on ti nu e wi th i ts m is si on of p ro vi di ng * * p r of es si on al g ra de , c ro ss p la tf or m , d e f ac to s ta nd ar d s ol ut io ns * * for microcontr ollers - completely free of charge ! * * * * > >> S ee ht tp : // w ww . F re eR TO S . or g / Do cu me nt at io n f or de ta il s . < << * * * * Than k you f or u sing F reeRTOS , a nd t hank y ou f or y our s up po rt ! * * * *********************************************************************
T hi s f il e i s p ar t o f t he F r ee R TO S d i st r ib u ti o n . F r ee R TO S i s f re e s o ft w ar e ; y ou c an r e di s tr i bu t e i t a nd / o r m o di fy i t u nd er t he t er ms of t he G NU G en er al P ub li c L ic en se ( v er si on 2 ) a s p u bl i sh e d b y t he F re e S o ft w ar e F o un d at i on A ND M O DI F IE D B Y t he F r ee R TO S exception. > >> NO TE < < < T he m od if ic at io n t o t he G PL i s i nc lu de d t o a ll ow y ou t o d i st r ib u te a c o mb i ne d w or k t ha t i n cl u de s F r ee R TO S w i th o ut b e in g o b li g ed t o p r ov i de t he s ou r ce c od e f or p r op r ie t ar y c o mp o ne n ts o u ts i de o f t he F re eR TO S k er ne l . F re eR TO S i s d i s tr ib ut ed i n t h e h op e t ha t i t w il l b e u se fu l , b ut W I TH O UT A NY W A RR A NT Y ; w i th o ut e ve n t he i m pl i ed w a rr a nt y o f M ER CH AN TA BI LI TY o r F IT NE SS F OR A P AR TI CU LA R P UR PO SE . S ee t he G NU G e ne r al P ub l ic L i ce n se f or m or e d e ta i ls . Y ou s h ou l d h av e r e ce i ve d a c op y o f t he G NU G e ne r al P ub l ic L i ce n se a nd t he F r ee R TO S l i ce n se e xc ep ti on a lo ng w it h F re eR TO S ; i f n ot i t c an b e v ie we d h er e : h tt p : // w w w . f re e rt o s . or g / a 00 1 14 . h t ml a nd a ls o o b ta i ne d b y w r it i ng t o R i ch a rd B ar ry , c o nt a ct d e ta i ls f or w ho m a re a v ai l ab l e o n t he F r ee R TO S W EB s it e . 1 t ab == 4 s pa ce s ! h t tp : / / w w w . F r e e R TO S . o r g - D o c um e n ta t i on , l a t es t i n f or m a ti o n , l i c en s e
43
a nd c o nt a ct d e ta i ls . h tt p : // w w w . S af e RT O S . co m - A v e rs i on t ha t i s c e rt i fi e d f or u se i n s a f et y c r i t ic a l s y s te m s . h t tp : / / w w w . O p e n R TO S . c o m - C o m m er c i a l s u pp o rt , d e v el o p me n t , p o rt i ng , l i ce n si n g a nd t r ai n in g s e rv i ce s . */ #ifndef LIB_SERIAL_H #define LIB_SERIAL_H #ifdef __cplusplus extern " C" { #endif #include / * C o ns t an t s f or w r it i ng t o U C SR 0 B . * / #define se rRX_INT_ENAB LE ( ( uint8_t #define serRX_ENABLE ( ( uint8_t ) #define serTX_ENABLE ( ( uint8_t ) #define se rTX_INT_ENAB LE ( ( uint8_t
) 0 x80 ) 0 x10 ) 0 x08 ) ) 0 x20 )
/ * C o ns t an t s f or w r it i ng t o U C SR 0 C . * / #define serU CSRC_SELECT ( ( uint8_t ) 0 x80 ) #define se rEIGHT_ DATA_BI TS ( ( uint8_t ) 0 x06 ) / * C on st an t f or z er o b lo ck t im e o n x Qu eu e * / #define xNoBlock ( ( uint8_t ) 0 x00 ) t y p e de f e n um { serCOM1 , serCOM2 , serCOM3 , serCOM4 , serCOM5 , serCOM6 , serCOM7 , serCOM8 } e C OM P or t ; t y p e de f e n um { serNO_PARITY , serODD_PARI TY , serEVEN_P ARITY , serMARK_P ARITY , serSPACE_PARITY } e P ar i ty ; t y p e de f e n um { serSTOP_1 , serSTOP_2 } e S to p Bi t s ; t y p e de f e n um { serBITS_5 , serBITS_6 ,
44
serBITS_7 , serBITS_8 } e D at a Bi t s ; t y p e de f e n um { ser50, ser75, ser110 , ser134 , ser150 , ser200 , ser300 , ser600 , ser1200 , ser1800 , ser2400 , ser4800 , ser9600 , ser192 00 , ser384 00 , ser576 00 , ser115200 } e Ba ud ;
t y p e de f v o id * x C o m P or t H a n dl e ; /* * C re at e a h an dl e r ef er en ce f or t he ( o nl y ) s er ia l p or t . * */ extern x C o m P o r t Ha n d l e x S e r ia l P o r t ; / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ / / x S er i al P ri n tf _ P ( P ST R ( "\ r \ n M es s ag e %u %u %u " ) , v ar 1 , v ar 2 , v ar 2 ) ; /* * * S e ri a l p r in t f . * @ p ar a m f o rm a t p r in t f f or m at s t ri n g . */ void xSerialPrintf( char * f o rm a t , . . .) ; /* * * S er ia l p ri nt f f ro m P RO GM EM t o t he s er ia l p or t . * @ p ar a m f o rm a t p r in t f f or m at s t ri n g . */ void x S e r i al P r i n tf _ P ( P G M _ P f o rm a t , . . .) ; /* * * P ri nt a c ha ra ct er s tr in g t o t he s er ia l p or t . * @ pa ra m s tr s tr in g t o p ri nt . */ void xSerialPrint( char * s tr ) ; /* * * P ri nt a c ha ra ct er s tr in g f ro m P RO GM EM t o t he s er ia l p or t . * @ pa ra m s tr s tr in g t o p ri nt . */ void x S e r i a l P ri n t _ P ( P G M _P s t r ) ; / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */
45
x C o m P or t H a n dl e x S e r i a l Po r t I n i tM i n i m a l ( u n s i gn e d l o ng ulWantedBaud , p o r t B AS E _ T Y PE u x T x Qu e u e Le n g t h , p o r t B AS E _ T Y PE u x R x Q ue u e L e ng t h ) ; void v S er i a l C lo s e ( x C o m P or t H a n d le x P o rt ) ;
/ / x C o m P or t H a n dl e x S e r i al P o r t I ni t ( e C O M Po r t e P or t , e B a ud e W a nt e d Ba u d , e P a r it y e W a nt e d Pa r i ty , e D a t aB i t s e W a nt e d D at a B i ts , e S t o pB i t s e W a n te d S t op B i ts , u n s i gn e d p o r t B AS E _ T Y PE u x B u f fe r L e n gt h ) ; / / v oi d v S e ri a lP u tS t ri n g ( x C om P or t Ha n dl e p xP or t , c o ns t s ig n ed c ha r * c o n st p c St r in g , u n s i gn e d s h o rt u s S t r in g L e n gt h ) ;
/ * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ /* * * I nt er ru pt d ri ve n r ou ti ne s t o i nt er fa ce t o I SR s er ia l p or t I O. * */ p o r t B AS E _ T Y PE x S e r i al G e t C ha r ( x C o m P o rt H a n d le p x Po r t , u i n t8 _ t * p c R x ed C h ar , p o rt T ic k Ty p e x B lo c kT i me ) ; p o r t B AS E _ T Y PE x S e r i al P u t C ha r ( x C o m P o rt H a n d le p x Po r t , u i n t8 _ t c O ut C ha r , p o r t Ti c k T y pe x B l o ck T i m e ) ;
/ * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ / / p o ll i ng w r it e a nd r ea d r ou ti ne s , f or u se b ef o re f r ee R TO S vTaskStartScheduler / / s am e a s a rg um en ts a nd f un ct io n as a bo ve , b ut d on t u se t he i n te r ru p ts .
'
void avrSerialPrintf( char * f o rm a t , . . .) ; void a v r S e ri a l P r i nt f _ P ( P G M _ P f o rm a t , . . .) ; void avrSerialPrint( char * s tr ) ; void a v r S e r i a lP r i n t _ P ( P G M _P s t r ) ; void a v r S e r i a l Wr i t e ( u i n t 8 _t D a t aO u t ) ; u i n t 8_ t a v r S e ri a l R e ad ( void ); u i n t 8_ t a v r S e r i al C h e c k R xC o m p l e t e ( void ); u i n t 8_ t a v r S e r i al C h e c k Tx R e a d y ( void ) ; / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */
#ifdef __cplusplus } #endif #endif
D.2.
lib serial.c
/* F r ee R TO S V 7 . 0. 1 - C o py r ig h t ( C ) 2 01 1 R ea l T im e E n gi n ee r s L td .
***************************************************************** * * * F re eR TO S t ut or ia l b oo ks a re a va il ab le i n p df a nd p ap er ba ck . * * C om pl et e , r ev is ed , a nd e di te d p df r ef er en ce m an ua ls a re a ls o *
46
* available . * * * * P u rc ha si ng F re eR TO S d o c um en ta ti on w il l n ot o nl y h e lp y ou , b y * * e ns ur in g y ou g et r u nn in g as q u ic kl y as p o ss ib le a n d wi th a n * * in - d ep th k no wl ed ge of h ow to u se F re eR TO S , it w il l a ls o h el p * * t he F r ee R TO S p r oj e ct t o c o nt i nu e w it h i ts m i ss i on o f p r ov i di n g * * p r o fe s si o na l g ra de , c ro s s p la tf or m , d e f a ct o s t an d ar d s o lu t io n s * * for microcontr ollers - completely free of charge ! * * * * > > > S ee h tt p : // w w w . F re e RT O S . or g / D o cu m en t at i on f or d e ta i ls . < < < * * * * T ha nk y ou f or u si ng F re eR TO S , a nd t ha nk y ou f or y ou r s up po rt ! * * * *****************************************************************
T hi s f il e i s p ar t o f t he F r ee R TO S d i st r ib u ti o n . F r ee R TO S i s f re e s o ft w ar e ; y ou c an r e di s tr i bu t e i t a nd / o r m o di fy i t u nd er t he t er ms of t he G NU G en er al P ub li c L ic en se ( v er si on 2 ) a s p u bl i sh e d b y t he F re e S o ft w ar e F o un d at i on A ND M O DI F IE D B Y t he F r e e RT O S e x c e pt i o n . > >> NO TE < < < T he m od if ic at io n t o t he G PL i s i nc lu de d t o a ll ow y ou t o d i st r ib u te a c o mb i ne d w or k t ha t i n cl u de s F r ee R TO S w i th o ut b e in g o b li g ed t o p r ov i de t he s o ur c e c od e f or p r op r ie t ar y c o mp o ne n ts o u ts i de o f t h e F re eR TO S k er ne l . F re eR TO S is d is tr ib ut ed i n t h e h op e t ha t i t w il l b e u se fu l , b ut W I TH O UT A NY W A RR A NT Y ; w i th o ut e ve n t he i m pl i ed w a rr a nt y o f M E RC H AN T AB I LI T Y o r F I TN E SS F OR A P A RT I CU L AR P U RP O SE . S ee t he G NU G en er al P ub li c L ic en se f or m or e d et ai ls . Y ou s ho ul d h av e r ec ei ve d a c op y o f t he G NU G en er al P ub li c L ic en se a nd t he F re eR TO S l ic en se e xc ep ti on a lo ng w it h F re eR TO S ; i f n ot i t c an b e v ie we d h er e : h tt p : // w w w . f re e rt o s . or g / a 00 1 14 . h t ml a nd a ls o o b ta i ne d b y w r it i ng t o R i ch a rd B ar ry , c o nt a ct d e ta i ls f or w ho m a re a v ai l ab l e o n t he F r ee R TO S W EB s it e . 1 t ab == 4 s pa ce s ! h t tp : / / w w w . F r e e R TO S . o r g - D o c um e n ta t i on , l a t es t i n f or m a ti o n , l i c en s e a nd c o nt a ct d e ta i ls . h tt p : // w w w . S af e RT O S . co m - A v e rs i on t ha t i s c e rt i fi e d f or u se i n s a f et y c r i t ic a l s y s te m s . h t tp : / / w w w . O p e n R TO S . c o m - C o m m er c i a l s u pp o rt , d e v el o p me n t , p o rt i ng , l i c e ns i n g a n d t r a i ni n g s e r v ic e s . */ /* C h an g es f ro m V 1 . 2. 3 + T he f u nc t io n x P o rt I ni t Mi n im a l ( ) h as b ee n r e na m ed t o x S e ri a l Po r t In i tM i n im a l ( ) a nd t he f u nc t io n x P or t In i t () h as b ee n r e n am e d t o x S e r i al P o r t I ni t ( ) . C h an g es f ro m V 2 . 0. 0 + D e la y p e ri o ds a re n ow s p ec i fi e d u si n g v a ri a bl e s a nd c o ns t an t s o f p o rt T ic k Ty p e r a th er t ha n u n si g ne d l on g . + x Q u eu e Re c e iv e F ro m IS R ( ) u se d i n p l ac e o f x Q ue u eR e ce i ve ( ) w i th i n t he I SR . C h an g es f ro m V 2 . 6. 0
47
+ R e pl a ce d t he i nb ( ) a nd o ut b ( ) f u nc t io n s w it h d i re ct m e mo r y a cc es s . T hi s a ll ow s t he p or t to b e b u il t w it h t he 2 00 50 41 4 b ui ld o f W i nA V R . */ / * B AS IC I N TE R RU P T D R IV E N S E RI A L P OR T D R IV E R . */ / * A ls o w it h p o ll i ng s e ri al f un ct io n s , f or u se b ef o re s c he d ul e r i s enabled*/
#include #include #include #include #include #include #include #include #include #include #include
/ * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ / * n i k o sa m u s : P o rt A T M E GA 3 2 * R e e mp l az o d e U CS R 0B p or U C SR B */ #define vInterruptOn () \ { \ uint8_t ucByte ; \ ucByte = UCSRB ; \ ucByte |= serTX_INT_EN ABLE ; \ UCSRB = ucByte ; \ } / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U CS R0 B p or U CS RB */ #define vInterruptOff () \ { \ uint8_t ucByte ; \ \ ucByte = UCSRB ; \ ucByte &= ~ serTX _INT_ENABLE ; UCSRB = ucByte ; \ }
\
static x Q u e u e Ha n d l e x R x e dC h a r s ; static x Q u e u e Ha n d l e x C h a rs F o r T x ; / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - * / / / x S er i al P ri n tf _ P ( P ST R ( "\ r \ n M es s ag e %u %u %u " ) , v ar 1 , v ar 2 , v ar 2 ) ; void xSerialPrintf( char * f o rm a t , . . .) {
48
v a _ l is t a r g ; char temp[80]; v a _ st a r t ( a rg , f o r ma t ) ; v s n p ri n t f ( t em p , 8 0 , f o rm a t , a r g ) ; xSerialPrint(temp); va_end(arg); } void x S e r i al P r i n tf _ P ( P G M _ P f o rm a t , . . .) { v a _ l is t a r g ; char temp[80]; v a _ st a r t ( a rg , f o r ma t ) ; v s n p ri n t f _ P ( t em p , 8 0 , f o rm a t , a r g ) ; xSerialPrint(temp); va_end(arg); } void xSerialPrint( char * s tr ) { i nt 16 _t i = 0; s i z e_ t s t r i ng l e n g th ; s t r i n gl e n g th = s t r le n ( s t r ) ; while ( i < s t ri n gl e ng t h ) x S e r i al P u t C ha r ( x S e ri a l Po r t , s t r [ i ++ ] , x N o B lo c k ) ; } void x S e r i a l P ri n t _ P ( P G M _P s t r ) { u in t1 6_ t i = 0 ; s i z e_ t s t r i ng l e n g th ; s t r i n gl e n g th = s t r l en _ P ( s t r ) ; while ( i < s t ri n gl e ng t h ) x S e r i al P u t C ha r ( x S e ri a l Po r t , p g m _ r ea d _ b y te ( & s t r [ i + + ] ) , x N o B lo c k ) ; } / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ p o r t B AS E _ T Y PE x S e r i al G e t C ha r ( x C o m P o rt H a n d le p x Po r t , u i n t8 _ t * p c R x ed C h ar , p o rt T ic k Ty p e x B lo c kT i me ) { / * O nl y o ne p or t i s s up po rt ed . * / ( void ) p x Po rt ; / * G et t he n ex t c ha ra ct er f ro m t he b uf fe r . R et ur n f al se i f n o characters a re a va i la bl e , o r a r ri ve b e fo r e x B lo c kT i me e x pi r es . * / if ( x Q u e u eR e c e i ve ( x R xe d C ha r s , p c R xe d C ha r , x B l o ck T i m e ) ) { return pdTRUE; } else { return pdFALSE; } }
49
p o r t B AS E _ T Y PE x S e r i al P u t C ha r ( x C o m P o rt H a n d le p x Po r t , u i n t8 _ t c O ut C ha r , p o r t Ti c k T y pe x B l o ck T i m e ) { / * O nl y o ne p or t i s s up po rt ed . * / ( void ) p x Po rt ;
/ * R et ur n f al se i f a ft er t he b lo ck t im e t he re i s n o r oo m o n t he T x q u eu e . * / if ( x Q ue u e Se n dT o Ba c k ( x C ha r sF o rT x , & c O ut Ch ar , x B lo c kT i me ) ! = p dP A SS ) { return pdFAIL; }
vInterruptOn(); return pdPASS; } / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U BR R0 L p or U BR RL , U BR R0 H p or U BR RH y U CS R0 C p or U CS RC */ x C o m P or t H a n dl e x S e r i a l Po r t I n i tM i n i m a l ( u n s i gn e d l o ng ulWantedBaud , p o r t B AS E _ T Y PE u x T x Qu e u e Le n g t h , p o r t B AS E _ T Y PE u x R x Q ue u e L e ng t h ) { u n s i gn e d l o ng ulBaudRateCounter; u i n t 8_ t u c B yt e ;
portENTER_CRITICAL(); { / * C re at e t he q ue ue s u se d b y t he s er ia l c om mu ni ca ti on s t as k . * / x R x e dC h a r s = x Q u e u eC r e a t e ( u x R xQ u e u eL e n g th , ( p o r t B AS E _ T Y PE ) sizeof ( p or tB AS E_ TY PE ) ) ; x C h a rs F o r T x = x Q u e ue C r e a te ( u x T x Qu e u e Le n g t h , ( p o r t B AS E _ T Y PE ) sizeof ( p or tB AS E_ TY PE ) ) ;
//
/ * C al cu la te t he b au d r at e r eg is te r v al ue f ro m t he e qu at io n i n t he d at a s he e t . * / u lB au dR at eC ou nt er = ( c on fi gC PU _C LO CK _H Z / ( u lW an te dB au d * 16 UL ) 1; / / A t A r du i no 1 6 MH z ; a bo v e d at a s he e t c a lc u la t io n i s w ro n g . N e e d b e l ow f r om < u t il / s e t b a u d . h > u l Ba u d Ra t eC o u nt e r = ( ( c o nf i gC P U _C L OC K _H Z + u l Wa n te d Ba u d * 8 U L ) / ( u lW an te dB au d * 1 6 UL ) - 1 );
/* S et t he b au d r at e. */ u cB yt e = ( u in t8 _t ) ( u lB au d Ra te Co un t er & ( u n s ig n e d l o ng ) 0 xff ) ; U B RR L = u c By t e ; u l B a u d Ra t e C o u nt e r > > = ( u n s i gn e d l o ng ) 8; u cB yt e = ( u in t8 _t ) ( u lB au d Ra te Co un t er & ( u n s ig n e d l o ng ) 0 xff ) ; U B RR H = u c By t e ; / * E n ab le t he R x i n t er ru pt . T he T x i nt er ru pt w il l g et e na bl ed l at er . A ls o e na bl e t he R x a nd Tx . * / U C SR B = ( s e rR X _I N T_ E N AB L E | s e rR X _E N AB L E | s e rT X _E N AB L E ) ; /* S et t he d at a b it s to 8. */ U C SR C = ( s e rU C SR C _S E LE C T | s e rE I GH T _ DA T A_ B I TS ) ;
50
} portEXIT_CRITICAL(); / * U nl ik e o th er p or ts , t hi s s er ia l c od e d oe s n ot a ll ow f or m or e t ha n one c om p or t. We t he re fo re do n t r et ur n a p oi nt er t o a p or t s tr uc tu re a nd can i n st e ad j us t r et u rn N UL L . * / return NULL;
'
} / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U CS R0 B p or U CS RB */ void v S er i a l C lo s e ( x C o m P or t H a n d le x P o rt ) { u i n t 8_ t u c B yt e ; / * T he p ar am et er i s n ot u se d . * / ( void ) x Po rt ; / * T u rn o ff t he i nt er ru pt s . W e m ay a ls o w an t t o d el et e t he q ue ue s a nd / or re - i n s ta l l t he o r ig i na l I SR . * / portENTER_CRITICAL(); { vInterruptOff(); u c By t e = U C SR B ; u c B yt e & = ~ s e r R X _ IN T _ E N AB L E ; U C SR B = u c By t e ; } portEXIT_CRITICAL(); } / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ / / p o ll i ng r ea d a nd w r it e r ou ti ne s , f or u se b ef o re f r ee R TO S vTaskStartScheduler / / s am e a s a bo ve , b ut d oe sn t u se i n te r ru p ts . '
void avrSerialPrintf( char * f o rm a t , . . .) { v a _ l is t a r g ; char temp[80]; v a _ st a r t ( a rg , f o r ma t ) ; v s n p ri n t f ( t em p , 8 0 , f o rm a t , a r g ) ; avrSerialPrint(temp); va_end(arg); } void a v r S e ri a l P r i nt f _ P ( P G M _ P f o rm a t , . . .) { v a _ l is t a r g ; char temp[80]; v a _ st a r t ( a rg , f o r ma t ) ; v s n p ri n t f _ P ( t em p , 8 0 , f o rm a t , a r g ) ; avrSerialPrint(temp); va_end(arg); }
51
void avrSerialPrint( char * s tr ) { u in t1 6_ t i = 0 ; s i z e_ t s t r i ng l e n g th ; s t r i n gl e n g th = s t r le n ( s t r ) ; while ( i < s t ri n gl e ng t h ) avrSerialWrite(str[i++]); } void a v r S e r i a lP r i n t _ P ( P G M _P s t r ) { int i = 0; s i z e_ t s t r i ng l e n g th ; s t r i n gl e n g th = s t r l en _ P ( s t r ) ; while ( i < s t ri n gl e ng t h ) avrSerialWrite(pgm_read_byte(&str[i++])); } / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U DR 0 p or U DR */ void a v r S e r i a l Wr i t e ( u i n t 8 _t D a t aO u t ) { while ( ! a v r S e r i a lC h e c k T x Re a d y ( ) ) / / wh il e N OT r e ad y to t r an sm it _delay_ms(1); / / d el a y U DR = D a ta O ut ; } / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U DR 0 p or U DR */ u i n t 8_ t a v r S e ri a l R e ad ( void ) { while ( ! a v r S e r i a l Ch e c k R x C om p l e t e ( ) ) / / W hi le d at a i s N O T a v ai la bl e t o r ea d _delay_ms(1); / / d e la y return UDR; } / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U CS R0 A p or U CS RA y R XC 0 p or R XC */ u i n t 8_ t a v r S e r i al C h e c k R xC o m p l e t e ( void ) { return ( UCSR A & (1 << RXC ) ) ; / / n on ze ro if se ri al da ta is a v ai l ab l e t o r ea d . } / * n i k o sa m u s : P o rt A T M E GA 3 2 * R ee mp la zo d e U CS R0 A p or U CS RA y U DR E0 p or U DR E */ u i n t 8_ t a v r S e r i al C h e c k Tx R e a d y ( void ) { return ( UCSR A & (1 << UDRE ) ) ; / / no n ze r o if t r an s mi t r e gi s te r is r e ad y t o r e ce i ve n ew d at a . }
/ * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ # i f d e f in e d ( _ _ A V R _ A T m e ga 6 4 0 _ _ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 0 __ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 1 _ _ ) | | defined ( _ _ A V R _ A T m e ga 2 5 6 0 _ _ ) | | defined (
52
__AVR_ATmega2561__) I SR ( U S AR T 0_ R X_ v ec t ) # e l i f d e f in e d ( _ _ A VR _ A Tm e ga 3 2 4P _ _ ) | | defined ( _ _ A V R _ A T m e g a 6 4 4 P _ _ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 4 P __ ) | | defined ( _ _ A V R _ A T m e ga 3 2 4 P A __ ) | | defined ( _ _ A V R _ A T m e g a 6 4 4 P A _ _ ) I SR ( U S AR T 0_ R X_ v ec t ) # e l i f d e f in e d ( _ _ A V R _ A T m eg a 1 6 8 __ ) | | defined ( _ _ A V R _ A T m e g a 3 2 8 P _ _ ) I SR ( U S AR T _R X _v e ct ) / * n i k o sa m u s : P o rt A T M E GA 3 2 * E s pe c if i ca c io n d e l a R SI p ar a A T ME G A3 2 * R ee mp la zo d e U DR 0 p or U DR */ # e l i f d e f in e d ( _ _ A V R _ A T m e g a 3 2 _ _ ) I SR ( U S AR T _R X C_ v ec t ) #endif { u i n t 8_ t c C ha r ; signed p o r t BA S E _ T YP E x H i g h e rP r i o r i t yT a s k W o k en = p d F AL S E ;
/ * G et t he c ha ra ct er a nd p os t i t o n t he q ue ue o f R xe d c ha ra ct er s . I f t he p os t c au se s a t as k t o w ak e f or ce a c on te xt s wi tc h a s t he a wo ke n task may have a higher priority than the task we have interrupted . */ c Ch ar = U DR ; x Q u e u e S en d T o B a ck F r o m I S R ( x R x ed C h ar s , & c C ha r , & x H i g h e r P r i o ri t y T a s k Wo k e n );
if ( x H i gh e r Pr i o ri t y Ta s k Wo k e n ! = p d FA L SE ) { taskYIELD(); } } / * - - - - - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - -- - - - - - - - - - - -- - - - - - - - - - */ # i f d e f in e d ( _ _ A V R _ A T m e ga 6 4 0 _ _ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 0 __ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 1 _ _ ) | | defined ( _ _ A V R _ A T m e ga 2 5 6 0 _ _ ) | | defined ( __AVR_ATmega2561__) I SR ( U S AR T 0_ U DR E _ ve c t ) # e l i f d e f in e d ( _ _ A VR _ A Tm e ga 3 2 4P _ _ ) | | defined ( _ _ A V R _ A T m e g a 6 4 4 P _ _ ) | | defined ( _ _ A V R _ A T m e ga 1 2 8 4 P __ ) | | defined ( _ _ A V R _ A T m e ga 3 2 4 P A __ ) | | defined ( _ _ A V R _ A T m e g a 6 4 4 P A _ _ ) I SR ( U S AR T 0_ U DR E _ ve c t ) # e l i f d e f in e d ( _ _ A V R _ A T m eg a 1 6 8 __ ) | | defined ( _ _ A V R _ A T m e g a 3 2 8 P _ _ ) I SR ( U S AR T _U D RE _ ve c t ) / * n i k o sa m u s : P o rt A T M E GA 3 2 * E s pe c if i ca c io n d e l a R SI p ar a A T ME G A3 2 * R ee mp la zo d e U DR 0 p or U DR */ # e l i f d e f in e d ( _ _ A V R _ A T m e g a 3 2 _ _ ) I S R ( U S A R T _U D R E _ ve c t ) #endif { u i n t 8_ t c C ha r ; i n t 8_ t c T a s kW o k e n ;
if ( x Q u eu e R ec e iv e F ro m IS R ( x Ch a rs F or T x , & c Ch ar , & c T a sk W ok e n ) = = p d TR U E ) { / * S en d t he n ex t c ha ra ct er q ue ue d f or T x. * / U DR = c Ch ar ; }
53
else { / * Q ue ue e mp ty , n ot hi ng t o s en d . * / vInterruptOff(); } }
54
Ap´ endice E Librer´ıa para LEDs
E.1.
led lib.h
/* * l e d_ l ib . h * * C r ea t ed : 0 6 /0 2 /2 0 12 1 8 :3 0 :1 3 * A ut ho r : ni ko sa mu s */
#ifndef LED_LIB_H_ #define LED_LIB_H_ #include " h a r d w a r e C o n f i g . h " void LEDInit( void ); void LEDToggle(uint8_t); #endif / * L E D_ L IB _ H_ * /
E.2.
led lib.c
/* * l e d_ l ib . c * * C r ea t ed : 0 6 /0 2 /2 0 12 1 8 :3 0 :0 0 * A ut ho r : ni ko sa mu s */ #include #include #include " h a r d w a r e C o n f i g . h " / / I n ci a li z ac i on d el p u er to d e L ED s void LEDInit( void ){ configLED_REG=0xFF; configLED_PORT=0x00; } / / I nv e rt i r e l v al o r d el p in s e le c ci o na d o c on u na X OR void L E D T o g gl e ( u i n t 8 _ t i n t Le d ) { c o n f i g LE D _ P O RT ^ =( 1 < < i n t Le d ) ; }
55
Ap´ endice F Librer´ıa para Botones
F.1.
boton lib.h
/* * b o to n _l i b . h * * C r ea t ed : 0 9 /0 2 /2 0 12 1 8 :1 4 :3 8 * A ut ho r : ni ko sa mu s */ #ifndef BOTON_LIB_H_ #define BOTON_LIB_H_ void BOTONInit( void ) ; u i n t 8_ t B O T O N Ch e c k P in ( u i n t8 _ t ) ; #endif / * B O TO N _L I B_ H _ * /
F.2.
boton lib.c
/* * b o to n _l i b . c * * C r ea t ed : 0 7 /0 2 /2 0 12 1 8 :1 4 :1 5 * A ut ho r : ni ko sa mu s */ #include #include #include " b o t o n _ l i b . h " #include " h a r d w a r e C o n f i g . h " / / I n i c i a li z a c i on d e l p u e rt o void BOTONInit( void ) { / / P ue r to d e b o to n es c om o s a li d a c o nf i gB O T ON _ RE G = 0 x 00 ; / / A c t iv o P u l l up s i n t e rn o s c o n f i g BO T O N _ PO R T = 0 x F F ; } / / D ev o lv e r e l e s ta d o d el p in c o ns u lt a do u i n t 8_ t B O T O N Ch e c k P in ( u i n t8 _ t i n t Pi n ) { return ! ( c o n f i g B O TO N _ P I N & (1 < < i n t Pi n ) ) ; }
56