Curso introductorio a la arquitectura ARM con Cortex M4

Curso introductorio a la arquitectura ARM con Cortex M4 Microcontrolador STM32F407VG Firtec Capacitación Técnica Realizado y editado por: ` Call...
0 downloads 3 Views 2MB Size
Curso introductorio a la arquitectura ARM con Cortex M4

Microcontrolador STM32F407VG

Firtec Capacitación Técnica

Realizado y editado por:

`

Calle San Lorenzo 2755 – Rosario (Santa Fe) (S2000KPK) ARGENTINA e-mail: [email protected] [email protected] Revisión: Julio 2015

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 Características 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 Características de la placa entrenadora................................................................................................21 Configurando el entorno de trabajo.....................................................................................................26 Puedo programar el microcontrolador sin un programador específico?.............................................30 Mi Primer Programa en KEIL.............................................................................................................31 Capitulo II................................................................................................................................................41 Interrupciones......................................................................................................................................41 Temporizador del sistema (SysTick)...................................................................................................48 Funcionamiento de la USART.............................................................................................................57 Conversor Analógico con STM32F407VG.........................................................................................64 Capitulo III...............................................................................................................................................67 Pantalla LCD 16x2 con STM32..........................................................................................................67 Voltímetro con pantalla LCD 16x2.................................................................................................69 Midiendo la temperatura del Núcleo Cortex..................................................................................71 Canales DMA......................................................................................................................................77 Modo DMA de doble buffer................................................................................................................90 Emular memoria EEPROM en FLASH..............................................................................................90 Protocolo I2C......................................................................................................................................93 Puerto SDIO con STM32..................................................................................................................103 Memoria SD con FAT........................................................................................................................108 Ejemplo de manejo de FAT con STM32.......................................................................................115 Creando un disco extraíble a partir de una memoria SD..............................................................119 Control PID.......................................................................................................................................121 Funcionamiento general de un PID..............................................................................................122 Control PID con STM32F407......................................................................................................122 Datalogger de temperatura................................................................................................................127 Capitulo IV.............................................................................................................................................134 FSMC (Flexible Static Memory Controller)....................................................................................134 Pantallas TFT................................................................................................................................134 3

Sensor de imagen OV7670 con STM32F407...............................................................................141 Formato de la imagen...................................................................................................................142 RGB..............................................................................................................................................142 Señales de la camara.....................................................................................................................144 SCCB (Serial Camera Control Bus).............................................................................................146 Estructura del proyecto DCMI_OV7670......................................................................................148 Manejo del Touch-Screen.............................................................................................................151 Protocolo 1-wire................................................................................................................................157 Niveles eléctricos del bus.............................................................................................................157 Envío y recepción de datos...........................................................................................................158 Ejemplo con 1-Wire y el sensor DS18B20 & UART...................................................................158 Ejemplo con 1-Wire y el sensor DS18B20 & LCD TFT..............................................................162 Ethernet y MII (Media Independent Interface).................................................................................165 Señales del transmisor Ethernet....................................................................................................165 Señales del receptor Ethernet........................................................................................................165 Reducción Media Independent Interface (RMII).........................................................................166 El stackt LwIP controlando LED´s mediante CGI.......................................................................168 SSI (Server Side Include).............................................................................................................172 CAN BUS ( Controller Area Network).............................................................................................176 CAN BUS Loop Back (Sin la capa física)...................................................................................178 CAN NORMAL (Con la capa física)...........................................................................................186 Bibliografía............................................................................................................................................194 Carpetas con Ejemplos (Opcional).........................................................................................................195 Carpeta con Herramientas (Opcional)....................................................................................................196

4

Características heredadas de RISC. La arquitectura ARM incorporó algunas características del diseño RISC de Berkeley, aunque no todas. Las que se mantuvieron son: • Arquitectura de carga y almacenamiento(load-store). Las instrucciones que acceden a memoria están separadas de las instrucciones que procesan los datos, ya que en este último caso los datos necesariamente están en registros. • Instrucciones de longitud fija de 32 bits. Campos de instrucciones uniforme y de longitud fija para simplificar la decodificación de las instrucciones. • Formatos de instrucción de 3 direcciones. Consta de “f” bits para el código de operación, “n” bits para especificar la dirección del 1er. operando, “n” bits para especificar la dirección del 2do. operando y “n” bits para especificar la dirección 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 diseño, se adapta mejor a sistemas de tecnología de procesos. Mayor rendimiento. Si se diseña un procesador simple y luego se le agregan instrucciones complejas hará en forma más eficiente varias funciones de alto nivel pero también decaerá un poco el reloj para el conjunto de las instrucciones. Midiendo los beneficios de esta técnica en programas típicos se comprueba que todos los sets de instrucciones complejos hacen que el programa corra a menor velocidad.

