#include #include #include volatile uint32_t ISR_Ticks = 0; struct TASK { void (*fn)(void); uint32_t counter; uint32_t counter_rst; }; uint8_t Tasks_len = 0; struct TASK Tasks[8]; void SysTick_Handler() { ISR_Ticks++; } bool addTask(void (*fn)(void), uint32_t counter, uint32_t counter_init) { if (Tasks_len >= 8) { return false; } Tasks[Tasks_len].fn = fn; Tasks[Tasks_len].counter = counter_init; Tasks[Tasks_len].counter_rst = counter; Tasks_len++; return true; } void taskGreen() { GPIOD->ODR ^= GPIO_ODR_OD12; } void taskOrange() { GPIOD->ODR ^= GPIO_ODR_OD13; } void taskRed() { GPIOD->ODR ^= GPIO_ODR_OD14; } void taskBlue() { GPIOD->ODR ^= GPIO_ODR_OD15; } enum STATE { STATE_GREEN, STATE_ORANGE, STATE_RED }; int main(void) { // GPIO Port D Clock Enable RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN; // GPIO Port D Pin 15 down to 12 Push/Pull Output GPIOD->MODER = GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0; // Set all leds off GPIOD->ODR = 0; // SysTick enable with interupt and clk source to AHB/8 SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk; SysTick->LOAD = 2000; // 1 ms / (16 MHz / 8) addTask(*taskGreen, 200, 100); addTask(*taskOrange, 500, 200); addTask(*taskRed, 750, 300); addTask(*taskBlue, 300, 400); // Do forever: while (1) { // Wait a moment while (ISR_Ticks == 0) { __asm__(" WFI"); // sleep until SysTick } uint32_t ticks = ISR_Ticks; ISR_Ticks = 0; // decrement all counters for (uint8_t i=0; i ticks) { Tasks[i].counter -= ticks; } else { Tasks[i].counter = 0; } } // rust all tasks where the counter has run out for (uint8_t i=0; i