Está en la página 1de 47

Curso introductorio a la

arquitectura ARM con


Cortex M4

Microcontrolador STM32F407VG
Realizado y editado por:

` Calle Urquiza 1695 Gch. (Entre Ros)


(2820) ARGENTINA
e-mail: informes@firtec.com.ar
consultas@firteconline.com.ar

Revisin: Marzo 2017

2
ndice de contenido
Prologo.......................................................................................................................................................5
Capitulo I....................................................................................................................................................6
Historia de la Arquitectura ARM...........................................................................................................6
Que es Cortex M4..................................................................................................................................8
Algunos detalles del STM32F407VG...................................................................................................9
Caractersticas heredadas de RISC......................................................................................................11
Algunas ventajas de RISC...................................................................................................................11
Desventajas de RISC...........................................................................................................................11
Bus AMBA..........................................................................................................................................11
Pipeline................................................................................................................................................12
FPU......................................................................................................................................................14
ARM y Thumb....................................................................................................................................14
Modos de Funcionamiento..................................................................................................................14
Modo usuario (Thread ).......................................................................................................................15
Modos de Privilegios (Handler)..........................................................................................................15
El sistema de memoria ARM...............................................................................................................16
Que es CMSIS.....................................................................................................................................18
Caractersticas de la placa entrenadora................................................................................................21
Configurando el entorno de trabajo.....................................................................................................26
Puedo programar el microcontrolador sin un programador especfico?.............................................30
Mi Primer Programa en KEIL.............................................................................................................31
Capitulo II................................................................................................................................................41
Interrupciones......................................................................................................................................41
Temporizador del sistema (SysTick)...................................................................................................48
Funcionamiento de la USART.............................................................................................................57
Conversor Analgico con STM32F407VG.........................................................................................64
Capitulo III...............................................................................................................................................67
Pantalla LCD 16x2 con STM32..........................................................................................................67
Voltmetro con pantalla LCD 16x2.................................................................................................69
Midiendo la temperatura del Ncleo Cortex..................................................................................71
Canales DMA......................................................................................................................................77
Modo DMA de doble buffer................................................................................................................90
Emular memoria EEPROM en FLASH..............................................................................................90
Protocolo I2C......................................................................................................................................93
Sensor para medir Temperatura y Humedad HDC1000....................................................................103
Driver para el sensor HDC1000...................................................................................................104
Sensor Baromtrico LPS25HB..........................................................................................................110
Driver para el sensor LPS25HB....................................................................................................114
Sensor BME280 (Todo en uno).........................................................................................................119
Impresoras Trmicas.........................................................................................................................121
Puerto SDIO con STM32..................................................................................................................123
Memoria SD con FAT........................................................................................................................128
Ejemplo de manejo de FAT con STM32.......................................................................................135
Creando un disco extrable a partir de una memoria SD..............................................................139
Control PID.......................................................................................................................................141

3
Funcionamiento general de un PID..............................................................................................142
Control PID con STM32F407......................................................................................................142
Datalogger de temperatura................................................................................................................147
Capitulo IV.............................................................................................................................................154
FSMC (Flexible Static Memory Controller)....................................................................................154
Pantallas TFT................................................................................................................................154
Que es RFID.................................................................................................................................161
Origen de los RFID.......................................................................................................................161
Frecuencias en distintos pases.....................................................................................................161
Cantidad de informacin almacenada en una etiqueta de RFID...................................................162
Etiquetas de lectura y lectura/escritura.........................................................................................162
Etiquetas pasiva y etiquetas activas.............................................................................................162
Colisin entre tarjetas...................................................................................................................162
Modo lector denso........................................................................................................................163
Tags pasivos usados en el ejemplo...............................................................................................163
Receptor RFID CR95HF...............................................................................................................164
Comandos del CR95HF................................................................................................................166
Hardware usado en el proyecto.....................................................................................................176
Driver para RFID CR95HF...........................................................................................................178
Sensor de imagen OV7670 con STM32F407...............................................................................186
Formato de la imagen...................................................................................................................187
RGB..............................................................................................................................................187
Seales de la cmara.....................................................................................................................189
SCCB (Serial Camera Control Bus).............................................................................................191
Estructura del proyecto DCMI_OV7670......................................................................................193
Manejo del Touch-Screen.............................................................................................................196
Protocolo 1-wire................................................................................................................................202
Niveles elctricos del bus.............................................................................................................202
Envo y recepcin de datos...........................................................................................................203
Ejemplo con 1-Wire y el sensor DS18B20 & UART...................................................................203
Ejemplo con 1-Wire y el sensor DS18B20 & LCD TFT..............................................................207
Ethernet y MII (Media Independent Interface).................................................................................210
Seales del transmisor Ethernet....................................................................................................210
Seales del receptor Ethernet........................................................................................................210
Reduccin Media Independent Interface (RMII)..........................................................................211
El stackt LwIP controlando LEDs mediante CGI.......................................................................213
SSI (Server Side Include).............................................................................................................217
Que es un socket?.........................................................................................................................220
Capturando paquetes con LwIP....................................................................................................221
Wi-Fi con ESP8266......................................................................................................................227
Enviando datos con ESP8266.......................................................................................................230
Sensor OPT3001................................................................................................................................236
CAN BUS ( Controller Area Network).............................................................................................239
CAN BUS Loop Back (Sin la capa fsica)....................................................................................241
CAN NORMAL (Con la capa fsica)...........................................................................................248
Bibliografa............................................................................................................................................256

4
Capitulo I.
Historia de la Arquitectura ARM.
ARM es una empresa presente en el mercado desde 1990 y que ha logrado en estos pocos aos colocar
productos de consumo global diseando una arquitectura que lidera a escala mundial en 32 bits.
Concebida originalmente por Acorn Computers para uso en computadoras, los primeros productos
basados en ARM fueron los Acorn Archimedes lanzados en 1987.
La relativa simplicidad de los procesadores ARM los ha convertido en la tecnologa dominante en el
mercado de la electrnica mvil integrada, microprocesadores y microcontroladores pequeos, de bajo
consumo y relativamente bajo costo. En la actualidad alrededor del 98% de los telfonos mviles
vendidos cada ao utilizan al menos un procesador ARM.
Desde 2009, los procesadores ARM son aproximadamente el 90% de todos los procesadores RISC de
32 bits que se utilizan en la electrnica de consumo, incluyendo PDA, Tablets, Telfonos
inteligente,videoconsolas, calculadoras, reproductores digitales de msica y medios (fotos, vdeos,
etc.), y perifricos de computadoras como discos duros y routers.
La arquitectura ARM es licenciable. Las empresas que son titulares de licencias ARM actuales o
anteriores incluyen a empresas como Alcatel-Lucent, Apple Inc., AppliedMicro, Atmel, Broadcom,
Cirrus Logic, Digital Equipment Corporation, Ember, Energy Micro, Freescale, Intel, LG,Marvell
Technology Group, Microsemi, Microsoft, NEC, Nintendo, Nokia , Nuvoton, Nvidia, Sony, NXP (antes
Philips), Oki, ON Semiconductor, Psion, Qualcomm, Samsung, Sharp, STMicroelectronics, Symbios
Logic, Texas Instruments, VLSI Technology, Yamaha, y ZiiLABS.
ARM solo desarrolla la arquitectura pero no fabrica chips, estos son fabricados por otras empresas que
licencian esta arquitectura.
El origen de ARM se remonta a 1983 como un proyecto de desarrollo en la empresa Acorn Computers
cuya meta era, originalmente, el desarrollo de un procesador avanzado, pero con una arquitectura
similar a la del MOS 6502.
La razn era que Acorn tena una larga lnea de computadoras basados en ese micro.
El equipo termin el diseo preliminar y los primeros prototipos del procesador en el ao 1985, al que
llamaron ARM1. La primera versin utilizada comercialmente se bautiz como ARM2 y se lanz al
mercado en el ao 1986.
La arquitectura del ARM2 posee un bus de datos de 32 bits y ofrece un espacio de direcciones de 26
bits, junto con 16 registros de 32 bits. Uno de estos registros se utiliza como contador de programa,
aprovechndose sus 4 bits superiores y los 2 inferiores para contener las banderas del propio
procesador.
El ARM2 es probablemente el procesador de 32 bits til ms simple del mundo, ya que posee slo
30.000 transistores. Su simplicidad se debe a que no est basado en microcdigo (sistema que suele
ocupar la cuarta parte de la cantidad total de transistores usados en un procesador) y a que, como era
comn en aquella poca, no incluye cach. Gracias a esto, su consumo en energa es bastante bajo, a la
vez que ofrece un mejor rendimiento que un 286.
Su sucesor, el ARM3, incluye una pequea memoria cach de 4 KB, lo que mejora los accesos a
memoria repetitivos.
A finales de los aos 80 Apple Computer comenz a trabajar con Acorn en nuevas versiones del ncleo
ARM.

6
Caractersticas heredadas de RISC.
La arquitectura ARM incorpor algunas caractersticas del diseo RISC de Berkeley, aunque no todas.
Las que se mantuvieron son:
Arquitectura de carga y almacenamiento(load-store). Las instrucciones que acceden a memoria
estn separadas de las instrucciones que procesan los datos, ya que en este ltimo caso los datos
necesariamente estn en registros.
Instrucciones de longitud fija de 32 bits. Campos de instrucciones uniforme y de longitud fija
para simplificar la decodificacin de las instrucciones.
Formatos de instruccin de 3 direcciones. Consta de f bits para el cdigo de operacin, n
bits para especificar la direccin del 1er. operando, n bits para especificar la direccin del
2do. operando y n bits para especificar la direccin del resultado (el destino).

Algunas ventajas de RISC.


Menor desperdicio de rea de silicio. Un procesador simple economiza transistores y rea de
silicio. En consecuencia una CPU RISC deja mayor rea libre para realizar mejoras de
rendimiento, tales como, memoria cach, funciones de manejo de memoria, punto flotante por
hardware,etc.
Menor tiempo de desarrollo. Un procesador simple tiene menor costo y lleva menos esfuerzo de
diseo, se adapta mejor a sistemas de tecnologa de procesos.
Mayor rendimiento. Si se disea un procesador simple y luego se le agregan instrucciones
complejas har en forma ms eficiente varias funciones de alto nivel pero tambin decaer un
poco el reloj para el conjunto de las instrucciones. Midiendo los beneficios de esta tcnica en
programas tpicos se comprueba que todos los sets de instrucciones complejos hacen que el
programa corra a menor velocidad.

Desventajas de RISC.
No ejecuta cdigos x86.Pero hay programas de emulacin para varias plataformas RISCs.
Pobre densidad de cdigo. Comparada con CISC. sto es consecuencia del set de instrucciones
de longitud fija. En ausencia de memoria cach, esta pobre densidad de cdigo significa que la
bsqueda de la instruccin necesita un aumento del ancho de banda de la memoria principal,
dando por resultado un mayor consumo.

Bus AMBA.
El significado de esta sigla es Advanced Microcontroller Bus Architecture. La misma se refiere a un
standard de facto, abierto, que facilita la interconexin de bloques de propiedad intelectual para formar
Sistemas On Chip, es decir, circuitos integrados formados por varios procesadores y perifricos,
interconectados en un bus comn. Los procesadores ARM utilizan esta arquitectura para interconexin
de los diferentes bloques internos que forman el chip.

Podemos ver en el grfico anterior que en el procesador hay tres buses con tres velocidades distintas.
AHB1 corriendo a 168Mhz.
APB2 corriendo a 84Mhz.
APB1 corriendo a 42Mhz.

11
Esto ltimo es muy importante porque marca una de las grandes diferencias con un microcontrolador
de 8 bits o de arquitectura tradicional en donde podemos tener la certeza de que cada operacin dura
un determinado tiempo o ciclo de CPU lo que lleva a que los tiempos en juego se pueden determinar
con facilidad. En un micro de 32 bits hay varios buses y los tiempos ya no son tan fciles de predecir ya
que otros perifricos pueden estar usando estos buses o si el micro tiene memoria cache esto altera los
tiempos en juego por lo que debe usted desterrar la idea que solo basta con contar las instrucciones y
multiplicar por la velocidad del bus.
Lo siguiente que puede resultar un poco confuso es que todo dentro del Cortex tiene su reloj individual
que por defecto esta desconectado.
Es decir entonces que para hacer uso de un mdulo una de las configuraciones que debemos incluir es
activar y el reloj y determinar una frecuencia de operacin dentro del rango que el bus admite.

Pipeline.
Se llama pipeline a la tcnica que aprovecha un mtodo para optimizar los recursos de hardware y
tambin el rendimiento del procesador.
Consiste en comenzar a procesar una instruccin antes de que se haya finalizado de procesar la actual.
En la siguiente figura se ilustra la ejecucin de instrucciones con la tcnica pipeline.

Tomando la secuencia de operaciones a partir de la instruccin 1, el procesador se organiza de tal


manera que tan pronto como haya completado la primera etapa de esa instruccin, fetch y haya
avanzado hacia la segunda etapa, comenzar la primera etapa, fetch, de la prxima instruccin. En
principio, de esta manera el tiempo de ejecucin debera ser hasta seis veces ms veloz que el que
corresponde a instrucciones no superpuestas pero, como veremos luego, en la prctica no ocurre as.
Una de las caractersticas clave del alto desempeo de los microcontroladores ARM es el pipeline.
ARM7 tiene un pipeline de tres etapas que aumentan el flujo de instrucciones a travs del procesador.
As que cada instruccin se ejecuta en tres etapas:

1) Recoger: Se lee la instruccin de la memoria y se coloca en el pipeline


2) Decodificar: Se decodifica la instruccin.
3) Ejecutar: Se ejecuta la instruccin.

12
El pipeline se implementa en el nivel de hardware. Pipeline es lineal, lo que significa que el procesador
ejecuta una instruccin mientras est cargando otra para ser decodificada. Si bien esto suena interesante
presenta problemas con los saltos, por ejemplo cuando una instruccin necesita de un dato que todava
no ha sido decodificado por lo que se ve obligado a esperar la ejecucin de la instruccin que contiene
la informacin, esto se mejora con tcnicas predictivas a nivel de hardware.

Registros del Procesador.

Existen trece registros de propsito general todos de 32 bits, otra gran diferencia con
microcontroladores menores donde solo existen un registro de trabajo y la interaccin de nuestras
aplicaciones con este registro es fcilmente predecible, con trece registros la historia se complica y ya
no es tan claro como el procesador usar estos registros cuando programamos en lenguajes como C
donde la independencia con el hardware es importante.
Dos registros para el manejo del Stack, Main Stack Pointer (MSP) que es cargado con el valor
0x00000000 luego de un Reset, y el Procesador Pointer (PSP.
El Link Register (LR), registro R14 almacena la informacin de declaracines de subrutinas, llamadas a
funciones y excepciones, valores de retorno. Luego de un reset el valor LR es 0xFFFFFFFF.
El Program Status Register (PSR) se usa para para monitorear el estado del programa en ejecucin, por
ejemplo si un nmero es negativo o cero entre otras cosas.
Luego de un RESET el PC se carga con el valor 0x00004 y el M4 puede direccin hasta un lmite
terico de 4GB.

13
Procesadores Escalares:
Los procesadores escalares son el tipo ms simple de procesadores. Cada instruccin de un
procesador escalar opera sobre un dato cada vez. En contraposicin, en un procesador
vectorial una sola instruccin opera simultneamente sobre un conjunto de datos. La
diferencia entre ambos es la misma que entre la aritmtica escalar y la vectorial. Los
procesadores escalares pueden ser CPUs completas o ALUs. En algunos casos, un
procesador puede estar compuesto de una CPU y varias ALUs, formando el conjunto un
procesador superescalar.

Instrucciones Ortogonales:
La ortogonalidad es una propiedad de las unidades centrales de procesamiento. Se dice
que un conjunto de instrucciones es ortogonal cuando se puede utilizar cualquier modo de
direccionamiento en cualquier instruccin. La bsqueda de la ortogonalidad hace que el
diseo de la unidad central de procesamiento sea ms complejo pero aporta una mayor
facilidad de programacin.

La programacin para este dispositivo es C casi podemos decir de manera obligada, la complejidad de
sus funciones, estructura y posibles configuraciones de trabajo hacen que estos dispositivos no sean
aptos para una total programacin en lenguajes de bajo nivel.
Existen en la actualidad herramientas/soft de programacin para todos los sistemas operativos y
muchas de estas herramientas basadas en Linux y Windows son de uso libre corriendo por ejemplo en
Eclipse.

Nosotros en el curso usaremos el entorno de KEIL en Windows pero los programas pueden ser
compilados en cualquier herramienta como veremos mas adelante.

17
Para trabajar con solo necesitamos una computadora con puerto USB puesto que la propia placa que
estamos usando se alimenta desde el USB.
Al conectar la placa entrenadora puede suceder que el firmware del programador STLink embebido en
la placa este desactualizado, esto depende de las distintas versiones que hay en el mercado de esta
entrenadora.
Para actualizar el firmware solo debe ejecutar el siguiente programa que encontrar dentro de las
herramientas del curso.

Esto actualizar el firmware de su programador a la versin mas resiente.

23
Tambin encontrar un soft programador para esta arquitectura, si ha programado usted PICs podemos
decir que sera algo como el PicKit, ICD3, etc. Todo lo necesario para instalarlo junto a los drivers
USB estn en el paquete de herramientas del curso. Antes de intentar trabajar con la entrenadora se
deben instalar los drivers para que el sistema la reconozca. Sin embargo normalmente no necesitaremos
lidiar con el programador ya que el entorno KEIL integra la placa entrenadora/programadora en sus
herramientas y todo el trabajo lo haremos desde el mismo entorno sin necesidad de trabajar con
ninguna herramienta exterior.
Con KEIL podremos hacer una gran variedad de aplicaciones para distintos ambientes y necesidades.

Una de las caractersticas mas interesantes que tiene la arquitectura ARM es que nos permite
formar parte de una comunidad donde existen muchos desarrolladores de aplicaciones para
hardware diverso donde hay mucho cdigo y paquetes de programas ya resueltos, rutinas que
son de uso libre que inclusive pueden haber sido escritas para Cortex M3 y son perfectamente
portables a M4 con simples ajustes en el proyecto a compilar.

24
Configurando el entorno de trabajo.

Desde la lengeta Device seleccionamos el micro-controlador, desde la lengeta Target definimos


algunas configuraciones bsicas para nuestro controlador. MicroLib es una biblioteca altamente
optimizado para aplicaciones embebidas escritas en C basados en ARM. Cuando se compara con la
biblioteca de C estndar que se incluye con el compilador de ARM, MicroLib proporciona
significativas ventajas en cuanto al tamao de cdigo requerido para muchos sistemas embebidos.

26
Aqu configuramos el entorno, las rutas de archivos y libreras, si en el paso anterior indicamos que
usaremos libreras provistas por STM en este paso indicamos donde estn estas libreras.

IMPORTANTE: MicroLib es una biblioteca altamente optimizado para


aplicaciones embebidas escritas en C basados en ARM. Cuando se compara con la
biblioteca de C estndar que se incluye con el compilador de ARM, MicroLib
proporciona significativas ventajas en cuanto al tamao de cdigo requerido para
muchos sistemas embebidos.

Recordar: Todos los trabajos ejemplos estn para


ser compilados con MICROLIB.

KEIL lo puede descargar directamente desde su pagina oficial.

28
Desde la lengeta Debug siempre dentro de Utilities indicamos que el programador es del tipo SW y
no del tipo JTAG. (Si olvido este paso el programador NO FUNCIONAR.)

Puedo programar el microcontrolador sin un programador especfico?


El controlador STM32F407VG y todos los
dispositivos de STMicroelectronics tienen
incorporado un cargador que funciona con el
protocolo UART y que permite bajar nuestro
cdigo directamente a la memoria FLASH de
controlador.
Solo se necesita un conversor USB-RS232 para
nuestra notebook, elegir el COM en uso,
conectar el TX al pin PB10 y RX al pin PB11 en
el caso del STM32F407VG.
Si durante el arranque del controlador detecta un
nivel alto en el pin Boot 0 ejecuta el cargador
que espera recibir el programa que se guardar
en FLASH a travs del puerto COM.
Luego se cambia el nivel de Boot 0, un RESET y
se ejecuta el programa grabado.
Es importante comentar que este cargador no
consume recursos del microcontrolador ni memoria de programa, es un mdulo aparte agregado por
STM para simplificar el proceso de grabacin de la FLASH con la aplicacin programada.

30
Mi Primer Programa en KEIL
Teniendo todo ya configurado vamos a intentar escribir nuestro primer programa, una plantilla genrica
de un programa con CMSIS.

Podemos ver aqu los dos archivos para el inicio del sistema generados por CMSIS.
El archivo startup_stm32f4xx.s es el archivo de arranque del sistema dentro de este archivo se puede
leer lo siguiente:

El archivo startup_stm32f4xx.s llama a funciones que se encuentran en system_stm32f4xx.c, este


archivo es el que contiene la configuracin de hardware del microcontrolador como velocidad de los
buses, tipo de cristal, reloj para USB, etc.
*===============================================================================
* Supported STM32F4xx device revision | Rev A
*-----------------------------------------------------------------------------
* System Clock source | PLL (HSE)
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 168000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 4
*-----------------------------------------------------------------------------
* APB2 Prescaler | 2
*-----------------------------------------------------------------------------
* HSE Frequency(Hz) | 8000000
*-----------------------------------------------------------------------------
* PLL_M | 8

31
Se declara el uso de la estructura para la configuracin de los puertos GPIO.
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
Aqu se activa el reloj que proviene del bus AHB1 y especficamente lo estamos activando para el
puerto D.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

Especficamente vamos a configurar el pin 15 del puerto D e indicamos que ser salida. Tambin se
podran configurar mas pines de una sola vez por ejemplo de la siguiente forma:
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13| GPIO_Pin_14;
En la siguiente lnea indicamos que la salida ser del tipo Push-Pull. (Opuesto a Open Drain).
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
Los pines del puerto en modo salida pueden ser configurados en tres modos distintos.

open drain Salida de colector abierto.


open drain, with pull-up Transistor para el nivel bajo y una resistencia a nivel alto.
push-pull Un transistor para el nivel alto y otro para el nivel bajo.
En el modo entrada son tres tambin los modos de funcionamiento:

pull-up Un resistor conectado a nivel alto.


Pull-down Un resistor conectado a nivel bajo.
pull-up and pull-down Un resistor conectado a nivel alto y otro a nivel bajo (Se utiliza en
raras ocasiones, no es una configuracin usual).
Se configura el puerto a 100Mhz.
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

No hay resistencias Pull-Up ya que el puerto funciona como salida.


GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

Finalmente la estructura se hace activa.


GPIO_Init(GPIOD,&GPIO_LED);
Es en este momento que la configuracin pasa a ser efectiva y el puerto es configurado.

Importante:
Todo trabaja a 3V, por lo tanto los niveles lgicos son de 3V tenga especial cuidado de no
mezclar niveles digitales de 5V puesto que podra daar la placa entrenadora.

36
Para el tratamiento de estos datos con la informacin provista por el fabricante podemos crear una
funcin que lo resuelva.
float temperatura_leer_grados(void) {
float grados;
ADC_SoftwareStartConv(ADC1); // Inicia la conversin
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)){}
grados = ADC_GetConversionValue(ADC1);
grados = (grados *3.3)/4095;
grados = ((grados - 0.76)/2.5)+25;
return(grados); // Retorna el valor ya escalado
}

Importante:
Tenga en cuenta que incluso si usted no est usando un disparador externo mediante la instruccin:
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None
En la declaracin ADC_InitStructure.ADC_ExternalTrigConv sigue siendo necesaria para la estructura
que se escriba algo vlido de lo contrario se producen resultados extraos en las conversiones.
La inicializacin T1_CC1 es equivalente a la inicializacin del miembro de estructura a 0.

Para visualizar los datos usaremos una pantalla 16x2 Hitachi 44780, el controlador para esta pantalla lo
encontramos en los archivos stm32f4_hd44780.c y stm32f4_hd44780.h donde se encuentran tanto las
funciones para el manejo de la pantalla como la conexin de los pines.

La pantalla se puede conectar a cualquier puerto del controlador solo basta editar el archivo
stm32f4_hd44780.h que es donde se encuentran estas definiciones.

El archivo temperatura_intern.c tiene todas las funciones para la medicin de temperatura y el archivo
temperatura_intern.h las correspondientes declaraciones de variables y funciones.

72
Canales DMA.
Hay dos controladores DMA casi idnticos siendo la principal diferencia que solo el DMA2 puede
realizar transferencias de memoria a memoria y claro que los DMA estn conectados a distintos buses
de reloj.

Cada DMA puede manejar ocho stream (ocho canales FIFO), cada flujo de datos deber estar asociado
a uno de estos canales.

Los perifricos tienes asociado tanto el canal como el stream.


En el manual del dispositivo se puede consultar el mapeo de los perifricos y su relacin con los DMA.

77
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 4; // Cuatro conversiones en ADC3
ADC_Init(ADC3, &ADC_InitStructure);

Configura el rden de lectura de los canales y la velocidad


ADC_RegularChannelConfig(ADC3, ADC_Channel_10, 1, ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 2, ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_13, 3, ADC_SampleTime_144Cycles);
ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 4, ADC_SampleTime_144Cycles);
/* Habilita la transferencia DMA con el ADC3 (Modo Single-ADC) */
ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);
/* Habilita ADC3 DMA */
ADC_DMACmd(ADC3, ENABLE);
/* Habilita ADC3 */
ADC_Cmd(ADC3, ENABLE);
}

/******************* FIRTEC Capacitacin *****FIN DE ARCHIVO**********************/

Vemos otro ejemplo de uso del DMA tratando los datos desde la UART4.
El objetivo es recibir 16 Bytes almacenarlos en el DMA y transmitirlos por el mismo puerto.
De acuerdo al mapa de perifricos vemos que la recepcin del UART4 se conecta al Canal4 con el
Stream2 del DMA1. Observe que 16 Bytes son 128 bits que es lo mximo que puede manejar el FIFO
del mdulo DMA.

Se activan los relojes de los mdulos que se usarn:


RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);

Configuramos los pines que usaremos en el puerto UART.


En este programa usaremos el PA0 para transmitir y el PA1 para recibir los datos.

83
Modo DMA de doble buffer.
Funciona como el modo normal (single-buffer), con la diferencia de que se tiene dos punteros a
memoria. Cuando el modo doble buffer est activo el modo circular es activado automticamente y en
cada extremo de la transaccin (DMA_SxNDTR register reach 0), el punteros memoria se mantiene.
Esto permite que el software pueda procesar un rea de memoria mientras que la segunda rea de
memoria est siendo utilizado o completado por la transferencia DMA.

El modo de doble buffer es adecuado cuando necesitamos hacer el seguimiento de una seal o para el
muestreo de una seal que evoluciona rpido en el tiempo y necesitamos que los datos en proceso de
ser tratados no se interfieran con los datos que estn siendo capturados.

Emular memoria EEPROM en FLASH.


Muchos microcontroladores cuentan con memoria EEPROM para guardar datos que el usurario desea
conservar cuando el controlador ha sido desconectado, un ejemplo podra ser la clave de una alarma.
Es poco prctico que para cambiar la clave de una alarma o sistema de acceso debiramos re-programar
nuestro controlador, es mas lgico pensar que el usuario puede hacerlo por si mismo.

El STM32F407 no dispone de memoria EEPROM sin embargo podemos emular esta memoria en la
propia FLASH asignando sectores de FLASH a las que llamaremos pginas.
La memoria de programa de este microcontrolador es de 1MB y est definida desde la direccin
0X200FFFFF a 0x20000000 (1,048,575 Bytes) si bien el procesador puede direccionar 4GB este Mega
Byte est mapeado dentro de estos 4 GB tericos.
El ejemplo que tratamos esta basado en la nota de aplicacin AN3969 de STM donde se crean dos
pginas de 16K.
Pgina 0 con direccin de 0x0000 a 0x3FFF
Pgina 1 con direccin de 0x4000 a 0x7FFF

La direccin FLASH donde inicia la emulacin est en 0x08008000 y se usan dos sectores de 16K para
crear estas pginas con direcciones virtuales.

90
Sensor para medir Temperatura y Humedad HDC1000.
Con este sensor podemos medir temperatura con un rango que va desde -40 grados a +125 grados y
humedad de 0 a 100%. Utiliza un conversor analgico de 14 bits lo que da una precisin mas que
aceptable para aplicaciones donde el control de estas variables sea necesario. Un ejemplo podra ser un
invernculo, una bodega, una cmara frigorfica, etc.

Desarrollado por Texas Instruments y ha sido calibrado en fbrica por lo que no requiere ajuste alguno.
Este sensor tiene una serie de registros de 16 bits para su configuracin y uso.
En la direccin 0x00 se guardan dos Bytes que corresponden a la temperatura y en la direccin 0x01
dos Bytes para la humedad.

La direccin 0x02 es el registro de configuracin, en este registro nos interesa solamente el bit 12 que
configura la forma en que los datos estarn disponibles.
Si el bit es puesto a uno la temperatura y humedad sern accedidos en secuencia, primero la
temperatura y luego la humedad.

En nuestro ejemplo y para simplificar las cosas, estamos usando un sensor ya montado en una placa
impresa construido por MikroElektronika y por su bajo costo no justifica construirla. (Sin embargo el
fabricante de la placa brinda todos los diagramas de conexionado).
Para el manejo de este sensor hemos desarrollado un pequeo driver que resuelve todo su

103
while(1);
}
HD44780_Puts(0, 0,"STM32F4<>HDC1000");
Config_Sensor();

while(1){
Leer_Sensor();
sprintf(floatStr,"T:%2.1f",temperature);
HD44780_Puts(0, 1,floatStr);
sprintf(floatStr,"Hum:%2.1f%%",humidity);
HD44780_Puts(7, 1,floatStr);
Delayms(500);
}
}

/*** fin del archivo ***********************************************************/

El resultado final obtenido es el que se aprecia en la imagen.


La direccin I2C de este sensor es 0x40 y su ID es 0x1000, este ID se encuentra escrito en el registro
0xFF y puede ser usado para verificar si el sensor accedido es el correcto.

Analizando la funcin que lee el sensor.


void Leer_Sensor() {

I2C_start(I2C1, SLAVE_ADDRESS<<1, I2C_Direction_Transmitter);


I2C_write(I2C1, 0x00);

108
En la imagen siguiente se puede ver como estn dispuestos estos registros de datos. Las direcciones
0x28, 0x29 y 0x2A contienen la informacin de presin, las direcciones 0x2B y 0x2C contienen el
valor de temperatura con su signo.

Un detalle curioso es que si pretendemos leer consecutivamente los registros en un acceso I2C de
lectura de mltiples registros consecutivos, en ocasiones el valor ledo se corrompe. No ocurre si se lee
los registros de uno en uno como se ver en el ejemplo mostrado.
El fabricante indica que para interpretar correctamente la temperatura se aplica el siguiente criterio.

En la practica veremos que el valor de temperatura en realidad es un tanto inexacto a la hora de


implementarlo como valor til, en realidad el sensor lo utiliza en sus procesos internos con la presin
siendo para el usuario un valor agregado.

112
Para el clculo de la temperatura aplicamos la siguiente formula:

Para el clculo de la presin absoluta los pasos indicados por el fabricante seran como sigue:

En el ejemplo siguiente vemos como leer y mostrar el valor de presin atmosfrica, el resultado final es
el que se aprecia en la siguiente foto.

El sensor por cuestiones prcticas, hemos usado uno ya montado en una pequea placa.
Un detalle a tener en cuenta es que, al menos en la placa que probamos, no estn soldadas las
resistencias de 4,7K necesarias para el correcto funcionamiento del bus I2C siendo necesarias
colocarlas de manera externa.
Para dialogar con el sensor necesitaremos de un driver, en la pgina siguiente podemos ver el listado
completo des driver que permite el acceso y control del sensor LPS25HB.

113
SD_Response(&response, RESP_R1);
//Configura SDIO->CLKC
tempreg=0;
tempreg|=(0x01)<<11; //4 bit para el bus
tempreg|=SDIO_CLKCR_CLKEN; // Clock habilitado
// Nuevo clock =48/(Div+2)=48/2=24
SDIO->CLKCR=tempreg; // Ahora se pueden usar los comandos de lectura/escritura
}

El resto de las funciones las encontrar en el archivo SDIO.C y SDIO.H dentro de la


carpeta de proyecto SDIO.

Memoria SD con FAT.


Secure Digital (SD) es un formato de tarjeta de memoria
inventado por Panasonic. Se utiliza en dispositivos porttiles
tales como cmaras fotogrficas digitales, PDA, telfonos
mviles, computadoras porttiles e incluso videoconsolas,
entre muchos otros.
Estas tarjetas tienen unas dimensiones de 32 mm x 24 mm x
2,1 mm. Existen dos tipos: unos que funcionan a velocidades
normales, y otros de alta velocidad que tienen tasas de
transferencia de datos ms altas. Algunas cmaras
fotogrficas digitales requieren tarjetas de alta velocidad para poder grabar vdeo con fluidez o para
capturar mltiples fotografas en una sucesin rpida.
Los dispositivos con ranuras SD pueden utilizar tarjetas MMC, que son ms finas, pero las tarjetas SD
no caben en las ranuras MMC.
Asimismo, se pueden utilizar en las ranuras de CompactFlash o de PC Card con un adaptador.
Sus variantes MiniSD y MicroSD se pueden utilizar, tambin directamente, en ranuras SD mediante un
adaptadores.
Todas las tarjetas de memoria SD y SDIO necesitan soportar el antiguo modo SPI/MMC que soporta la
interfaz de serie de cuatro cables ligeramente ms lenta (reloj, entrada serial, salida serial y seleccin de
chip) que es compatible con los puertos SPI en muchos microcontroladores.

Muchas cmaras digitales, reproductores de audio digital y otros dispositivos porttiles, probablemente
utilicen exclusivamente el modo MMC. La documentacin para implementar este modo es arancelada
sin embargo, la documentacin parcial para SDIO es libre y existe documentacin libre disponible para
tarjetas de memoria como parte de las hojas de especificacin de algunos fabricantes.

El modo MMC no proporciona acceso a las caractersticas propietarias de cifrado de las tarjetas SD y la
documentacin libre de SD no describe dichas caractersticas.
La informacin del cifrado es utilizada primordialmente por los productores de medios y no es muy
utilizada por los consumidores quienes tpicamente utilizan tarjetas SD para almacenar datos no
protegidos.

Existen 3 modos de transferencia soportados por SD:

Modo SPI: entrada separada serial y salida serial.

128
herramientas del curso.
La idea es lograr escribir con el microcontrolador un archivo de texto (Hola.txt) con el contenido
Manejando archivos con FAT.
Luego podemos ver el contenido de este archivo en nuestra computadora como se muestra en la
siguiente imagen.

Tambin vamos a crear un archivo de texto (Mensaje.txt) con un texto cualquiera que ser ledo por
nuestro controlador y toda la informacin del contenido de la memoria ser enviada a travs del puerto
serial .
La comunicacin se establece a 11520 baudios.
El pin PC_7 recibe y el pin PC_6 a transmite.
La trama se establece en 8 bits S/Paridad.

133
Captura de pantalla en el momento en que se conecta la memoria SD. Como se observa el sistema
detecta nuestra memoria como una unidad de disco donde podemos leer, borrar o guardar doscumentos
creados en nuestra computadora. El proyecto completo listo para ser compilado y/o reformado a
voluntad lo encontrar en la carpeta USB_MemSD.

Utiliza el puerto USB de usuario.

Proyecto completo

140
Funcionamiento general de un PID.
Para el correcto funcionamiento de un controlador PID que controle un proceso o sistema se necesita,
al menos:
1. Un sensor, que determine el estado del sistema.
2. Un controlador, que genere la seal que gobierna al actuador.
3. Un actuador, que modifique al sistema de manera controlada.
El sensor proporciona la informacin al controlador, la cual representa el punto actual en el que se
encuentra el proceso o sistema.
El controlador lee una seal externa que representa el valor que se desea alcanzar. Esta seal recibe el
nombre de punto de consigna (o punto de referencia), la cual es de la misma naturaleza y tiene el
mismo rango de valores que la seal que proporciona el sensor.

El controlador resta la seal de punto actual a la seal de punto de consigna, obteniendo as la seal de
error, que determina en cada instante la diferencia que hay entre el valor deseado (consigna) y el valor
medido. La seal de error es utilizada por cada uno de los 3 componentes del controlador PID. Las 3
seales sumadas, componen la seal de salida que el controlador va a utilizar para gobernar al actuador.
La seal resultante de la suma de estas tres se llama variable manipulada que ser transformada para
ser compatible con el actuador utilizado en el sistema.
Las tres componentes de un controlador PID son: parte Proporcional, accin Integral y accin
Derivativa. El peso de la influencia que cada una de estas partes tiene en la suma final, viene dado por
la constante proporcional, el tiempo integral y el tiempo derivativo, respectivamente. Se pretender
lograr que el bucle de control corrija eficazmente y en el mnimo tiempo posible los efectos de las
perturbaciones.

Control PID con STM32F407.

CMSIS de ARM proporciona funciones matemticas avanzadas para el diseo de un control PID.
Tambin hay funciones PID en diferentes formatos para f32, q31 y Q7. Este proyecto implementa un

142
controlador PID con STM32F4xx usando funciones PID de ARM que ofrece tres funciones diferentes
para el PID. f32: float, q31: nmero entero, Q7: char.
Para cada uno de los tres tipos, tiene tres funciones:
f32
arm_pid_init_f32
arm_pid_reset_f32
arm_pid_f32
q31
arm_pid_init_q31
arm_pid_reset_q31
arm_pid_q31
q7
arm_pid_init_q7
arm_pid_reset_q7
arm_pid_q7
Tambin hay una estructura donde se pasa parmetros al PID.
En el proyecto tratado se utilizan dos sensores de temperatura DS18B20. Se configuran en la
resolucin de 12 bits por lo que demora unos ~ 750ms entre cada medicin.

El proyecto completo se puede ver funcionado en este link.

143
#define TEMP_CURRENT temps[1] // Temperatura Actual
#define TEMP_WANT temps[0] // Temperatura Referencia

#define PID_PARAM_KP 100 // Proporcional


#define PID_PARAM_KI 0.025 // Integral
#define PID_PARAM_KD 20 // Derivativo

char str[100];

int main(void) {

PWM_TIM_t TIM_Data; // Timer para el PWM


uint8_t devices, i, count;
uint8_t device[EXPECTING_SENSORS][8]; // ID de los sensores

float temps[EXPECTING_SENSORS]; // Temperatura de los sensores


float pid_error; // PID Error
float duty = 0; // Duty del PWM

arm_pid_instance_f32 PID; // Funcin PID de ARM

// Seteo de los parmetros del PID


PID.Kp = PID_PARAM_KP; // Proporcional
PID.Ki = PID_PARAM_KI; // Integral
PID.Kd = PID_PARAM_KD; // Derivativo

arm_pid_init_f32(&PID, 1); // Configura la funcin ARM PID float 32

DELAY_Init(); // Configura los retardos

PWM_InitTimer(TIM2, &TIM_Data, 1000); // TIM2 a 1kHz (Carrier del PWM)

// Configura TIM2 en Canal1, PinsPack 2 (PA5)


PWM_InitChannel(TIM2, PWM_Channel_1, PWM_PinsPack_2);

// Seteo del duty cycle por defecto


PWM_SetChannelPercent(TIM2, &TIM_Data, PWM_Channel_1, duty);

// Inicializa 1-Wire en pin PA6 (Archivo defines.h)


OneWire_Init();
HD44780_Init(20, 2); // LCD en 20 columnas x 2 filas

// Verificar la presencia de sensores 1-Wire


count = 0;
devices = OneWire_First();
while (devices) {
// Busca los cdigos ROM de los sensores
OneWire_GetFullROM(device[count]);
count++;
devices = OneWire_Next();

145
unsigned char bandera =0;
static char ArchNombre[13];
char temp[11];
char espacio[20];
uint8_t devices,count;
uint8_t device[EXPECTING_SENSORS][8];
float temps[EXPECTING_SENSORS];
unsigned char minuto_anterior = 0;
TM_DS1307_Time_t time;
static void fault_err (FRESULT rc);
#define EXPECTING_SENSORS 1

#ifdef USB_OTG_HS_INTERNAL_DMA_ENABLED
#if defined ( __ICCARM__ ) //!< IAR Compiler
#pragma data_alignment=4
#endif
#endif // USB_OTG_HS_INTERNAL_DMA_ENABLED

__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END ;


FUNCION PRINCIPAL DEL PROGRAMA
int main(void){
TM_DS1307_Init();

/* // Valores por defecto para el calendario


time.hours = 8;
time.minutes = 8;
time.seconds = 10;
time.date = 16;
time.day = 6;
time.month = 1;
time.year = 15;
TM_DS1307_SetDateTime(&time);
*/

HD44780_Init(16, 2); // 16 col x 2 filas

DELAY_Init(); // Configura las rutinas de tiempo

OneWire_Init(); // OneWire en pin PC0

149
Modo lector denso.
Este es una modalidad de operacin que previene que los lectores interfieran entre s cuando muchos de
estos lectores se utilizan ubicndolos de manera cercana el uno del otro. Los lectores saltan entre los
canales dentro de cierto rango del espectro de la frecuencia y puede ser necesario que tengan que captar
una seal antes de poder usar un canal. Si "escuchan" que otro lector est usando ese canal, saltan a
otro canal para evitar interferir con el lector que est usando ese canal.

Tags pasivos usados en el ejemplo.


En el ejemplo propuesto usamos los tpicos tags de uso comn para reglamentar el ingreso a edificios,
controla de alarmas, etc. Su funcionamiento se basa en la seal que le llega de los lectores. sta induce
una pequea corriente elctrica, suficiente para el funcionamiento del circuito integrado CMOS del tag
y la transmisin de informacin al lector.
La distancia de aplicacin de estos tags es para uso cercano, unos pocos centmetros entre el tag y el
lector.

Debido a la importancia en el consumo de energa, la respuesta del tag pasivo ha de ser breve,
normalmente poco ms que un nmero de identificacin.
La posicin u orientacin de los tags presentados frente al lector puede afectar al funcionamiento
ptimo, se pretende siempre intentar la mxima interaccin entre las antenas.

163
Escribe_Comando(0x02,2);
Leer_Comando();
}
}

En este caso el cdigo enviado es 0x02, no confundirlo con con el comando que tambin es 0x02.
Una vez que todas las configuraciones estn terminadas solo resta recibir los distintos tag que se
presenten frente al receptor RFID.

La deteccin de los tags se resume en un bucle while() que llama a la funcin Buscar_TagID(), esta
funcin es la encargada de leer el tag, intenta primero con el protocolo 18092 y si no tiene xito cambia
al protocolo 14443.
Si miramos dentro de la funcin que detecta los tags podemos ver donde se determina el protocolo de
recepcin (marcado en rojo).

void Buscar_TagID(){
sdata[0] = 0x00;
sdata[1] = 0xFF;
sdata[2] = 0xFF;
sdata[3] = 0x00;
sdata[4] = 0x00;
Escribe_Comando(0x04,5);
Leer_Comando();
.
.
.
(Resto de la funcin)

En la hoja de datos se indica la secuencia de bytes que se deben enviar para configurar el chip en uno u
otro protocolo.

En el bucle principal del programa se interroga por nuevos tags y se los muestra en una pantalla LCD,

174
La placa RFID tiene varios pines, varios de ellos no llevan conexin. Los pines SS1 y SS0 son los
encargados de la seleccin del tipo de conexin al microcontrolador, UART o SPI.

El pin Int1 es el pin encargado de validad el estado de los bits presentados en SS0 y SS1, la accin
sobre este pin est a cargo del software siguiendo el procedimiento indicado en la hoja de datos.
Los pines que se vinculan al puerto SPI se conectan este rden.

SDI se conecta al pin MOSI de nuestro controlador, GPIOB_15 en este ejemplo.


SDO se conecta al pin MISO de nuestro controlador, GPIO_14 en este ejemplo.

177
}

unsigned char SPI_RX_Byte(void)


{
while(SPI_I2S_GetFlagStatus(Open_SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPIx,0x00);

while(SPI_I2S_GetFlagStatus(Open_SPIx, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPIx);
}

Una vez que tenemos todos los archivos podemos ensamblar el proyecto, su aspecto final debera ser
como se aprecia en la siguiente imagen. Los archivos para el manejo de la pantalla LCD como las
rutinas de tiempo no se incluyen por razones de espacio y por considera que son de uso comn
existiendo muchos ejemplos que se descargan libremente de internet.

Sensor de imagen OV7670 con STM32F407


El OV7670 es un sensor de imagen de bajo costo con un DSP integrado que puede operar a un mximo
de 30 fps y 640 x 480 de resolucin (VGA), equivalente a 0.3 Megapixels.
La imagen capturada puede ser pre-procesada por el DSP antes de enviarla al puerto DCMI. Este pre-
procesamiento se puede configurar a travs de un registro de control (SCCE).
El mdulo de la cmara tiene una doble fila de 8 pines por lado:

La interfaz se conecta a la placa entrenadora mediante 16 conexiones.

186
Manejo del Touch-Screen.
El hardware que maneja el Touch es el controlador XPT2046 y su driver est en el archivo
TouchPanel.c
El panel tctil es del mismo tamao que la pantalla LCD de modo que si pulsamos un lugar en el panel
tctil, conoceremos las coordenadas (x, y) que corresponde a la pantalla. El XPT2046 es un controlador
de pantalla tctil resistiva de 4 hilos que incorpora un conversor de 12 bits 125 kHz de muestreo.
El mtodo que utilizamos para obtener las coordenadas (x, y) se llama referencia diferencial. La teora
no se explica aqu. Si usted tiene inters, puede echar un vistazo a la hoja de datos XPT2046.

Estructura interna del controlador.

Conexiones mnimas del controlador.

196
El siguiente programa utiliza el Touch Screen de la pantalla TFT y nos servir de ejemplo.
/**********************************************************************************
* Nombre : Touch_TFT.c
* Descripcin : Manejo del TouchScreen
* Target : STM32F407VG
* ToolChain : MDK-ARM
* IDE : uVision 4
*
* www.firtec.com.ar
*********************************************************/
#include "stm32f4xx.h"
#include "LCD/LCD.h"
#include "TouchPanel/TouchPanel.h"
#include <stdio.h>

int main(void){
int8_t temp[20]={0};
uint16_t tempx=0,tempy=0;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_ResetBits(GPIOB, GPIO_Pin_0);
TP_Init();
Configurar_LCD();
LCD_Clear(Black);
TouchPanel_Calibrate();
LCD_DrawLine( 0, 0, 320, 0, White); // Lnea superior
LCD_DrawLine( 0, 222, 320, 222, White); // Lnea ttulo, abajo
LCD_DrawLine( 0, 239, 320, 239, White); // Lnea abajo final
LCD_DrawLine( 319, 0, 319, 240, White); // Lnea vertical derecha
LCD_DrawLine( 0, 0, 0, 240, White);
GUI_Text(1,223," http://www.firtec.com.ar ",White,Blue);
LCD_DrawLine( 319, 0, 319, 240, White); // Lnea vertical derecha

while (1)
{
getDisplayPoint(&display, Read_Ads7846(), &matrix );
TP_DrawPoint(display.x,display.y);
if(tempx != display.x || tempy != display.y)
{
sprintf(temp,"X:%3d,Y:%3d",tempx,tempy);
GUI_Text(10,10,(uint8_t*)temp,Red,Black);
tempx = display.x;
tempy = display.y;
}
}
}

197
// LEE por la dir ROM de cada sensor y guarda en temps
TM_DS18B20_Read(&device[i][0], &temps[i]);
sprintf(buf, "T%d: %3.2f ", i, temps[i]);
GUI_Text(Y,X,buf,White,Red);
Y=Y+100;
}
alarm_count = 0;
// Verifica si algn sensor tiene seteada alarmas
while (TM_DS18B20_AlarmSearch()) {
// Almacena la dir ROM del sensor con alarma
TM_OneWire_GetFullROM(&alarm_device[alarm_count][0]);
alarm_count++;
}
sprintf(buf, "Alarmas Activas: %d", alarm_count);
GUI_Text(92,100,buf,Black,Cyan);
X =120;
Y =86;
// Muestra cuantas sensores con alarma existen
if (alarm_count > 0) {
// Muestra el ROM code del sensor con alarma
for (j = 0; j < alarm_count; j++) {
for (i = 0; i < 8; i++) {
sprintf(buf, "%02X ", alarm_device[j][i]);

GUI_Text(Y,X,buf,Black,Green);
Y = Y + 20;
}
X = X + 20;
Y =82;
}
}
else{
GUI_Text(7,120," ",Cyan,Green);
GUI_Text(7,140," ",Black,Green);
GUI_Text(7,160," ",Cyan,Green);

}
Delayms(250);
}
}

Resultado esperado de nuestra aplicacin en ejecucin.

209
Configura los LED's de la placa
void LED_Init(void){
STM_EVAL_LEDInit(LED1);
STM_EVAL_LEDInit(LED2);
STM_EVAL_LEDInit(LED3);
STM_EVAL_LEDInit(LED4);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{}
}
#endif

Aspecto del proyecto a compilar.

Que es un socket?
Seguramente encontrar variadas definiciones de lo que es un
Socket en redes informticas, sin embargo desde el punto de vista
de la electrnica con microcontroladores, podramos simplemente
decir que es el RS-232 de TCP-IP.
Una de las formas mas simples de conectar un microcontrolador,
PLC o electrnica en general a una computadora es a travs de una
UART con el conocido protocolo RS-232. Un socket hace eso
mismo, establece una conexin entre dos puntos, sin importar donde se encuentren estos puntos y esto
si es una gran diferencia con el viejo RS-232.
Podemos hacer una medicin de voltaje, temperatura, humedad o lo que fuera necesario verificar y
transmitir estos datos a cualquier parte del mundo por TCP-IP para esto solo necesitamos tres cosas:

220
1. Una direccin IP donde enviar los datos.
2. Un puerto virtual donde los datos ser recogidos.
3. El conocimiento para darle forma a la idea

Hay varios tipos de socket pero dos son de uso mas comn.

Los socket de flujo (SOCK_STREAM) que son transportados por TCP (Protocolo de Control
de Transmisin) y asegura que los mensajes lleguen en el mismo orden que fueron enviados y
sin errores. Telnet, los navegadores y muchas aplicaciones usan este tipo de conexin fiable y
segura.
Los socket de datagrama (SOCK_DGRAM) son transportados por UDP (Protocolo de
Datagramas de Usuario), Es la forma mas simple de enviar datos por la red. Simplemente
montamos un paquete le damos una direccin destino y un puerto y listo!! El SOCK_DGRAM es
mas rpido que el anterior pero claro aqu no importa el orden en que los paquetes llegan y
varias cosas mas no son tomadas en cuenta motivo por el cual es mas rpido. Pero cuando lo
que enviamos son simples datos de una medicin o el estado de una mquina y solo estaremos
usando la conexin para enviar datos sueltos y espordicos (mismo que hacemos con RS-232 y
microcontroladores) este tipo de socket es ideal para mover datos con nuestra electrnica.

Capturando paquetes con LwIP.


Con una exigencia de memoria RAM muy baja y ocupando menos de 40KB de memoria de programa,
la pila LwIP es muy adecuada para embeberla en microcontroladores.
Esta formado por varios archivos todos escritos en C que se pueden adaptar a casi cualquier necesidad
ya que su uso es libre.
LwIP ofrece tres API's para el manejo de red, RAW, NETCON y SOCKET.
La gestin de los paquetes se realiza en un buffer llamado pbuf que asigna y organiza toda la memoria
para el correcto funcionamiento del satck, bsicamente hay tres tpos de pbuf, el PBUF_POOL que es
el mas adecuado para recibir paquetes y almacenarlos rpidamente y es el que usaremos. PBF_RAM es
mas lento puesto que lleva mas gestin de memoria y los paquetes no se guardan en espacios contiguos
resultando en una fragmentacin de memoria, aplicaciones puntuales hacen uso de este modo.
PBUF_ROM se utiliza para enviar datos constantes obtenidos de la memoria de programa.
El pbuf que usaremos tiene el siguiente formato.

Bsicamente es una estructura con varios campos, el campo next es un apuntador al siguiente pbuf dado

221
#********************************************************************************
def info():
showinfo(title='Acerca de..', message='Script en Python 2.7 \n
www.firtec.com.ar')
def makemenu(parent):
menubar = Frame(parent)
menubar.pack(side=TOP, fill=X)

fbutton = Menubutton(menubar, text='Menu', underline=0)


fbutton.pack(side=LEFT)
file = Menu(fbutton)
file.add_command(label='Acerca de...', command=info, underline=0)
file.add_command(label='Salir', command=parent.quit, underline=0)
fbutton.config(menu=file)

makemenu(ventana)

label_Nombre_IP = Label(ventana, text="IP:", bg="beige", fg="blue",


font=("Helvetica", 14))
label_Nombre_IP.place(x=18, y=35)

label_IP = Label(ventana, bg="beige", fg="blue", font=("Helvetica", 14))


label_IP.config(text = Dir_IP)
label_IP.place(x=42, y=35)

label = Label(ventana, text="Voltios:???", bg="beige", fg="red", font=("Helvetica",


28))
label.place(x=100, y=80)

ventana.after(1, update_label)
ventana.mainloop( )

Resultado obtenido al ejecutar el programa Python

224
Wi-Fi con ESP8266.
El chip ESP8266 brinda la posibilidad de conexin a una red Wi-Fi con
mucha facilidad sin importar la arquitectura del micro utilizado. (ARM,
PIC, ATMEL etc).
Soporta el protocolo 802.11 y tiene capacidad para Wi-Fi Direct (P2P),
integra el stack TCP/IP con un ncleo Cortex M3 con arquitectura RISC
de 32bits a 80Mhz. Cuenta con 64KBytes de RAM para instrucciones y
96KBytes de RAM para datos. Los mdulos que usan este chip son de
varios fabricantes y vienen en diferentes formatos con distintos pines
para puertos GPIO, puertos de comunicaciones, un canal analgico.
Incluso algunos mdulos integran una memoria Flash SPI que se suma a
la memoria propia para guardar programas que controlan el propio
ESP8266 sin necesidad de un microcontrolador.
El firmware que trae por defecto solo permite controlarlo mediante
comandos AT por lo que no puede ejecutar ningn programa, para esto
hay que cambiar el firmware por otro, hay varios por ejemplo
NodeMCU, una plataforma abierta para la Internet de las Cosasque fue
desarrollada en China.
Cuando apareci el mdulo Wi-Fi ESP8266, el mundo de los hobbistas se entusiasm bastante ante el
surgimiento de un dispositivo capaz de entregar conectividad inalmbrica a plataformas de hardware a
un bajo costo, entre los entusiastas se encontraba un grupo de desarrolladores chinos de plataformas
abiertas de hardware, quienes se basaron en el ESP8266 para lanzar un kit llamado NodeMCU para el
desarrollo de prototipos compatible con Arduino, que se programa en Lua. NodeMCU ha sido bastante
bien recibido por la gente dedicada a desarrollar proyectos Hazlo-Tu-Mismo, pues permite el desarrollo
de sistemas como por ejemplo para el monitoreo de temperaturas y humedad ambiental en habitaciones
a un costo muy bajo.
Sin embargo el uso de este firmware no solo sirve para Arduino, tambin podemos usarlo en otras
arquitecturas como por ejemplo ARM.
Para los comandos AT la comunicacin se realza mediante una conexin UART, y cualquier programa
terminal sirve sin embargo el programa que usemos debe enviar un final de lnea en cada transmisin.
Para actualizar el firmware se debe usar un programa especial que permite el acceso a la Flash o
memoria de programa.
Este procedimiento puede inutilizar de manera permanente el modulo Wi-Fi si no se realiza
correctamente.
Es importante conocer el origen del firmware que se est cargando en el mdulo, hay muchas versiones
modificadas en Internet y no todas funcionan correctamente, adems ser necesario cargar los
parmetros de acceso a nuestra red Wi-Fi lo que en definitiva es abrir una puerta al mundo en nuestra
propia red con los consabidos riesgos de seguridad.
Siempre conviene descargar las versiones oficiales desde el sitio de Espressif, fabricante del chip.
Descargaremos los firmware denominados como based on ESP8266_NONOS_SDK_Vx.x.x. La
denominacin NONOS significa sin sistema operativo y responden a comandos AT.

La conveniencia de cambiar de firmware esta en relacin con lo que necesitamos hacer y con el tipo de
mdulo que tenemos, para cambiar de firmware es importante contar con memoria de programa, Lua es
un lenguaje interpretado y es necesario cargar el interprete Lua en el ESP8266 para que este pueda
correr los programas, si tenemos un mdulo que tiene pocos pines GPIO, sin memoria exterior

227
Para esto enviamos AT+CWJAP=nombre_de_la_red,clave, esperamos un momento y si todo est
correcto responder OK. Para saber que direccin IP nos ha asignado enviamos el comando AT+CIFSR
que nos informa el IP por ejemplo podemos tener una respuesta como la que se aprecia en la siguiente
imgen.

En el caso que nuestro mdulo este en modo 3, tendremos como respuesta dos direcciones IP, una ser
192.168.4.1 que es la que corresponde al modo 2 asignada por el propio DHCP interno, (esta direccin
no se puede cambiar) y la otra ser la que nos asigna el servidor DHCP de nuestra red.
El paso siguiente ser crear un socket UDP con el ESP8266 que reporte el voltaje presente en un canal
analgico a un servidor. En la siguiente imagen se aprecia como los datos son representados tanto en
una pantalla LCD y en la computadora.

Se ha definido una pequea funcin que se encarga de configurar el ESP8266 para la creacin del
socket, esta funcin asume que los parmetros de red (SSID y Password) ya fueron cargados
anteriormente.
El programa principal del proyecto es el siguiente. (El servidor Python se encuentra dentro de a
carpeta con el ejemplo).
/***********************************************************************
* Descripcin : Envo de datos con un modulo WiFi ESP8266. Se conecta
* a la red enviando los datos de un canal analgico
* Los datos tambin se muestran en un LCD 16x2.
* Target : STM32F407VG
* ToolChain : MDK-ARM
* IDE : uVision 5
* www.firtec.com.ar
*
************************************************************************/
// Conexiones del LCD al controlador
//------------------------------------
// Pin RW GPIOE_4
// Pin RS GPIOB_2
// Pin E GPIOB_7

231
tiempo_UDP++;
if(tiempo_UDP == 100){ // Espera
Enviar_String(floatStr); // Enva el dato al socket
tiempo_UDP =0;
}
}
}

Tambin podramos enviar los datos de temperatura y humedad con el sensor HDC1000.

Datos recibidos en el Socket Servidor

En este ejemplo se ha usado la misma biblioteca que se usara en el ejemplo del HDC1000 con su
configuracin I2C.
La funcin principal de este ejemplo es la siguiente.
int main(void) {
TM_DELAY_Init();
Config_USARTx();
Config_I2C1();
lcd_init();
device_id = Leer_SensorID();
lcd_locate(0,0);
if(device_id != 0x1000){
lcd_str(" HDC1000 ERROR!");
while(1);
}
Config_Sensor();
Delayms(1000);
lcd_locate(0,0);
lcd_str("Espere........");
Configurar_ESP8266();
lcd_locate(0,0);
lcd_str(" ECP8266 WiFi");

while (1){
Delayms(500);
Leer_Sensor();
sprintf(floatStr,"%2.1f - %2.1f%% ", temperature,humidity);
Enviar_String(floatStr);
sprintf(floatStr,"T:%2.1f",temperature);

235
El sensor se vincula con el procesador mediante un bus I2C con identificador I2C 0x44.

OPT3001 en funcionamiento

En el siguiente ejemplo podemos ver como implementar el uso de este sensor.


/***********************************************************************
* Descripcin : Medicin de luz ambiente en el rango de visin del
* ojo humano con el sensor OPT3001
* Target : STM32F407VG
* ToolChain : MDK-ARM
* IDE : uVision 5
* www.firtec.com.ar
*
************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "lcd_hd44780_lib.h"
#include "tm_stm32f4_delay.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include ".\OPT3001_Driver\OPT3001_Driver.h"

char floatStr[10];
char txt_viejo[10];
unsigned char temp;

237
interrumpa la lnea L, ocurrir lo contrario. Esta situacin permite que el sistema siga trabajando con
uno de los cables cortados o comunicados a masa.

Es importante tener en cuenta que el trenzado entre ambas lneas sirve para anular los campos
magnticos, por lo que no se debe modificar en ningn caso ni el paso ni la longitud de dichos cables.
Dado que la lnea es un par trenzado se necesitan resistencias de terminacin 120 ohm en ambos
extremos del bus, solo colocar la resistencias en los extremos no en los nodos individuales.

El controlador STM32F407VG tiene dos puertos CAN, estos puertos tienen todo lo necesario a nivel
lgico para el tratamiento de las tramas CAN sin embargo para implementar las comunicaciones se
necesita la capa fsica (al igual que Ethernet, RS-232, etc).

La capa fsica la implementamos con un integrado muy popular en el mundo CAN que ademas de ser
muy econmico funciona muy bien y se puede conseguir ya montado en una placa como se ve en la
imagen. Para verificar el funcionamiento del CAN inicialmente no necesitamos la capa fsica puesto

240
CanRxMsg RxMessage;
CAN_Receive(CAN2,CAN_FIFO0, &RxMessage);
CAN2_ID=RxMessage.StdId;
CAN2_Dato0=RxMessage.Data[0];
CAN2_Dato1=RxMessage.Data[1];
CAN2_Dato2=RxMessage.Data[2];
CAN2_Dato3=RxMessage.Data[3];
CAN2_Dato4=RxMessage.Data[4];
CAN2_Dato5=RxMessage.Data[5];
CAN2_Dato6=RxMessage.Data[6];
CAN2_Dato7=RxMessage.Data[7];
CAN_ClearITPendingBit(CAN2,CAN_IT_FMP0);
Bandera_Can2 = ENABLE;
}

Resultado obtenido al ejecutar el programa.

255