Desventajas de RISC. • •

No ejecuta códigos x86.Pero hay programas de emulación para varias plataformas RISCs. Pobre densidad de código. Comparada con CISC. Ésto es consecuencia del set de instrucciones de longitud fija. En ausencia de memoria caché, esta pobre densidad de código significa que la búsqueda de la instrucción 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 interconexión de bloques de propiedad intelectual para formar “Sistemas On Chip”, es decir, circuitos integrados formados por varios procesadores y periféricos, interconectados en un bus común. Los procesadores ARM utilizan esta arquitectura para interconexión de los diferentes bloques internos que forman el chip. Podemos ver en el gráfico 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 operación 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 fáciles de predecir ya que otros periféricos 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 módulo una de las configuraciones que debemos incluir es activar y el reloj y determinar una frecuencia de operación dentro del rango que el bus admite.

Pipeline. Se llama “pipeline” a la técnica que aprovecha un método para optimizar los recursos de hardware y también el rendimiento del procesador. Consiste en comenzar a procesar una instrucción antes de que se haya finalizado de procesar la actual. En la siguiente figura se ilustra la ejecución de instrucciones con la técnica pipeline.

Tomando la secuencia de operaciones a partir de la instrucción “1”, el procesador se organiza de tal manera que tan pronto como haya completado la primera etapa de esa instrucción, “fetch” y haya avanzado hacia la segunda etapa, comenzará la primera etapa, “fetch”, de la próxima instrucción. En principio, de esta manera el tiempo de ejecución debería ser hasta seis veces más veloz que el que corresponde a instrucciones no superpuestas pero, como veremos luego, en la práctica no ocurre así. Una de las características clave del alto desempeño de los microcontroladores ARM es el pipeline. ARM7 tiene un pipeline de tres etapas que aumentan el flujo de instrucciones a través del procesador. Así que cada instrucción se ejecuta en tres etapas: 1) Recoger: Se lee la instrucción de la memoria y se coloca en el pipeline 2) Decodificar: Se decodifica la instrucción. 3) Ejecutar: Se ejecuta la instrucción.

12

El pipeline se implementa en el nivel de hardware. Pipeline es lineal, lo que significa que el procesador ejecuta una instrucción mientras está cargando otra para ser decodificada. Si bien esto suena interesante presenta problemas con los saltos, por ejemplo cuando una instrucción necesita de un dato que todavía no ha sido decodificado por lo que se ve obligado a esperar la ejecución de la instrucción que contiene la información, esto se mejora con técnicas predictivas a nivel de hardware.

Registros del Procesador.

Existen trece registros de propósito general todos de 32 bits, otra gran diferencia con microcontroladores menores donde solo existen un registro de trabajo y la interacción de nuestras aplicaciones con este registro es fácilmente 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 información de declaraciónes 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 ejecución, por ejemplo si un número es negativo o cero entre otras cosas. Luego de un RESET el PC se carga con el valor 0x00004 y el M4 puede dirección hasta un límite teórico de 4GB.

13

FPU. Este bloque opcional agrega un conjunto extra de treinta y dos registros para números en coma flotante de simple precisión (32-bits), de S0 a S31. A su vez, cada par de estos registros puede verse como un registro de 64-bits, es decir, una double-word. Un registro adicional, el FPSCR (Floating-Point Status and Control Register) contiene los bits de estado (N, Z, C, V) y las excepciones ocurridas (por ejemplo una división por cero). El set de instrucciones reserva una serie de opcodes para ser utilizados por coprocesadores. En la arquitectura, existen además espacios de registros asignados acorde al identificador del coprocesador. En ARMv7-M se encuentran permitidos sólo dos coprocesadores, CP10 y CP11, mediante los cuales se accede a la FPU. De este modo, accedemos a los registros mediante instrucciones adicionales. La FPU provee entonces más de treinta instrucciones adicionales para soportar números en coma flotante, entre las cuales encontramos suma y multiplicación en un ciclo de clock, división en catorce ciclos, y multiplicación y acumulación en tres ciclos de clock. La FPU puede ser habilitada o no, en las opciones del proyecto del KEIL se puede configurar esto. Internamente, la FPU opera con una pipeline de tres etapas totalmente independiente

