#include "stm32c0xx_hal.h"
#include "FreeRTOS.h"
#include "task.h"
// Task Handles
TaskHandle_t HLO;
TaskHandle_t HLG;
TaskHandle_t HLB;
TaskHandle_t HLR;
uint16_t ledBl = GPIO_PIN_0; // Blue LED, PA0
uint16_t ledOr = GPIO_PIN_1; // Orange LED, PA1
uint16_t ledGr = GPIO_PIN_4; // Green LED, PA4
uint16_t ledRd = GPIO_PIN_11; // Red LED, PA11
void ToggleLED(void* p);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
// задачи для каждого светодиода
xTaskCreate(ToggleLED, "LED_BL", 128, &ledBl, 1, &HLB);
xTaskCreate(ToggleLED, "LED_OR", 128, &ledOr, 2, &HLO);
xTaskCreate(ToggleLED, "LED_GR", 128, &ledGr, 3, &HLG);
xTaskCreate(ToggleLED, "LED_RD", 128, &ledRd, 4, &HLR);
// ядро
osKernelStart();
// планировщик задач FreeRTOS
vTaskStartScheduler();
while (1)
{
}
}
void ToggleLED(void* p)
{
uint16_t pin = *((uint16_t*) p);
GPIO_TypeDef* port = GPIOA;
TaskHandle_t* selfHandle = NULL;
if (pin == ledBl) selfHandle = &HLB;
else if (pin == ledOr) selfHandle = &HLO;
else if (pin == ledGr) selfHandle = &HLG;
else if (pin == ledRd) selfHandle = &HLR;
TickType_t xLastWakeTime = xTaskGetTickCount();
TickType_t xSyncTime = xTaskGetTickCount();
const TickType_t xStandardFrequency = 500 / portTICK_PERIOD_MS;
const TickType_t xSyncFrequency = 2500 / portTICK_PERIOD_MS;
while (1)
{
HAL_GPIO_TogglePin(port, pin);
vTaskDelayUntil(&xLastWakeTime, xStandardFrequency + (pin % 3) * 100);
// каждые 5 секунд синхронизируем светодиоды
if ((xTaskGetTickCount() - xSyncTime) / portTICK_PERIOD_MS >= 5000) {
HAL_GPIO_WritePin(port, ledBl | ledOr | ledGr | ledRd, GPIO_PIN_SET); // включаем все
vTaskDelay(xSyncFrequency); // задержка на время синхронизации
HAL_GPIO_WritePin(port, ledBl | ledOr | ledGr | ledRd, GPIO_PIN_RESET); // выключаем все
// глушим задачу управления синим светодиодом
if (selfHandle == &HLB) {
vTaskSuspend(NULL);
vTaskDelay(1500 / portTICK_PERIOD_MS);
vTaskResume(HLB);
}
xSyncTime = xTaskGetTickCount(); // сброс таймера синхронизации
}
}
}
void MX_GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
HAL_RCC_OscConfig(&RCC_OscInitStruct);
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
}
void vApplicationIdleHook(void) {}