#include <Arduino_FreeRTOS.h> // Библиотека FreeRTOS для Arduino Core
#include <semphr.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
// Настройки пинов
#define LED_PIN PC13
#define BTN_UP PA0
#define BTN_DOWN PA1
// Пределы частоты (задержки в мс)
const int MIN_DELAY = 100;
const int MAX_DELAY = 2000;
const int STEP = 100;
// Разделяемые ресурсы
int blinkDelay = 500;
SemaphoreHandle_t xMutex;
// Прототипы задач
void TaskLed(void *pvParameters);
void TaskButtons(void *pvParameters);
void setup() {
Serial.begin(115200);
// Инициализация OLED
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.println("FreeRTOS Ready");
display.display();
// Создание мьютекса
xMutex = xSemaphoreCreateMutex();
if (xMutex != NULL) {
// Создание задач
xTaskCreate(TaskLed, "LED", 128, NULL, 1, NULL);
xTaskCreate(TaskButtons, "Buttons", 128, NULL, 1, NULL);
}
}
void loop() {
// В FreeRTOS loop пустой или удаляется
}
void TaskLed(void *pvParameters) {
pinMode(LED_PIN, OUTPUT);
int currentDelay;
for (;;) {
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
currentDelay = blinkDelay;
xSemaphoreGive(xMutex);
}
digitalWrite(LED_PIN, LOW); // Встроеный LED на BluePill включается LOW
vTaskDelay(pdMS_TO_TICKS(currentDelay));
digitalWrite(LED_PIN, HIGH);
vTaskDelay(pdMS_TO_TICKS(currentDelay));
}
}
void TaskButtons(void *pvParameters) {
pinMode(BTN_UP, INPUT); // В вашей схеме внешние резисторы, поэтому просто INPUT
pinMode(BTN_DOWN, INPUT);
for (;;) {
bool changed = false;
// Кнопка Вверх (увеличить частоту = уменьшить задержку)
if (digitalRead(BTN_UP) == HIGH) {
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
if (blinkDelay > MIN_DELAY) blinkDelay -= STEP;
changed = true;
xSemaphoreGive(xMutex);
}
vTaskDelay(pdMS_TO_TICKS(250)); // Антидребезг
}
// Кнопка Вниз (уменьшить частоту = увеличить задержку)
if (digitalRead(BTN_DOWN) == HIGH) {
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
if (blinkDelay < MAX_DELAY) blinkDelay += STEP;
changed = true;
xSemaphoreGive(xMutex);
}
vTaskDelay(pdMS_TO_TICKS(250)); // Антидребезг
}
if (changed) {
Serial.print("New Delay: ");
Serial.println(blinkDelay);
// Обновление дисплея
display.clearDisplay();
display.setCursor(0,0);
display.print("Delay: ");
display.print(blinkDelay);
display.println(" ms");
display.display();
}
vTaskDelay(pdMS_TO_TICKS(10)); // Пауза задачи
}
}Loading
stm32-bluepill
stm32-bluepill