ARM y Thumb. Se llama densidad de código a la medida de cuánta memoria necesita un sistema embebido para contener instrucciones. Frecuentemente en los sistemas embebidos hay una limitación al tamaño de la memoria. Esto es especialmente cierto para los sistemas con la memoria dentro del chip, en los cuales la memoria normalmente ocupa más espacio en el chip que la propia CPU, por ejemplo la memoria caché. La arquitectura del procesador ARM se basa en los principios RISC aunque tiene aún mejor densidad de código que la mayoría de los procesadores RISC. Sin embargo, su densidad de código todavía no alcanza a ser tan buena como la de los procesadores CISC. Para las aplicaciones en que es primordial la importancia de la densidad del código, ARM incorporó un novedoso mecanismo llamado arquitectura Thumb. El set de instrucciones Thumb es una forma comprimida a 16 bits del set de instrucciones de 32 bits original y emplea hardware de descompresión dinámica en la instrucción pipeline, para descomprimir las instrucciones de 16 a 32 bits. Por supuesto, la etapa extra requerida para manejar instrucciones de 16 bits afecta el rendimiento. La densidad del código Thumb es mejor que la alcanzada por la mayoría de los procesadores CISC. El set de instrucciones Thumb usado para obtener alta densidad de código en varios procesadores ARM utiliza, predominantemente, una arquitectura de dos direcciones. Se puede llevar a cabo un nuevo ajuste en el número de bits que se requiere para almacenar una instrucción haciendo que el registro de destino coincida con alguno de los registros fuente.

Modos de Funcionamiento. Tiene varios modos básicos de funcionamiento. El cambio de modo se puede hacer bajo control del software o puede ser causado por interrupciones. La mayoría de los programas de aplicaciones se ejecutan en modo usuario. 14

Mientras el procesador está en modo usuario, el programa que se está ejecutando no puede acceder a recursos protegidos del sistema o cambiar de modo. Esto permite escribir un sistema operativo adecuado para controlar el uso de los recursos del sistema.

Modo usuario (Thread ). Sin privilegios, bajo el cual corren la mayoría de las aplicaciones. Modo de ejecución normal de los programas. Los programadores a nivel de usuario deben tener en cuenta que solo pueden acceder a las funciones a nivel del sistema a través de llamadas del supervisor. Generalmente estas funciones incluyen cualquier acceso a los registros periféricos del hardware y operaciones frecuentes, tales como entrada y salida de caracteres. Los restantes modos son privilegiados y se llaman excepciones.

Modos de Privilegios (Handler). •

• •

• • •





Modo supervisor, SVC Supervisor Mode. Entra en este modo con el reset o cuando se ejecuta una interrupción de software, SWI Software Interrupt. Modo protegido para sistema operativo. El mecanismo de protección asegura que el código del usuario no pueda obtener los privilegios del supervisor sin los controles apropiados a fin de asegurar que este código no intente operaciones ilegales. Modo instrucción indefinida, UND Undefined Mode. Se usa este modo para manejar instrucciones indefinidas. Soporta emulación de software de coprocesadores de hardware. Modo interrupciones de alta prioridad FIQ Fast Interrupt Request Mode. Entra en este modo cuando aparece una interrupción de alta prioridad (fast). Soporta un proceso de transferencia de datos o canal de alta velocidad. Modo interrupciones de baja prioridad o normales,IRQ, Normal interrupt request Mode. Entra en este modo cuando aparece una interrupción de baja prioridad (normal). Usado para manejar interrupciones de propósitos generales. Modo aborto, ABT, Abort Mode. Se usa para manejar violaciones de acceso a memoria. Aborto por una fallo de memoria al leer una instrucción (instruction fetch memory fault) o al acceder a un dato (data abort). Modo sistema SYS, System Mode. Modo privilegiado que usa los mismos registros que el modo usuario. Corre tareas privilegiadas del sistema operativo (arquitectura ARM versión 4 y superiores).Se entra en ellos cuando aparece una excepción específica. Tienen acceso a todos los recursos y pueden cambiar libremente de modo. Cada uno de ellos tiene registros adicionales para evitar que cuando ocurre una excepción se arruinen los registros del modo usuario. Al modo sistema, presente solamente a partir de la arquitectura ARM 4, no se entra con cualquier excepción y participa de los mismos registros que el modo usuario. Sin embargo, es un modo privilegiado y, por lo tanto, no está sujeto a las restricciones del modo usuario. Se entra en él para usar tareas del sistema operativo que necesitan acceder a recursos de éste, pero deseando evitar el uso de registros adicionales asociados con el modo de excepción. Así se evita que el estadode la tarea no se corrompa por la aparición de cualquier excepción.

