#include <Arduino.h>
// Прапорці стану
volatile bool system_active = false;
volatile bool adc_ready = false;
volatile uint16_t adc_value = 0;
// Створюємо об'єкт апаратного таймера (TIM3)
HardwareTimer *MyTim = new HardwareTimer(TIM3);
// 1. Обробник переривання: Кнопка
void button_isr() {
system_active = !system_active; // Змінюємо стан системи
if (!system_active) {
digitalWrite(PA5, LOW); // Вимикаємо LED
Serial.println("\r\n[EVENT] Monitoring STOPPED");
} else {
Serial.println("\r\n[EVENT] Monitoring STARTED");
}
}
// 2. Обробник переривання: Таймер (спрацьовує кожні 200 мс)
void timer_isr() {
if (system_active) {
// Зчитуємо значення АЦП безпосередньо в перериванні
adc_value = analogRead(PA1);
adc_ready = true; // Встановлюємо прапорець для головного циклу
}
}
void setup() {
Serial.begin(115200);
// Налаштовуємо роздільну здатність АЦП як у STM32 (12 біт: 0-4095)
analogReadResolution(12);
pinMode(PA5, OUTPUT); // LED
pinMode(PA0, INPUT_PULLUP); // Кнопка
// Налаштовуємо зовнішнє переривання (EXTI) для кнопки на спад сигналу
attachInterrupt(digitalPinToInterrupt(PA0), button_isr, FALLING);
// Налаштовуємо апаратний таймер на 5 Гц (200 мс)
MyTim->setOverflow(5, HERTZ_FORMAT);
MyTim->attachInterrupt(timer_isr);
MyTim->resume(); // Запускаємо таймер
Serial.println("--- System Initialized ---");
Serial.println("Press the Button to start/stop monitoring.");
}
void loop() {
// Обробка події від таймера/АЦП
if (adc_ready) {
adc_ready = false; // Скидаємо прапорець
// Керування LED на основі показань (поріг 2048)
if (adc_value > 2048) {
digitalWrite(PA5, HIGH);
} else {
digitalWrite(PA5, LOW);
}
Serial.print("ADC Value: ");
Serial.print(adc_value);
Serial.print("\t LED State: ");
Serial.println((adc_value > 2048) ? "ON" : "OFF");
}
// Переводимо процесор у режим сну (Wait For Interrupt)
// Жодного блокування чи delay(), мікроконтролер "прокидається" тільки від подій
__WFI();
}Loading
stm32-bluepill
stm32-bluepill