Отличная подача материала, и наглядно всё показано, мало кто пишет на регистрах, было очень интересно посмотреть. Жду новых видео в подобном формате! Автору благодарность и удачи)
Я раньше использовал похожий метод. Создавал таймер с частотой 1000Гц, опрашивая порт увеличивал или уменьшал некую переменную. Для этой переменной задал два порога 20 (для состояния нажата) и 80 (для состояния отжата). Таким образом реализовал программный аналог RC-фильтра с триггером Шмидта. Недавно решил проверить встроенный триггер Шмидта и поставил параллельно контактам кнопки последовательно соединенные конденсатор 1 мкФ и резистор 300 Ом (для ограничения тока при разряде). Встроенная подтяжка к плюсу, если не ошибаюсь составляет ~40 кОм. Настроил EXTI прерывание и... у меня все равно иногда срабатывало двойное нажатие. Увеличив конденсатор до 2.2 мкФ эффект все равно остался. Тогда я в прерывании поставил проверку по времени события (с помощью HAL_GetTick). Оказалось в данной конфигурации (2.2 мкФ + 300 Ом) достаточно отбраковки повторных событий в течение 1 мс. Я поставил для надежности 2 мс.
// до main typedef struct { uint16_t click; // количество нажатий на кнопку uint8_t t_to_trigger; // время до срабатывания uint8_t t_trigger; // время до инкремента количества нажатий uint32_t t_hold; // время удержания кнопки (в миллисекундах) } my_BUTTON; const uint8_t button_t_trigger[10] = {1, 10, 10, 20, 20, 40, 40, 60, 60, 60}; // временные интервалы до следующего инкремента количества нажатий void BUTTON_step (uint32_t data, my_BUTTON *button) { // подпрограмма работы кнопки (должна выполняться 100 раз в 1 секунду) if (data==RESET) { if (button->t_to_trigger!=0) { button->t_to_trigger--; if (button->t_hold) { button->t_hold+=10; }; if (button->t_to_trigger==0) { if (button->t_trigger!=0) { button->t_trigger--; } button->t_to_trigger = button_t_trigger[button->t_trigger]; button->click++; if (!button->t_hold) { button->t_hold=10; } } } } else { button->t_to_trigger=6; button->t_trigger=9; button->t_hold=0; } }; my_BUTTON key_ok; my_BUTTON key_left; my_BUTTON key_right; // в таймере void TIM1_UP_IRQHandler(void) { // срабатывает 100 раз в секунду BUTTON_step (GPIOB->IDR&GPIO_PIN_1, &key_left); BUTTON_step (GPIOA->IDR&GPIO_PIN_7, &key_ok); BUTTON_step (GPIOB->IDR&GPIO_PIN_0, &key_right); } Таким образом в любом месте программы можно узнать время удержания кнопки и количество нажатий. Очень удобно использовать в меню для изменения каких-либо значений - при удержании кнопки аргумент количества нажатий увеличивается быстрее.
у меня есть две программы на устранение дребезга контактов.Одна это при нажатии считаются дрбезг после счёта устанавливается флаг.потм при отжатии другой счёт дребезга выставляется флаг отжатия.При уравнении этих флагов операнд и и пороисходит событие.Другая программа.В прерывании по таймеру.При нажатии кнопки выставляется флаг.А при выставлении флага работает инкремент.Если флаг==1&&GPIO==1&&pauza>20 после этого событие.
две проблемы пытаюсь решить, матричную клавиатуру как прикрутить, а точнее к F103C8T6 нужно запихать 176 кнопок, убить дребезг, скорость настолько важна, что минимум задержек на убивание дребезга нужно. Куда копать?
Очень хреново использовать текой фильтр для подавления дребезга. Время реакции на кнопку можно сильно затянуть. Годный алгоритм получается на контроле предыдущего длительного состояния, суть его (время утрировано): если 0,1 секунду состояние на пине было лог 1, то считаем, что лог 1 это текущее состояние это лог 1, значит любой переход в лог 0 будем считать нажатием, но отпусканием будем считать вновь появление лог 1 только когда лог 0 просуществует не менее 0,1 секунды. Таким образом мы "ловим" первое замыкание или первое размыкание кнопки, что человеком воспринимается как "мгновенная реакция на нажатие".
Скажите пожалуйста, как можна увеличит размер текста и интерфейса в STM32Cube IDE? Я ползою последная версия, но не могу разбиратся, есть ли вооше такая возможност. Хотель би такие надписи, как на вашем комютре? Поздравляю за уроки, они очнь полазные!
текст в окнах (код, консоли): увеличить: Ctrl и Shift и + уменьшить: Ctrl и - все остальное через саму винду 10: Нажать Win и u, там масштаб ставлю 175% там же размер надписей можно менять в полный экран сделать: Alt + F11
Отличная форма подачи материала! Никаких там ненужных пауз и лишних слов. Лайк однозначно.
Поддерживаю! Прекрасная подача материала. Я наконец узнал зачем эта стрелочка ->...
Отличная подача материала, и наглядно всё показано, мало кто пишет на регистрах, было очень интересно посмотреть. Жду новых видео в подобном формате! Автору благодарность и удачи)
ЕЕЕ!! Кайф. Впервые видео смотрел на пониженной скорости, а не наоборот, как с другими авторами по программированию МК)
удалось ли вам продвинутся в теме MIDI ?
Терпи, автор, и не сдавайся. Возможно, через год "умные" алгоритмы туба выведут твои видео в рекомендуемые.
В своё время, тоже мудыхался с дребезгом. Но остановился на следующем решении -- опрашиваю кнопки 5 раз в секунду т.е. с интервалом в 200 мС.
Я раньше использовал похожий метод. Создавал таймер с частотой 1000Гц, опрашивая порт увеличивал или уменьшал некую переменную. Для этой переменной задал два порога 20 (для состояния нажата) и 80 (для состояния отжата). Таким образом реализовал программный аналог RC-фильтра с триггером Шмидта. Недавно решил проверить встроенный триггер Шмидта и поставил параллельно контактам кнопки последовательно соединенные конденсатор 1 мкФ и резистор 300 Ом (для ограничения тока при разряде). Встроенная подтяжка к плюсу, если не ошибаюсь составляет ~40 кОм. Настроил EXTI прерывание и... у меня все равно иногда срабатывало двойное нажатие. Увеличив конденсатор до 2.2 мкФ эффект все равно остался. Тогда я в прерывании поставил проверку по времени события (с помощью HAL_GetTick). Оказалось в данной конфигурации (2.2 мкФ + 300 Ом) достаточно отбраковки повторных событий в течение 1 мс. Я поставил для надежности 2 мс.
Редко кто ставит резистор последовательно с конденсатором, а потом удивляются что контакты кнопок обгорают.
// до main
typedef struct
{
uint16_t click; // количество нажатий на кнопку
uint8_t t_to_trigger; // время до срабатывания
uint8_t t_trigger; // время до инкремента количества нажатий
uint32_t t_hold; // время удержания кнопки (в миллисекундах)
} my_BUTTON;
const uint8_t button_t_trigger[10] = {1, 10, 10, 20, 20, 40, 40, 60, 60, 60}; // временные интервалы до следующего инкремента количества нажатий
void BUTTON_step (uint32_t data, my_BUTTON *button) { // подпрограмма работы кнопки (должна выполняться 100 раз в 1 секунду)
if (data==RESET) {
if (button->t_to_trigger!=0) { button->t_to_trigger--;
if (button->t_hold) { button->t_hold+=10; };
if (button->t_to_trigger==0) { if (button->t_trigger!=0) { button->t_trigger--; } button->t_to_trigger = button_t_trigger[button->t_trigger]; button->click++; if (!button->t_hold) { button->t_hold=10; } }
}
} else { button->t_to_trigger=6; button->t_trigger=9; button->t_hold=0; }
};
my_BUTTON key_ok;
my_BUTTON key_left;
my_BUTTON key_right;
// в таймере
void TIM1_UP_IRQHandler(void) { // срабатывает 100 раз в секунду
BUTTON_step (GPIOB->IDR&GPIO_PIN_1, &key_left);
BUTTON_step (GPIOA->IDR&GPIO_PIN_7, &key_ok);
BUTTON_step (GPIOB->IDR&GPIO_PIN_0, &key_right);
}
Таким образом в любом месте программы можно узнать время удержания кнопки и количество нажатий. Очень удобно использовать в меню для изменения каких-либо значений - при удержании кнопки аргумент количества нажатий увеличивается быстрее.
В st к резистору в кнопке добавлен конденсатор. И это очень сильно экономит ресурсы 401/411 контроллера из которых и так вырезано все что можно.
у меня есть две программы на устранение дребезга контактов.Одна это при нажатии считаются дрбезг после счёта устанавливается флаг.потм при отжатии другой счёт дребезга выставляется флаг отжатия.При уравнении этих флагов операнд и и пороисходит событие.Другая программа.В прерывании по таймеру.При нажатии кнопки выставляется флаг.А при выставлении флага работает инкремент.Если флаг==1&&GPIO==1&&pauza>20 после этого событие.
а можно ли таким способом обработать 176 кнопок? делаю цифровое фортепиано
Шикарно!
RC Достаточно R внутренняя подяжка конденсатор на землю..А конденстор на входную НЧ ножку всегда хорошая идея..много лищнего
две проблемы пытаюсь решить, матричную клавиатуру как прикрутить, а точнее к F103C8T6 нужно запихать 176 кнопок, убить дребезг, скорость настолько важна, что минимум задержек на убивание дребезга нужно. Куда копать?
Очень хреново использовать текой фильтр для подавления дребезга. Время реакции на кнопку можно сильно затянуть.
Годный алгоритм получается на контроле предыдущего длительного состояния, суть его (время утрировано):
если 0,1 секунду состояние на пине было лог 1, то считаем, что лог 1 это текущее состояние это лог 1, значит любой переход в лог 0 будем считать нажатием, но отпусканием будем считать вновь появление лог 1 только когда лог 0 просуществует не менее 0,1 секунды.
Таким образом мы "ловим" первое замыкание или первое размыкание кнопки, что человеком воспринимается как "мгновенная реакция на нажатие".
Твой голос шедевр
Скажите пожалуйста, как можна увеличит размер текста и интерфейса в STM32Cube IDE? Я ползою последная версия, но не могу разбиратся, есть ли вооше такая возможност. Хотель би такие надписи, как на вашем комютре? Поздравляю за уроки, они очнь полазные!
текст в окнах (код, консоли):
увеличить: Ctrl и Shift и +
уменьшить: Ctrl и -
все остальное через саму винду 10:
Нажать Win и u, там масштаб ставлю 175%
там же размер надписей можно менять
в полный экран сделать: Alt + F11
там же есть в нwindow>preferences>general>apperance>colors and fonts > c/c++ EDITOR TEXT FONT и темы в APPERANCE >Theme >Dark например
Подписался