Normalmente y para simplificar, haremos referencia a dos modos para el Cortex M4. • •

Modo Thread: Es el modo normal de uso, entra en este modo luego de un RESET. Modo Handler: Pasa a este modo cuando se ejecuta una interrupción o una excepción, luego de finalizado regresa al modo Thread. Puede trabajar en modo “Con Privilegios” y “Sin 15

Privilegios”. El primero es la forma normal de uso teniendo acceso a puertos, interrupciones y memoria en general. El segundo modo de trabajo no permite interrupciones y se restringe el acceso a memoria y puertos.

El sistema de memoria ARM. Además del estado de registros del procesador, un sistema ARM tiene estado de la memoria. La memoria se puede ver como un arreglo lineal de bytes numerados desde cero hasta 232– 1. Los datos pueden ser de bytes (8 bits), de medias palabras ( Half Word 16 bits) o palabras ( Word 32 bits). Las palabras están siempre alineadas en bandas de 4 bytes (esto es, los 2 bits de direcciones menos significativos son cero, porque son múltiplos de 4) y las medias palabras están alineadas en bandas de pares de bytes (porque son múltiplos de 2). Un byte puede ocupar cualquiera de estas posiciones de memoria. El dato de tamaño de una palabra debe ocupar un grupo de posiciones de cuatro bytes que comienzan en una dirección que es un múltiplo de cuatro y tiene sus cuatro bits menos significativos en 0. Esta es la organización de memoria littleendian usada por Intel y por ARM. Algunos ARM se puede configurar para trabajar como big-endian, que es la configuración adoptada por Motorota y por los protocolos TCP, entre otros, donde los bytes se escriben en el orden natural en que se los lee. En la forma big endian, al tener primero el byte de mayor peso, se puede saber rápidamente si el número es positivo o negativo sólo comprobando el estado del bit más significativo del primer byte (recordemos que el signo se almacena en el bit más significativo) y sin necesidad de saber la longitud del número. Esta forma de representación coincide con el orden en que se escriben los números, de modo que las rutinas de conversión entre sistemas de numeración son más eficientes que si se realizaran en little endian.

NOTA: Como curiosidad, el nombre big endiany little endian se tomó irónicamente de "Los viajes de Gulliver", de Jonathan Swift, novela en la que los habitantes de los imperios de Lilliputy Blefuscu libran una encarnizada guerra por una disputa sobre si los huevos hervidos debería empezar a comerse abriéndolo por su extremo pequeño o por su extremo grande.

16

Aquí configuramos el entorno, las rutas de archivos y librerías, si en el paso anterior indicamos que usaremos librerías provistas por STM en este paso indicamos donde están estas librerías.

IMPORTANTE: MicroLib es una biblioteca altamente optimizado para aplicaciones embebidas escritas en C basados en ARM. Cuando se compara con la biblioteca de C estándar que se incluye con el compilador de ARM, MicroLib proporciona significativas ventajas en cuanto al tamaño de código requerido para muchos sistemas embebidos.

Recordar: Todos los trabajos ejemplos están para ser compilados con MICROLIB.

KEIL lo puede descargar directamente desde su pagina oficial.

28

Desde la lengüeta 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 específico? El controlador STM32F407VG y todos los dispositivos de STMicroelectronics tienen incorporado un cargador que funciona con el protocolo UART y que permite bajar nuestro código 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 través 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 módulo aparte agregado por STM para simplificar el proceso de grabación de la FLASH con la aplicación programada. 30

Capitulo II. Interrupciones. El M4 soporta 240 fuentes de interrupción con 256 niveles de prioridad. Cada interrupción tiene un vector (Interrupciones Vectorizadas) donde se aloja el código (ISR) que trata la interrupción. Hay un controlador para las interrupciones llamado NVIC (Nested Vector Interrupt Controller).

