Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

8051. Прерывание на кнопке, жесть.

Ср янв 20, 2021 21:47:17

Что нибудь можно сделать, чтоб избавится от дребезга? Пытаюсь сбрасывать бит IE0 в регистре PCON, на 12-тактовых это более-менее работает, на 1-тактовом (STC11F04E) это не работает никак, видимо слишком шустрый. Пытался внедрять задержки в подпрограмме, тоже не катит совсем. Кнопка на #INT0 работает кошмарно. Что в таких случаях обычно делается?
Код:
 
ledpin   bit   P3.7

   org   0000h
   jmp   main

   org   0003h
   jmp   ledchange

   org   000Bh

main:
   setb   EX0
   setb   IT0
   setb   EA
loop:
   mov   PCON, #00000001B
   jmp   loop

ledchange:
   clr   EA
   clr   IE0
   cpl   ledpin
   setb   EA
   reti

   end

Re: 8051. Прерывание на кнопке, жесть.

Ср янв 20, 2021 22:13:37

В сети куча информации по борьбе с дребезгом. См, например, здесь: https://radioprog.ru/post/251

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:05:00

В сети куча информации по борьбе с дребезгом. См, например, здесь: https://radioprog.ru/post/251

Не спорю, но про то как это сделать в прерывании у 8051-го - чё-то небогато.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:31:30

Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:33:44

Вот мой старый проект часов на асме для С8051. Анти-дребезг реализован в соответствии с алгоритмом в листинге 1 на стр. 20 в приложенной PDF.
Clock.zip
(526.75 KiB) Скачиваний: 172

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 00:53:33

Потому что никто так не делает. Разве что, из всяких слипов выходить.
К чему такая молниеносная реакция на нажатие кнопки ?

молниеносная реакция мне не нужна. На самом деле пока не смог придумать как сделать кнопки на МК по-другому.
Хочется читать штук 8, сразу. Захожу в прерывание, читаю порт с кнопками, кладу в регистр, выхожу из прерывания (МК при этом снимается с IDLE), Прерывание по нажатию любой кнопки, через диодное лог. "ИЛИ" на вход инта. Вроде все классно.
Но пока решил попробовать с одной, и получается не очень.
Вложения
buttonz.png
(10.11 KiB) Скачиваний: 114

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 07:47:33

Сканировать по таймеру каждые 20-50мс не пробовал?

Так-то классика жанра, которую ТС не знает. Ха-ха... С IDLE можешь выходить по прерыванию таймера, что, обычно, позволяли все МК на ядре MCS-51, с которыми я когда-то работал. И не нужно ни каких "монтажных И". Для считывания 8 кнопок хватит 6 ног МК. Если ног не хватает, то добавляется сдвиговый регистр, который уменьшит число потребных ног до трёх.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 09:12:03

https://m.radiokot.ru/forum/viewtopic.php?f=61&t=79801

Там буквально на первых страницах описан принцип, Alex даже приводил пример на Си. По тому же принципу и действуйте на асме.

Для начала заведите таймер на 1 мс. На него и заведите все процессы: чтение кнопок, отображение информации, считайте датчики и пр.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 10:15:14

В схеме диоды нужно переставить в цепь R1,R3.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 10:37:00

Изображение
Px.0-Px.2 настроены как входы с подтягивающим резистором.
Собственно там больше мороки с режимом прерывания - вход в обработчик по прерыванию, затем в теле обработчика запрет прерывания по INT, замена адреса возврата на адрес подпрограммы антидребезгового анализатора (при резервировании адреса возврата в точку вызова INT) и reti.
Далее выполняем антидребезг, захват комбинации и по завершении ret в точку вызова INT с последующим разрешением самого INT.
Это на случай, если в системе критичны прерывания более низкого уровня.
Собственно сам антидребезг классика - последовательное чтение комбинации ЛВК при сравнении с предыдущим прочитанным.
старт
читать данные с Px.n - Px.m
совпали с буфером?
если совпало - установить флаг "данные готовы" и выход
если нет - перезапись значения буфера текущим считанным, задержка в N интервал и повторять от старт
8)
Ну и ессно смотрим чтобы выход на исполнение был не ранее "полного отпускания" ВСЕХ кнопок (или смены стабильной комбинации, если таковое возможно для программы). Иначе сразу по выходу снова в прерывание вскочим.
Там вариаций море - все зависит от фантазии автора.
8)

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 12:52:53

Вот только как все это сделать, блин. Примеры на "С" (а других в общем, нет) мне непонятны, я его почти не знаю, в больших программах на асме тоже сложно разобраться.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:05:47

Вечерком чегось поднашкрябаю для примера...
Именно под вариант прерывания - но только для базовой классики (AT89C51 за основу).
Для STC там надо "привести в соответствие" - влазить в доки чуток влом.
:write:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:20:09

Таймер с прерыванием в 1 мс настроить сможете?
Заведите переменную, скажем counter = 20.
В прерывании по таймеру делаете декремент counter, затем проверяете на 0.
Если counter == 0, выставляете какой-то флаг, read_keys = 1.

