Arquitectura Software
Visión general
El firmware sigue una arquitectura simple basada en interrupciones con un bucle principal de baja frecuencia. La ISR del SysTick ejecuta las tareas de tiempo real (lectura del sensor y cálculos cinemáticos) mientras que el bucle principal se limita a imprimir resultados y hacer parpadear el LED.
Módulos
| Módulo | Archivos | Función |
|---|---|---|
| setup | setup.c, setup.h |
Configuración de relojes, periféricos y GPIO |
| h3lis | h3lis.c, h3lis.h |
Driver SPI del H3LIS331DL y cinemática MeltyBrain |
| delay | delay.c, delay.h |
Delays por SysTick (ms) y DWT (µs) |
| usart | usart.c, usart.h |
Redirección de printf a USART1 |
| config | config.h |
Constantes del sistema (frecuencias, π) |
| main | main.c |
Punto de entrada y bucle principal |
Bucle principal
flowchart TD
A[Inicio] --> B[setup]
B --> C[Init relojes 84 MHz]
C --> D[Init SysTick 1 kHz]
D --> E[Init GPIO / SPI / USART]
E --> F[Init H3LIS331]
F --> G{WHO_AM_I == 0x33?}
G -->|No| H[LED blink rápido 50 ms]
H --> H
G -->|Sí| I[Bucle principal]
I --> J[printf datos]
J --> K[Toggle LED]
K --> L[delay 200 ms]
L --> I
El bucle principal opera a ~5 Hz (200 ms de delay) y su única función es imprimir por USART los valores calculados por la ISR y hacer parpadear el LED. Toda la lógica de adquisición y cinemática ocurre en la ISR del SysTick.
ISR del SysTick
| Parámetro | Valor |
|---|---|
| Frecuencia | 1000 Hz |
| Período | 1 ms |
| Prioridad | 16 (grupo 1) |
flowchart TD
A[SysTick IRQ] --> B[clock_tick]
B --> C[h3lis_update]
C --> D[Lectura SPI burst 6 bytes]
D --> E["Conversión raw → g"]
E --> F["Cálculo a_c"]
F --> G{"a_c ≥ umbral?"}
G -->|Sí| H["Cálculo ω = √(a_c/r)"]
H --> I["Cálculo RPM"]
I --> J["Integración ángulo Δt=1ms"]
G -->|No| K["ω = 0, RPM = 0"]
J --> L["Normalización [0, 2π)"]
K --> L
L --> M[Fin ISR]
La ISR ejecuta en cada tick (1 ms) la lectura completa del sensor SPI y todos los cálculos cinemáticos. Los resultados se almacenan en una variable estática (h3lis_data) accesible desde el bucle principal mediante getters.
Flujo de datos
flowchart LR
subgraph ISR [ISR SysTick 1 kHz]
SPI[SPI burst read] --> RAW[Raw x,y,z int16]
RAW --> CONV[Conversión a g]
CONV --> KIN[Cinemática]
KIN --> DATA[h3lis_data]
end
subgraph MAIN [Bucle principal ~5 Hz]
DATA --> GET[Getters]
GET --> PRINT[printf USART1]
GET --> LED2[LED toggle]
end
Nota: No hay mecanismo de sincronización explícito entre la ISR y el bucle principal. Las lecturas de
floaten Cortex-M4 son atómicas por hardware (single-precision), pero no hay garantía de consistencia entre campos (ej.axnuevo conayviejo). Para una demo esto es aceptable; en producción se añadiría un double buffer o spinlock.
Arranque del sistema
La función setup() inicializa el hardware en el siguiente orden:
| Paso | Función | Descripción |
|---|---|---|
| 1 | setup_clock() |
HSE 25 MHz → PLL → SYSCLK 84 MHz. Habilita relojes de GPIOA, GPIOC, SYSCFG, USART1, SPI1. Habilita DWT. |
| 2 | setup_systick() |
SysTick a 1 kHz con interrupciones. |
| 3 | setup_timer_priorities() |
NVIC: SysTick prioridad 16, USART1 prioridad 32. Habilita IRQ de USART1. |
| 4 | setup_gpio() |
Configura LED (PC13 out), USART1 (PA9/PA10 AF7), SPI1 (PA5/PA6/PA7 AF5), CS (PA0 out). |
| 5 | setup_usart() |
USART1: 115200 baud, 8N1, sin flow control. |
| 6 | setup_mpu() |
SPI1 a 5.25 MHz (DIV_16), Modo 0, software NSS. Llama a h3lis_init(). |
Documento generado el 2026-06-27. Ver también Hardware, Sensores, Cinemática.