Hay dos formas de tratar las prioridades: preemption priorities y sub priorities. El que tiene mayor prioridad (preemption priorities) se ejecuta en primer lugar, cuando dos interrupciones tienen la misma prioridad el que tiene mayor prioridad secundaria (sub priorities) se ejecutará primero. Si ambas tienen igual prioridad y sub-prioridad la interrupción que ocurra primero se ejecutará primero (orden de llegada). Los procesadores Cortex M3 y M4 utilizan 8 bits para almacenar las prioridades y sub-prioridades separados en cinco grupos para elegir la forma en que procesamos la prioridad de la interrupción. Hay cinco grupos diferentes que podemos establecer. • • • • •

Grupo0 - 0 bits para el sobreseimiento, 4 bits para sub prioridad . Grupo1 - 1 bits para el sobreseimiento, 3 bits para sub prioridad . Group2 - 2 bits para el sobreseimiento, 2 bits para sub prioridad . Grupo3 - 3 bits para el sobreseimiento, 1 bits para sub prioridad . Grupo4 - 4 bits para el sobreseimiento, 0 bits para sub prioridad .

La función NVIC_PriorityGroupConfig configura los grupos de prioridades. Si elijo grupo 4 la sintaxis seria NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4) lo que me dejará 4 bits para NVIC_IRQChannelPreemptionPriority y 0 bits para NVIC_IRQChannelSubPriority. 41

En la configuración de pines se especifica: GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; Lo que indica que los pines han sido configurados como alternativos a un módulo de la unidad. Se detalla a continuación el listado del programa ejemplo. /********************************************************* * Nombre : USART.c * Descripción : Funcionamiento de la USART2 en Cortex M4. * Target : STM32F407VG * ToolChain : MDK-ARM * IDE : uVision 4 * www.firtec.com.ar **********************************************************/ #include "stm32f4xx_rcc.h" #include "stm32f4xx_gpio.h" #define USARTx

USART2 // Puerto que se usará

/* Esta función se utiliza para transmitir una cadena de caracteres a través * El USART especificado en USARTx. * La cadena tiene que ser pasado a la función como un puntero porque * El compilador no conoce el tipo de datos string. En C una cadena es sólo * un conjunto de caracteres. **/ void Enviar_String(const char *s) { while(*s) { while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, *s++); } } void Config_USARTx(void){

// Esta función configura el periférico USART2

TX=GPIOA_Pin_2 (RX) RX=GPIOA_Pin_3 (TX) RTS=GPIOA_Pin_1 (CTS) CTS=GPIOD_Pin_3 (RTS) GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Estructura para configurar las // interrupciones NVIC

Activa APB1 reloj periférico para USART2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

Activa el reloj periférico para los pines utilizadas por la USART2, PA3 para TX y RX para PA2 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

58

Len) es la encargada de transmitir donde Buf es un buffer donde se guardan los datos que serán transmitidos. Len es la cantidad de datos a transmitir y la función retorna USBD_OK si todo a salido bien, en caso contrario retorna VCP_FAIL. Para enviar datos la forma de implementar la función sería: VCP_DataTx (0,dato); Donde el 0 indica el EndPoint por donde se envía la información al USB, dato es el Byte enviado. Un detalle es que esta función solo envía Bytes no se pueden enviar cadenas. La función static int16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) es la encargada de recibir los datos que son almacenados en Buf siendo Len es la cantidad de datos recibidos. Notará que las funciones están declaradas como static lo que significa que las funciones solo se pueden acceder desde el módulo donde están declaradas. Si quiere tener acceso a estas funciones por ejemplo desde el main() debe quitar el static en la función y desde donde las llame agregar el modificador extern.

extern uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len); Al final de este archivo encontrará la siguiente función: void DISCOVERY_EXTI_IRQHandler(void) { VCP_DataTx (0,'F'); VCP_DataTx (0,'i'); VCP_DataTx (0,'r'); VCP_DataTx (0,'t'); VCP_DataTx (0,'e'); VCP_DataTx (0,'c'); }

Cada vez que se oprime el botón de usuario en la placa Discovery se envía por EndPoint 0 la palabra Firtec carácter por carácter. En el archivo usbd_desc.c encontramos todo lo referente al descriptor USB de la aplicación, si observa el contenido de este archivo verá que desde el se definen varias cosas como el PID-VID y en general la forma como la aplicación se identifica en el sistema, funciones clásicas de un descriptor USB. En usbd_usr.c encontrará cosas como estas: ////////////////////////////////////////////////////////////////////////////////// // Función que se ejecuta cuando el dispositivo se desconecta del puerto USB. ////////////////////////////////////////////////////////////////////////////////// void USBD_USR_DeviceSuspended(void) { STM32F4_Discovery_LEDOff(LED5); // Apaga LED rojo cuando desconecta // Aquí se puede poner el código para hacer algo cuando se desconecta del USB } ////////////////////////////////////////////////////////////////////////////////// // Función que se ejecuta cuando el dispositivo se conecta al puerto USB. ////////////////////////////////////////////////////////////////////////////////// void USBD_USR_DeviceResumed(void) { STM32F4_Discovery_LEDOn(LED5); // Enciende LED rojo cuando se conecta al USB // Aquí se puede poner el código para hacer algo cuando se conecta al puerto USB }

