2.2 Base de tiempos
Utilizaremos el temporizador SysTick para establecer una base de tiempos en el microcontrolador. Esto nos permitirá ejecutar acciones en intervalos regulares, y programar la ejecución de tareas.
¿Qué es SysTick?
SysTick (System Timer) es un temporizador de cuenta descendente de 24 bits disponible en los microcontroladores ARM Cortex-M. Se emplea para generar eventos periódicos, medir intervalos de tiempo, y como base temporal para programar tareas.
Diagrama de bloques de Systick:
System Timer (SysTick).
Registros de SysTick
El módulo SysTick se controla mediante los siguientes registros accesibles desde el espacio de memoria del procesador:
SYST_CSR(Control and Status Register):bit 0 (ENABLE): habilita/deshabilita el temporizador (1 = activo).
bit 1 (TICKINT): habilita la interrupción al llegar a 0 (1 = habilitada).
bit 2 (CLKSOURCE): selecciona la fuente de reloj (1 = HCLK del procesador, 0 = reloj externo).
Bit 16 (COUNTFLAG): se pone a 1 cuando el contador pasa de 1 a 0; se borra al leer
SYST_CSR.
SYST_RVR(Reload Value Register):Valor de recarga del contador.
Valor Máximo:
0x00FFFFFF(24 bits).El número de ciclos que transcurren entre recargas es
SYST_RVR + 1.
SYST_CVR(Current Value Register):Valor actual del contador.
Se recarga automáticamente desde
SYST_RVRal alcanzar 0.Escribir en este registro lo reinicia a 0.
Funcionamiento básico
Al poner a 1 el bit ENABLE en
SYST_CSR,SYST_CVRse carga conSYST_RVRy comienza a decrementarse en cada ciclo de reloj.Cuando
SYST_CVRpasa de 1 a 0 se activa COUNTFLAG (bit 16 deSYST_CSR).En el ciclo siguiente el contador
SYST_CVRse recarga automáticamente desdeSYST_RVRy continúa contando.
Funcionamiento del System Timer (SysTick).
Nota: el temporizador se detiene cuando el procesador entra en modo de
depuración (debug). Además, la lectura de SYST_CSR limpia COUNTFLAG.
Recursos HAL_Systick
Para facilitar el uso de SysTick en nuestras aplicaciones disponemos del módulo
HAL_SysTick, que se encuentra en el archivo de recursos (HAL_SysTick.c,
HAL_SysTick.h).
Este módulo proporciona funciones para configurar y utilizar SysTick en modo encuesta (polling). De este modo, podemos comprobar periódicamente si SysTick ha desbordado (llegado a 0) y ejecutar acciones en consecuencia.
Incluye las siguientes funciones:
/**
* @brief Configura SysTick en modo encuesta
* @details Inicializa SysTick en modo `free-running` generando eventos
* periódicamente, no genera interrupciones.
* @param [in] ticks Número de ticks (ciclos de reloj) entre dos eventos.
* @return 0 Ejecución exitosa.
* @return 1 Fallo en la ejecución.
* @note Da valor a los registros SYST_RVR y SYST_CSR.
* SYST_CSR se configura con los valores:
* CLKSOURCE => 1 (HCLK)
* ENABLE => 1
* others => 0
*/
uint32_t SysTick_Init(uint32_t ticks);
/**
*
* @brief Comprueba si ha habido overflow en SysTick
*
* @return 0 No ha habido overflow. (COUNTFLAG=0)
* @return 1 Ha habido overflow. (COUNTFLAG=1)
*
* @note Después de ejecutar la función COUNTFLAF=0
*/
uint32_t SysTick_ChkOvf(void);
Ejercicio 1: Base de tiempos con SysTick
Preparación del entorno.
Abre el proyecto lab2 en Keil.
Selecciona el target
lab2.0.
Tareas a realizar.
Completa el código
lab2.0.c, esta aplicación debe utilizar SysTick para cambiar el pin P7D/D8 cada 1 ms.nota: Para iniciar SysTick podemos utilizar el macro
SystemCoreClockque se expande a la frecuencia de reloj del µP, este caso 200.000.000, por lo tanto para 1ms el argumento de la función ticks seráSystemCoreClock/1000.
// includes, recursos externos que se van a utilizar (ficheros.h) #include "HAL_FM4_gpio.h" ... // no utilizamos variables globales int main(void) { // Configuración de periféricos: // - Config GPIO para utilizar leds y sw2 ... // -Config pin P7D/D8: // Pin P7D/D8 como salida // Pin P7D/D8 a 0 ... // -Config SysTick (1ms): SysTick_Init(SystemCoreClock / 1000U); // Ejecutivo cíclico while (1) { if (.......) // Si SysTick ha desbordado { GPIO_ChannelToggle(P7D); // Actualiza P7D/D8 } } }
Verificación del funcionamiento.
Compila y programa el microcontrolador.
Verifica utilizando los timers de Keil que la función
GPIO_ChannelToggle(P7D)se ejecuta cada 1ms.Conecta el osciloscopio como se hizo en lab1 para comprobar que P7D/D8 cambia cada 1ms:
Pin P7D/D8.