Обсуждаем контроллеры компании Atmel.
Пт янв 19, 2018 18:31:04
Гефестион писал(а):Чтобы зря не опрашивать её в цикле, если она нажимается редко. Плюс не будет гемора с многократным опросом кнопки за время её нажатия, поскольку прерывания происходят только по фронтам.
Не вопрос. Исходя из этой позиции, вы сидите ждете какой-то флаг. Работа МК судя по вашему производится зря, вхолостую. Временные задержки на основе счета тактов. Времянки какие угодно. От микросекунд, до секунд. И представляете, МК работает ЗРЯ! Парадокс, не правда ли?!
Я к чему, забудьте об этом суждении. Какую бы вы программу не написали, работа МК - выполнять написанную вами программу. Не хотите ждать зря кнопку? Создайте условие, по которому если кнопки не нажата, идем выполнять другую работу. Так вы освоите псевдопараллельность работы модулей программы.
Пт янв 19, 2018 18:37:55
Так и сделал, вроде работает.
Вот тестовый вариант для проверки кнопок на длительный дребезг (выбраковка кнопок)… на базе тини13, тактируется от заводской установки (1,2 МГц) – фьюзы устанавливать не надо… две кнопки и два светодиода… алгоритм проверяемой кнопки выполнен как описывал выше (от внешнего прерывания)… в теле прерывания организовано так: какой первый лог уровень замечен такой светодиод и загорится… зелёный – лог. 0; красный – лог. 1… сброс свечения светодиодов осуществляется кнопкой сброс.
Схема:
- 1.png
- (23.27 KiB) Скачиваний: 552
Прошивка:
Пт янв 19, 2018 19:57:40
На чём основаны такие умозаключения? Аргументы будут?
Математика, закон Ома... кнопка - сопротивление контакта 0.1Ом, на конденсаторе в момент нажатия 5Вольт... калькулятор сами достанете? А для кнопки заявлен максимальный ток в 50мА. И усреднение тут не катит, ток разряда конденсатора будет таки потихоньку плавить конаткт и оставлять нагар. В итоге кнопка превращается в черт знает что.
Тут тоже желательно аргументированных утверждений, а не бла бла.
Все люди у нас очень терпеливые и обладают железной выдержкой. Попробуйте к примеру поработать с планетом у которого нажатие регистрируется 9 раз из 10. Через 15 минут начинаешь присматриваться к стенке, как бы его так кинуть чтобы обои не поцарапать.
Пт янв 19, 2018 21:14:30
Alexeyslav писал(а):планетом
уже присматриваешься?
К кнопке ещё резистор, чтоб ток гасить..., не слишком ли много обвеса получается?
проще регулярно опрашивать, и на основе 2х или 3х подряд одинаковых замеров принимать решение...
Пт янв 19, 2018 21:34:21
Причем тут резистор? У кнопки по любому должен быть резистор подтяжки. Проблема в конденсаторе, который в момент нажатия находится после резистора.
И опрос не нужно делать подряд. Его нужно делать ПОСТОЯННО с интервалом чуть больше дребезга.. Но если дребезг слишком велик, можно опрашивать чаще, но фильтровать полученный битный массив. Впрочем, это не ускорит срабатывание изношенной кнопки.
Пт янв 19, 2018 21:40:47
Имхо, все эти игры с попыткой обработать нажатие кнопки через прерывание - это бирюльки. Потому что дребезг нормально таким способом не подавишь. И вешать конденсаторы - это не выход из ситуации.
Гораздо лучше делать периодический опрос состояния кнопок. Но не в главном цикле программы, как любят некоторые, судя по тем примерам кода, что я иногда встречаю. В этом случае, пока нажата кнопка, вся остальная программа, по сути, висит в ожидании.
Корректнее всего использовать аппаратный таймер. Как правило, либо есть свободный таймер, либо описываемый подход вполне сочетается с параллельным использованием какого-то уже задействованного таймера.
Допустим, таймер настроен на 1кГц. Каждую 1мс срабатывает прерывание, в нём мы просто смотрим на состояние кнопок. Если ничего не нажато - в этой итерации ничего не делаем. Если же по прерыванию мы видим, что одна из нескольких кнопкок нажата - записываем состояние кнопок в некотрой переменной (назовём её btnStatus), а также инкрементируем некоторый счётчик (btnCnt). При следующем прерывании - всё то же самое.
В какой-то момент кнопка будет отпущена. В прерывании мы увидим, что btnStatus изменился. Это повод для того, чтобы 1) обнулить счётчик; 2а) если счётчик насчитал достаточно (скажем, до 100 = 100мс) - мы предыдущий btnStatus сохраняем в новой глобальной переменной (скажем, btnStatusGlobal); 2б) если счётчик не насчитал достаточно - ничего не делаем (считаем это дребезгом контактов).
Ну а основной цикл просто смотрит btnStatusGlobal, и, если в ней что-то есть, выполняет соответствующий обработчик нажатия.
Из опыта - работает такой подход абсолютно надёжно.
Пт янв 19, 2018 21:52:51
Слишком сложно... переменные, счетчики... достаточно считать прерывания и смотреть на младшие 4 бита если они равны нулю - опрашиваем, сохраняем состояние кнопок и сравниваем с предыдущим - если есть несовпадения обновляем маску нажатия/отпускания кнопки, а обнулить маску может только основной цикл.
Как правило счетчик прерываний уже есть, поэтому никакой дополнительной шелухи не надо.
Пт янв 19, 2018 23:04:14
Ничего сложного. Минут за 30 набросал код (правда на C), который по вышеописанному принципу делает вроде как простую задачку, но с подвохами.
Вкратце - есть две кнопки, есть два светодиода. Кратковременное нажатие каждой кнопки зажигает свой светодиод на определённое время. Кнопки работают абсолютно независимо одна от другой.
Задействован лишь один - самый простой в atmega8 - таймер. Как для опроса кнопок, так и для таймаутов свечения. Ни одной функции задержки в коде нет, основной цикл программы не блокируется нигде, поэтому никакие полезные вычисления, которые могли бы где-то выполняться, выполнялись бы себе.
Добавить аналогично ещё кнопок / светодиодов - никакой проблемы.
Размер программы меньше 400 байт (на ассемблере, вероятно, и меньше был бы), исходник, hex и проект в Proteus там же.
- Вложения
-
- avrInput.7z
- (13.37 KiB) Скачиваний: 217
Пт янв 19, 2018 23:15:01
Математика, закон Ома... кнопка - сопротивление контакта 0.1Ом, на конденсаторе в момент нажатия 5Вольт... калькулятор сами достанете?
То есть твоя схема с конденсатором убивает кнопку!? А я тут причём… не нужно свои домыслы перекладывать на других… вот схема ничего не убивает и работает как часы устраняя дребезг… верхний по схеме резистор можно задействовать в самом МК… нижний рассчитывается в зависимости от ёмкости…
- 1.png
- (6.66 KiB) Скачиваний: 574
Alexeyslav писал(а):Попробуйте к примеру поработать с планетом у которого нажатие регистрируется 9 раз из 10. Через 15 минут начинаешь присматриваться к стенке, как бы его так кинуть чтобы обои не поцарапать.
И тут придумал что-то своё и пытаешься это навесить на меня…
ладно всё понятно.
Сб янв 20, 2018 06:58:39
получается: либо антидребезг занимает место в коде по методу, например, WiseLordа, либо на плате, по схеме АСУ, а тут уж самому решать - какое место нужнее...
Сб янв 20, 2018 07:02:42
Ну трындец...
В основном цикле.
Спойлер
- Код:
.cseg
//************************************************************************
Reset:
//----------
Clear_Registers
//----------
//----------
clr RCLR
ser r16
mov RSER, r16
clr FLAGS
//----------
//----------
Init_Stack // Инициализация стека.
//----------
//----------
Clear_SRAM // Очистка ОЗУ.
//----------
//----------
Init_System_Timer // Инициализация системного таймера.
//----------
//----------
Init_WDT
//----------
//----------
Init_Sleep_Mode
//----------
//---------- Отладка ----------
#if (PROJECT==DEBUG)
sbi KEYS_PIN_HEAT_ON_OFF, KEY_HEAT_ON_OFF
sbi KEYS_PIN_FAN_UP, KEY_FAN_UP
sbi KEYS_PIN_FAN_DOWN, KEY_FAN_DOWN
sbi AC_OUT_PIN, AC_OUT
// sbi FIRE_SENS_PIN, FIRE_SENS
// sbi OVERHEAT_SENS_PIN, OVERHEAT_SENS
#endif
//==================
sei
//==================
Main:
wdr
rcall Service_Timers
rcall KBD_DRV
rcall Proc_Emerg_Sens
rcall Proc_Heater
rcall Proc_Fan
rcall Proc_ADC
rcall Proc_Pump
rcall Proc_Heat_Err
rjmp Main
//==================
Спойлер
- Код:
.macro Scan_Keys
clrb FSM_FLAGS, KEYS_PRESSED_FLG
in r16, Keys_Pin
com r16
andi r16, Keys_Mask
cpi r16, 0
breq Scan_Keys_End
setb FSM_FLAGS, KEYS_PRESSED_FLG
Scan_Keys_End:
Save_Keys_Current
.endmacro
//==================
Kbd_Drv_Save_Val:
std Y+DISP_KEYS, FSM_STATE
std Y+DISP_KEYS_FLAGS, FSM_FLAGS
ret
//==================
//==================
Define_Keys:
sbrs FSM_FLAGS, DEFINE_KEYS_FLG
ret
Define_Keys_A:
clrb FSM_FLAGS, DEFINE_KEYS_FLG
ldz Table_Keys_Code*2
Read_Keys_Current
Define_Keys_Cycle:
lpm r17, Z+
cpi r17, 0xFF
brne Define_Keys_Cycle_A
ret
Define_Keys_Cycle_A:
cp r16, r17
breq Define_Keys_Equal
lpm r17, Z+
rjmp Define_Keys_Cycle
Define_Keys_Equal:
lpm r16, Z
std Y+DISP_KEYS_BUF, r16
ret
//==================
//==================
KBD_DRV:
pushiwl Kbd_Drv_Save_Val
pushiwl Define_Keys
ldy _KEYS
ldd FSM_STATE, Y+DISP_KEYS
ldd FSM_FLAGS, Y+DISP_KEYS_FLAGS
Scan_Keys // Макрос сканирование кнопок. Дефайнами подставляются нужные функции. Порт\Матрица\Несколько портов.
Proc_FSM Tab_FSM_KBD_DRV
Keys_Init:
ser r16
mov KEYS_PREV, r16
mov KEYS_CURRENT, r16
std Y+DISP_KEYS_BUF, r16
Set_State _KEYS_NONE
ret
Keys_None:
sbrs FSM_FLAGS, KEYS_PRESSED_FLG // Если что-то нажато, то пропуск команды.
ret
Read_Keys_Current
Save_Keys_Prev // Сохранение текущего состояния клавиатуры.
Set_Timer Par_Tim_Debounce_Delay // Установка задержки устранения дребезга.
Set_State _KEYS_DOWN
ret
Keys_Down:
Proc_Timer Par_Tim_Debounce_Delay
brtc Keys_Down_End
sbrs FSM_FLAGS, KEYS_PRESSED_FLG
rjmp Keys_Set_None
Comp_Last_Curr_Keys
breq Keys_Down_A
rjmp Keys_Set_None
Keys_Down_A:
setb FSM_FLAGS, DEFINE_KEYS_FLG
rjmp Keys_Set_Wait_Up
Keys_Down_End:
ret
Keys_Set_None:
Set_State _KEYS_NONE
ret
Keys_Set_Wait_Up:
Set_State _KEYS_WAIT_UP
ret
Keys_WAIT_UP:
sbrc FSM_FLAGS, KEYS_PRESSED_FLG
ret
Set_Timer Par_Tim_Debounce_Delay
Set_State _KEYS_UP
ret
Keys_UP:
Proc_Timer Par_Tim_Debounce_Delay
brtc Keys_UP_End
sbrc FSM_FLAGS, KEYS_PRESSED_FLG
rjmp Keys_Set_Wait_Up
Set_State _KEYS_NONE
Keys_UP_End:
ret
//==================
Table_Keys_Code:
.db 1<<KEY_HEAT_ON_OFF, KEY_COD_HEAT_ON_OFF
.db 1<<KEY_FAN_UP, KEY_COD_FAN_UP
.db 1<<KEY_FAN_DOWN, KEY_COD_FAN_DOWN
end_array
//==================
Сделано по принципу, описанному в статье. Прикреплено.
- Вложения
-
- 08.rar
- (107.57 KiB) Скачиваний: 195
Сб янв 20, 2018 09:14:25
получается:
Я борюсь с дребезгов в 90% случаях программными методами, но бывает когда по разным причинам приходится прибегать к старому методу RC цепочки которой пользовался в былые времена для рассыпухи.
Сб янв 20, 2018 09:24:30
Возник очередной вопрос. Подключил кнопку на PB7, разрешил прерывания PCIE и PCINT7. Т.е. любое изменение логического состояния на этой ноге будет вызывать прерывание... Как сделать так, чтобы кнопка срабатывала только один раз?
Как вариант использования PCINT для опроса кнопки с антидребезгом. Идея в накоплении состояния нажатой кнопки счетчиком за 128 тактов опроса. Если есть дребезг счетчик сбрасывается и счет начинается снова. Индикатором служит реверсирование состояния лапы PD0 при нажатии кнопки. Посмотрел на макете, правда кнопка у меня заведена на PB4 с резистором подтяжки 1,1к. Каждый раз при нажатии кнопки происходит смена состояния лапы PD0. При отпускании кнопки смены состояния нет.
Сб янв 20, 2018 11:24:34
Удалил
Сб янв 20, 2018 15:31:53
Все определяется схемотехникой конкретного устройства и системой команд/особенностями ядра конкретного семейства МК.
В том числе и для кнопок.
Так что решений может быть весьма много (в том числе и аппаратного предподавления дребезга механических контактов).
Сб янв 20, 2018 23:20:37
вот схема ничего не убивает и работает как часы устраняя дребезг… верхний по схеме резистор можно задействовать в самом МК… нижний рассчитывается в зависимости от ёмкости…
Боюсь разочаровать, но схема ваша не устраняет дребезг полностью, а лишь уменьшет его вероятность. Периодически, кнопку будет таки глючить несмотря на все предпринятые решения.
Чем больше величина нижнего резистора, тем хуже схема давит дребезг. А он не может быть маленьким - ибо ток через кнопку надо ограничить.
Зачем такие пляски с дополнительными деталями на каждую кнопку, если отлично справляется простой до гениальности программный способ подавления дребезга. Представьте, куда эти резисторы и конденсаторы ставить в матричную клавиатуру?
Вс янв 21, 2018 10:17:59
Периодически, кнопку будет таки глючить несмотря на все предпринятые решения.
Теоретические предположения – это хорошо. Только вот теория должна подтверждаться практическими фактами на железе. Если таковые факты есть (+ осциллограммы и т.п.) – с удовольствием взгляну. Если таковых нет, буду тогда тебя считать лишь теоретиком не более того.
Alexeyslav писал(а):Представьте, куда эти резисторы и конденсаторы ставить в матричную клавиатуру?
Опять ты «о своём, о девичьем» (С)
А если клавиатура на герконах!? Как в былые времена…
Alexeyslav писал(а):Зачем такие пляски с дополнительными деталями на каждую кнопку, если отлично справляется простой до гениальности программный способ подавления дребезга.
Бывают (у меня довольно часто) ситуации, когда свободной памяти для написания кода для подавления дребезга просто нет… часто это относится к девайсам на тини13… брать из-за этого более ёмкий МК или поставить дополнительные RC цепочки – я в большинстве случаях выбираю второе, так как это дешевле на порядок, да и кнопка может быть удалена от девайса на значительном расстоянии (несколько метров). Ты же в свою очередь поступай как считаешь нужным – я свой опыт тебе не навязываю.
Вс янв 21, 2018 10:56:17
А что, у герконов нет дребезга?
Вс янв 21, 2018 11:02:45
О чём думаем когда читаем пост!?
Вс янв 21, 2018 11:22:29
Думаем о подавлении дребезга и тех несчастных, которые во вновь разрабатываемых устройствах использует больше половины памяти. Как в дальнейшем можно модифицировать данное устройство, если не делать халтуру?
Powered by phpBB © phpBB Group.
phpBB Mobile / SEO by Artodia.