62

float numero_2 = 0.897; // Valor float a mostrar en la pantalla LCD int main(void){ HD44780_Init(16, 2); HD44780_Puts(0, 0,"STM32F4x Cortex"); sprintf(numStr,"D1:%d",numero); HD44780_Puts(0, 1,numStr); sprintf(floatStr," D2:%2.3f",numero_2); HD44780_Puts(7, 1,floatStr); while(1); } /*** fin del archivo *************************************************************/

En los archivos que conforman el driver de la pantalla LCD se pueden configurar los pines que se conectan al microcontrolador y cambiarlos según la necesidad. La función HD44780_Init(16, 2) Configura la pantalla en 16 caracteres visibles por dos líneas pudiendo ser 40 caracteres a cuatro líneas como máximo.

Trabajo practico Se pide que escriba un programa contador de 0 a 999 y se muestre el estado del contador en una pantalla LCD de dos líneas.

68

La idea es medir en cuatro canales analógicos (cuatro potenciómetros) y usar los canales DMA para procesar los datos. Usamos el módulo ADC3 que tiene asociado el canal 2 y el stream 0, también podríamos usar el stream 1 que está asociado al módulo ADC3. Los potenciómetros estarán conectados en GPC0, GPC1, GPC2 y GPC3. En la pantalla LCD deberíamos ver lo siguiente:

Esto depende de las siguientes líneas de código: HD44780_Puts(0, 0,"A1:"); HD44780_Puts(0, 1,"A2:"); HD44780_Puts(8, 0,"A3:"); HD44780_Puts(8, 1,"A4:"); while (1){ sprintf(datoStr,"%04d",ADC3ConvertedValue[0]); HD44780_Puts(3, 0,datoStr); sprintf(datoStr,"%04d",ADC3ConvertedValue[1]); HD44780_Puts(3, 1,datoStr); sprintf(datoStr,"%04d",ADC3ConvertedValue[2]); HD44780_Puts(11, 0,datoStr); sprintf(datoStr,"%04d",ADC3ConvertedValue[3]); HD44780_Puts(11, 1,datoStr); }

El módulo ADC está configurado para una resolución de 10 bits (0-1023). La configuración general para el modulo ADC es como sigue: ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div6; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure);

Específicamente para el ADC3 es como sigue: ADC_InitStructure.ADC_Resolution = ADC_Resolution_10b; // Resolución en 10bits ADC_InitStructure.ADC_ScanConvMode = ENABLE; 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);

Las líneas siguiente determinan el orden en que los canales serán leídos y la velocidad con que leemos los canales analógicos. 79

modo SD por defecto y no modo SPI, si se quiere trabajar en modo SPI hay algunos pasos para configurar su funcionamiento. En nuestro proyecto el driver para el manejo de la memoria se encuentra en los archivos SDIO.C y SDIO.H.

Aquí vamos a ver algunos detalles del manejo de estas memorias. • •

Bloque: Número fijo de Bytes ya sea para escribir o leer, típicamente un bloque tine 512 Bytes. Sector: Es el número de bloques a tratar.

Las memoria soportan dos modos de acceso, Modo Multiblock o Modo Simple Block, en este modo el tamaño máximo de datos posible es de 512 bytes (un bloque) pero el mínimo puede ser un solo byte. Para la lectura de varios bloques estos deben estar en el mismo sector. La escritura se hace en bloques (512 Bytes). Para el modo Multiblock el proceso es parecido solo que se procesan varios bloques siendo la dirección de inicio el inicio del sector, en este modo se habla de sectores siendo el tamaño mínimo a borrar/escribir un sector. Estas memorias típicamente soportan 100.000 ciclos de escritura/borrado. El ejemplo que vamos a ver escribe dos bloques, el bloque 1000 y el bloque 3001 que son completados con 512 bytes generados en el bucle: for (i=0;i

Suggest Documents