В основном цикле программы постоянно сканируете этот флаг на равенство 1.
Как только поймали, делаете read_keys = 0, counter = 20, call scan_keys.
В scan_keys считываете весь порт в переменную keys в инверсном виде (вам же 8 кнопок нужно было?)
Если keys не равен 0 проверяете его на равнство keys_old (предыдущее значение). Если не равны, то keys_old = keys и на выход.
Если равны, значит в текущее значение равно считанному 20 мс назад - это ваш антидребезг. По значению переменной keys оперируете кнопками. При выходе обнуляете keys_old = keys = 0, но и тут возможны варианты, если планируете обрабатывать длительные нажатия.

Все это на ассемблере.
А вообще, переходите на Си. Чтобы начать писать на нем, совсем необязательно знать все возможности.
Начните с базовых операций, а остальное изучите по ходу дела.

Добавлено after 6 minutes 11 seconds:
... для базовой классики (AT89C51 за основу)

STC11F04E, кстати, имеет совместимую с AT89C2051 цоколевку.
Отличаться может только вторым режимом таймера.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:47:17

Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...
Мне его готовить влом... имеется в наличии для STCшек только под stc15f204ea...
:(
Да так пока и лежит без дела (несмотря что есть подопытный МК).
:sleep:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:49:48

Таймер с прерыванием в 1 мс настроить сможете?

Вспомнил, что в программе для прошивки встроены различные полезные утилиты для генерации готового кода, например, настройка таймера, а также множество демо-кодов (правда, описание на китайском, да еще и шрифт левый). Причем все это и на Си, и на асме. В даташите на семейство тоже хватает примеров использования.

Добавлено after 2 minutes 11 seconds:
Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...

В прошивальщике все это есть:

Сравнить регистры и поправить.
15F204 от 11F04E практически не отличается.
Последний раз редактировалось Zhuk72 Чт янв 21, 2021 14:55:16, всего редактировалось 1 раз.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 14:54:35

Zhuk72 писал(а):Если keys не равен 0 проверяете его на равнство keys_old (предыдущее значение). Если не равны, то keys_old = keys и на выход.

меня вот тут ступор случилсся, чтоб сравнить с keys_old, его надо сначала где-то и как-то установить. А все проходы одинаковые, непонятно, где old, а где не old/

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:01:42

Изначально и старый и текущий - нулевые.
Если при считывании текущий не ноль, тогда только сравниваете со старым. Если не равны, то keys_old = keys и на выход.
В следующем проходе, если нажатие все-такие существуют, они будут равны, тогда и обрабатываете значение keys. При выходе опять обнуляете оба регистра (или нет, зависит от хотелок).
keys (если через инверсию читаете) может быть равен 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 или 0x80.
Ну это если одновременно 2 и более кнопок не нажмете.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:04:01

Для корректной прожки с использованием моего c51asm надо набросать *.inc с базовым описанием...

Я вообще не парюсь. Например, нужен регистр какого нет в классике, например, SPI в МК STC12C5A60S2 (успешно разобрался с MAX7219), я посмотрел его адрес в даташите, и сделал SPDAT equ (адрес регистра).
Единственное что - замороченные STC8 и STC15, там надо внимательно читать все, даже некоторые стандартные 8051 регистры там могут быть не на своем месте, а на выводах портов включены альтернативные функции по умолчанию.
Последний раз редактировалось Shuspano Чт янв 21, 2021 15:12:40, всего редактировалось 1 раз.

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:08:45

Там простой буфер-регистр под временное хранение (inp_dat) и буфер для чтения (tmp_lvk) (у STC правда можно непосредственно с выводами сравнивать, но уж лучше таки прочитать значение).
При первом вызове в него (inp_dat) записывается нейтральное состояние, статус tmp_lvk безразличен - он все равно свеженькое значение получит.
Далее
читаем порт в tmp_lvk
сравниваем с inp_dat
по результату
или
inp_dat = tmp_lvk - это случай подтверждения предыдущих считанных данных
или в случае неравенства
mov inp_dat,tmp_lvk ; и после интервала повторяем заново
Только вот надо отслеживать комбинацию "все отпущены" как основу выхода по фальстарту или по завершении исполнения.
А это уже дополнительная обработка считанных из порта данных.
Можно дополнить еще одним регистром - счетчиком для стабилизации количества верно считанных и/или ошибочных комбинаций.
Тогда тайминги автоматом уходят - просто используется контроль в течении N циклов подтверждения совпадения (та же программная задержка).
:roll:

Насчет *.inc - лучше таки нашкарябать...
:roll:

Re: 8051. Прерывание на кнопке, жесть.

Чт янв 21, 2021 15:46:17

Главное неудобство STC - документация, написанная через пень-колоду.
В этом плане МК с ядром 8051 от Силабс, конечно, вне конкуренции.
Ответить