Saltar a contenido
← Volver a OPRobots.org

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 float en Cortex-M4 son atómicas por hardware (single-precision), pero no hay garantía de consistencia entre campos (ej. ax nuevo con ay viejo). 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.