STM32 Обработка кнопки с антидребезгом без использования прерываний.

KakaiDiemon

✩✩✩✩✩✩✩
2 Мар 2026
4
0
Всем привет, учусь программировать мк stm32, хоть больше люблю плисины. Полистал примеры с антидребезгом и не очень они мне зашли и я решил попробовать реализовать по-другому таким кодом в бесконечном цикле без использования прерываний:
C++:
button = (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11) == GPIO_PIN_SET);
if (button != last_button) {
   start_timer = HAL_GetTick();
}
else if (HAL_GetTick() - start_timer >= 50) {
   debounced_button = button;
   start_timer = HAL_GetTick();
}
debounced_last_button = debounced_button;
last_button = button;
Насколько это костыльно реализовано и какие подводные камни у такого антидребезга?
 
Изменено:

Сотнег

★★★★★★★
15 Янв 2020
4,631
1,564
@KakaiDiemon,
это не антидребезг, а фильтр кратковременных нажатий.

Стоит начать не с примеров кода, а с описания сути решаемой проблемы.
 

Mark_gresh

✩✩✩✩✩✩✩
28 Янв 2026
13
0
А аппаратный не подойдёт? Внешний резистор с конденсатором.
 

KakaiDiemon

✩✩✩✩✩✩✩
2 Мар 2026
4
0
@Сотнег,
Но ведь фильтр кратковременных нажатий при коммутации и есть антидребезг. Обычный пример, где взводят таймер после первого изменения сигнала кнопки в целом проблематично назвать антидребезгом по сути.

Здесь скорее вопрос "как наиболее правильно". Может кто-то реализовал такой программный метод лучше.
 
Изменено:

Сотнег

★★★★★★★
15 Янв 2020
4,631
1,564
@KakaiDiemon,
обычно наиболее правильно - не игнорировать нажатие кнопки, даже если оно было кратковременным.
 

poty

★★★★★★★
19 Фев 2020
3,609
1,027
@KakaiDiemon, нужно править алгоритм. Если требуется только дебаунсинг, то изменение состояния кнопки означает, что с ней, действительно, произошло какое-то действие. Т.е., смена значения в коде должна происходить сразу (здесь @Сотнег прав).
Второе, ожидание 50 мс. Это - 20 Гц. Понятно, что с такой частотой вряд ли кто-то сможет нажимать на кнопку, разве что это какой-то датчик, но реальные ситуации могут быть разные. Частота самого дребезга в несколько раз выше. Т.о., нужно не ждать N мс с игнором, а дожидаться , когда в одном состоянии кнопка будет, допустим, 5 мс. Т.е. значение в коде должно измениться сразу после изменения состояния кнопки и повторно - после первого "периода тишины" в 5 мс.
 

poty

★★★★★★★
19 Фев 2020
3,609
1,027
Я ( и не только я) говорил о двух вещах.
"Счёт таймера" у Вас запускается с первого изменения состояния, я же предлагаю считать от последнего.
 

KakaiDiemon

✩✩✩✩✩✩✩
2 Мар 2026
4
0
@poty, в данном случае счет таймера как раз идет от последнего изменения. Поэтому и написал про только изменение счета таймера.
 

microsystems

✩✩✩✩✩✩✩
Просто считывай состояние кнопки с периодичностью, скажем, 20 мс, и все, и никаких больше ухищрений не требуется. Дальше сравнивай это текущее состояние с предыдущим и выставляй флаг либо нажатия, либо отпускания.