#include "stm32l0xx_hal.h"
#include <stdint.h>
/* ================================================================
МАКРОСИ ПІДКЛЮЧЕННЯ (згідно методички та моєї схеми)
================================================================ */
/* ЗЕЛЕНИЙ світлодіод:
PB3 — це пін D13 на платі Nucleo-L031K6
*/
#define LED_GREEN_PORT GPIOB
#define LED_GREEN_PIN GPIO_PIN_3
/* ЧЕРВОНИЙ світлодіод:
PA0 — це пін A0
*/
#define LED_RED_PORT GPIOA
#define LED_RED_PIN GPIO_PIN_0
/* КНОПКА:
PA12 — це пін D2
Кнопка підключена до GND, тому:
- відпущена = лог.1 (Pull-Up)
- натиснута = лог.0
*/
#define BUTTON_PORT GPIOA
#define BUTTON_PIN GPIO_PIN_12
/* ================================================================
НАЛАШТУВАННЯ ЧАСУ
================================================================ */
/* Затримка для усунення брязкоту контактів */
#define DEBOUNCE_MS 30
/* Межі для визначення типу натискання */
#define SHORT_PRESS_MS 1000 // коротке < 1 сек
#define LONG_PRESS_MS 3000 // довге 1–3 сек
/* ================================================================
ЗМІННІ СТАНУ
================================================================ */
/* Стан світлодіодів:
0 — вимкнений
1 — увімкнений
*/
static uint8_t green_state = 0;
static uint8_t red_state = 0;
/* Час початку натискання кнопки */
static uint32_t press_time = 0;
/* Ознака, що кнопка зараз натиснута */
static uint8_t pressed = 0;
/* ================================================================
ІНІЦІАЛІЗАЦІЯ GPIO
================================================================ */
static void GPIO_Init(void)
{
/* Вмикаємо тактування портів GPIOA та GPIOB */
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* ---------- ЗЕЛЕНИЙ LED (PB3) ---------- */
GPIO_InitStruct.Pin = LED_GREEN_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // режим виходу
GPIO_InitStruct.Pull = GPIO_NOPULL; // без підтягування
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LED_GREEN_PORT, &GPIO_InitStruct);
/* Спочатку вимикаємо світлодіод */
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_PIN_RESET);
/* ---------- ЧЕРВОНИЙ LED (PA0) ---------- */
GPIO_InitStruct.Pin = LED_RED_PIN;
HAL_GPIO_Init(LED_RED_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, GPIO_PIN_RESET);
/* ---------- КНОПКА (PA12) ---------- */
GPIO_InitStruct.Pin = BUTTON_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // режим входу
GPIO_InitStruct.Pull = GPIO_PULLUP; // внутрішній Pull-Up
HAL_GPIO_Init(BUTTON_PORT, &GPIO_InitStruct);
}
/* ================================================================
ФУНКЦІЯ УСУНЕННЯ БРЯЗКОТУ КНОПКИ
================================================================
Принцип роботи:
- читаємо стан кнопки
- чекаємо DEBOUNCE_MS
- читаємо ще раз
- якщо значення співпали — стан стабільний
Повертає:
GPIO_PIN_RESET — кнопка натиснута
GPIO_PIN_SET — кнопка відпущена
*/
static GPIO_PinState Button_ReadStable(void)
{
GPIO_PinState s1 = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
HAL_Delay(DEBOUNCE_MS);
GPIO_PinState s2 = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN);
if (s1 == s2)
return s1; // стабільний стан
else
return GPIO_PIN_SET; // вважаємо, що кнопка відпущена
}
/* ================================================================
ГОЛОВНА ПРОГРАМА
================================================================ */
int main(void)
{
/* Ініціалізація HAL та GPIO */
HAL_Init();
GPIO_Init();
while (1)
{
/* Отримуємо стабільний стан кнопки */
GPIO_PinState btn = Button_ReadStable();
/* ---------- МОМЕНТ НАТИСКАННЯ ---------- */
if (btn == GPIO_PIN_RESET && pressed == 0)
{
pressed = 1; // фіксуємо, що кнопка натиснута
press_time = HAL_GetTick(); // запам’ятовуємо час
}
/* ---------- МОМЕНТ ВІДПУСКАННЯ ---------- */
if (btn == GPIO_PIN_SET && pressed == 1)
{
pressed = 0;
/* Обчислюємо тривалість натискання */
uint32_t dt = HAL_GetTick() - press_time;
/* ---- КОРОТКЕ НАТИСКАННЯ (<1с) ---- */
if (dt < SHORT_PRESS_MS)
{
green_state ^= 1; // інверсія стану
HAL_GPIO_WritePin(
LED_GREEN_PORT,
LED_GREEN_PIN,
green_state ? GPIO_PIN_SET : GPIO_PIN_RESET
);
}
/* ---- ДОВГЕ НАТИСКАННЯ (1–3с) ---- */
else if (dt <= LONG_PRESS_MS)
{
red_state ^= 1;
HAL_GPIO_WritePin(
LED_RED_PORT,
LED_RED_PIN,
red_state ? GPIO_PIN_SET : GPIO_PIN_RESET
);
}
/* ---- ДУЖЕ ДОВГЕ (>3с) ---- */
else
{
green_state = 0;
red_state = 0;
HAL_GPIO_WritePin(LED_GREEN_PORT, LED_GREEN_PIN, GPIO_PIN_RESET);
HAL_GPIO_WritePin(LED_RED_PORT, LED_RED_PIN, GPIO_PIN_RESET);
}
}
}
}