Pull to refresh

Навсегда избавляемся от дребезга и дружим микроконтроллер с кнопкой

Reading time4 min
Views8.2K

Привет Хабр! Сегодня хочу поделиться опытом разработки небольшого модуля электронного циферблата на базе семисегментных дисплеев. Помимо этого, также рассмотрим способ устранения «дребезга контактов» механической кнопки, который я подсмотрел в одной известной книге и опробовал самостоятельно.

Вечная проблема

Думаю, каждый, кто работал со встраиваемыми системами, сталкивался с этой проблемой: когда проект требует подключения механической кнопки для самых разных задач, но всегда возникает одна и та же трудность — несовершенство механизма замыкания. То есть, вы нажимаете кнопку один раз, но контроллер воспринимает это как многократное нажатие. А в системах, где логика работы строится на количественном подсчёте нажатий, это может привести к серьёзным сбоям.

Паразитный дребезг
Паразитный дребезг

Даже подключение кнопки к пину с прерыванием не избавляет от проблемы: прерывание просто срабатывает несколько раз подряд. Конечно, вместо механической кнопки можно использовать сенсорную — она лишена этого недостатка. Однако это не всегда уместно, и внедрить её можно не во все системы. К тому же сенсорная кнопка может срабатывать произвольно — при случайном касании.

Программный метод борьбы

Некоторые решают эту проблему программно, то есть поручают решение этой задачи программной части. Например, когда я работал с одним модулем, мне дали готовую программу, которую необходимо было «допилить». В ней обработкой нажатия кнопки занимались сразу два прерывания: аппаратное и прерывание по таймеру.

Суть заключалась в следующем: после срабатывания первого прерывания по смене логического уровня с высокого на низкий (при нажатии кнопки) запускался аппаратный таймер, настроенный на определённый период — как правило, это 50 мс. После срабатывания таймера прерывание вызывало событие обработки нажатия: увеличение счётчика, смена положения стрелки в меню и т.д.

Плата stm32f103c8t6
Плата stm32f103c8t6

Метод надёжный, но у него есть недостатки: он требует использования таймера и может увеличивать сложность прошивки, особенно если в проекте задействовано много кнопок или используются другие временные процессы.

Аппаратный метод

Решение, взятое мною является аппаратным, построенным на простой RC-цепи и инвертирующем триггере Шмитта. Преимущество в том, что схема полностью снимает нагрузку с микроконтроллера. Решение я подсмотрел в книге Джереми Блума "Изучаем Arduino".

Вот основные компоненты:

  • Резистор 220 Ом (по книге — 100 Ом),

  • Конденсатор 10 мкФ,

  • Подтягивающий резистор 10 кОм,

  • Инвертирующий триггер Шмитта (например, 74HC14).

Первая часть схемы работает на RC-цепи, формирующей задержку по смене фронта, длительность которой определяется по формуле: t = RC. Подставим значения в формулу и получим 1 мс. Общий график сигнала RC-цепи представлен ниже.

Затем полученный сигнал поступает на инвертирующий триггер Шмитта — устройство, приводящее аналоговый сигнал к стабильным логическим значениям. В зависимости от модели и производителя, триггер Шмитта обладает порогами срабатывания по напряжению: 2,5 В для восходящего и 1,6 В для нисходящего фронта при амплитуде 5 В. Так как мы используем инвертирующий триггер Шмитта, он работает по обратному принципу: когда сигнал преодолевает верхний порог срабатывания, на выходе образуется логический ноль, а когда — нижний порог, логическая единица. Общая схема представлена ниже.

Схема с подключённым виртуальным осциллографом
Схема с подключённым виртуальным осциллографом

Я собрал данную схему в программе для моделирования электрических схем — Multisim, чтобы на программном осциллографе продемонстрировать работу схемы. Единственное, что я заменил — резистор 100 Ом на 220 Ом. Красным отмечен сигнал после RC-цепи, жёлтым — готовый сигнал, поступающий на пин прерывания после преодоления триггера Шмитта. На осциллограмме видны импульсы, происходящие в моменты нажатия кнопки. Для начала, за счёт RC-цепи происходит нисходящий фронт, и из-за этого на выходе триггера устанавливается логическая единица. Затем происходит плавное нарастание фронта, и, когда он проходит определённую грань, на выходе получается логический ноль. В этом и заключается работа всей схемы.

Осциллограмма
Осциллограмма

Пример практического применения: модуль индикации

Модуль представляет собой электронный циферблат на четырёх семисегментных индикаторах и двух светодиодах диаметром 3 мм (используются для индикации секунд, как на цифровых часах).

Архитектура:

  • Индикация организована через два сдвиговых регистра 74HC595.

    • Первый регистр управляет сегментами (A–G и DP),

    • Второй — выбором активного индикатора (общего анода или катода).

  • Управление регистрами осуществляется через три линии:

    • SER (DIO) — данные,

    • SRCLK (SCLK) — тактирование,

    • RCLK (LATCH) — защёлка.

  • Дополнительно используется пин ~OE (Output Enable), на который подаётся ШИМ-сигнал для регулировки яркости дисплея.

  • Перемычка Jumper1 позволяет выбрать: управлять двумя светодиодами с одного пина, либо независимо с двух.

Схема модуля
Схема модуля

Ключевым блоком данной схемы является управление механическими кнопками, подключёнными по схеме, разобранной ранее. Выходы с триггера Шмитта выведены на отдельные коннекторы. Индикация циферблата осуществляется с помощью STM32, данные на сегменты поступают по интерфейсу SPI, а управление осуществляется через четыре механические кнопки.

При желании данный модуль можно легко модифицировать, изменив количество кнопок на любое другое.

Внизу можно наблюдать 3D-модель платы, созданную в программе EasyEDA.

Спасибо за прочтение! Если есть что добавить или подправить — пишите, будет любопытно почитать!

3D модель
3D модель
Tags:
Hubs:
+21
Comments61

Articles