Сделать прерывание по FALLING и RISING на одном пине
- Войдите на сайт для отправки комментариев
Пнд, 29/11/2021 - 02:10
Здравствуйте!
Имеется Arduino UNO. Нужно сделать два аппаратных прерывания на пине D2. Один обработчик должен обрабатывать FALLING на этом пине, второй обработчик должен обрабатывать RISING на этом же пине.
Возможно ли такое сделать? Судя по документации, определить можно только одно прерывание на одном пине, если определить второе, оно отменит первое.
Может быть, есть способы как-то обойти эту проблему?
Может не маяться фигней и использовать CHANGE?
А в обработчике запоминать состояние порта. Если он HIGH - значит было с LOW на HIGH и наоборот.
Так, вроде бы, логичнее. Не?
Либо использовать один обработчик в котором переключаться с FALLING на RISING и наоборот.
Переключаться можно, если процессы не очень быстрые. В ряде случаев обычный дребезг с ума сведет неопределенностью исхода.
Если очень хочется именно два разных прерывания - то соединить физически пины D2 и D3, и настроить их по-разному :)
Я не написал, что время между фронтами "спада" и "подъема" где-то 500нс.
Arduino UNO в дефолте работает вроде как на 8МГц.
Вопрос в том, если настроить прерывание на CANGE, хватит ли времени в прерывании еще и вызывать чтение значения с пина, чтобы понимать какое состояние - FALLING или RISING?
Времени в прерывании будет столько , сколько потребуется на выполнение кода в прерывании .
Вопрос лишь в том, не повлияет ли долгое нахождение в прерывании на работу основной программы.
xintrea, с такими короткими импульсами даже первое прерывание не успеет завершиться.
Да и начаться толком тоже не успеет..
xintrea
Вы можете написать планируемый алгоритм работы, и возможные варианты входных сигналов?
Теоретически минимально возможное прерывание занимает на AVR восемь тактов: 3 на вход, 4 на выход и один на исполняемую команду. То есть на частоте 16 МГц требует как раз 500 нс. ;)))))))
----------------
Ведь уже 100500 раз сталкивались с тем, что не стоит давать ответы на абстрактные вопросы, типа "Интересуюсь Симочка - а скоки стоит океянский пароход?". А то потом выяснится, что на 16 МГц контроллере собираются ловить 500 нс импульсы!
Наплыв жаждущих НАНОСЕКУНД ...
Я не написал, что время между фронтами "спада" и "подъема" где-то 500нс.
Arduino UNO в дефолте работает вроде как на 8МГц.
Вопрос в том, если настроить прерывание на CANGE, хватит ли времени в прерывании еще и вызывать чтение значения с пина, чтобы понимать какое состояние - FALLING или RISING?
(по моим прикидкам порядка 4000 нс в каждую сторону. Да, это на частоте 16 МГц)
А то потом выяснится, что на 16 МГц контроллере собираются ловить 500 нс импульсы!
Автор имеет в виду 8 МГц (см. сообщение №5).
Получается, что под задачи ТС даже предложение dimax не годится?
Может быть, есть способы как-то обойти эту проблему?
Может быть изложите общую задачу? Глядишь и без обработки 500нс импульсов в прерывании удастся обойтись.
> Может быть изложите общую задачу? Глядишь и без обработки 500нс импульсов в прерывании удастся обойтись.
Я раздумываю над тем, можно ли на базе Arduino UNO сделать "эмулятор ПЗУ" для советской ПЭВМ "Микроша" через ее разъем "Внутренний интерфейс", который представляет собой, по сути системную шину, куда выведены шина данных, шина адреса, сигналы чтения/записи, сигналы выбора диапазонов адресов и прочее.
В Микроше используется микропроцессор К580ВМ80 с тактовой частотой 1.8МГц, но реальная скорость работы сильно ограничена контроллером дисплея, так что реальная частота как-бы плавающая, около 900Кгц.
Прерывание Arduino UNO я вешаю на передний фронт сигнала выбора нужного мне диапазона. В этом прерывании я считываю адрес с шины адреса с помощью четырех коммутаторов 4-1 с двухбитным адресом (555КП2), чтобы вместо 16 ножек использовать 6. Это дело уже работает. После получения адреса я должен из заранее подготовленного массива просто взять соответствующий байт и засунуть его на шину данных.
И на этом этапе у меня проблема, и я разбираюсь почему. По-хорошему, данные на шине адреса должны присутствовать только до заднего фронта сигнала выбора диапазона _и_ сигнала /RD. После чего Arduino должна перевести пины шины данных в высокоомное состояние. Если этого не сделать, то данные останутся на шине данных, и будут мешать данным, находящимся в других частях памяти компьютера, включая код текущей исполняемой программы.
Вот я и хочу понять, что происходит. То ли мне времени не хватает на выставление данных и перевод выходов Arduino в режим INPUT. То ли я неправильно понимаю, что такое высокоомное состояние, и режим INPUT для этого не подходит, а значит надо городить аппаратный регистр-буфер с возможностью выставления трех состояний на ногах.
Когда я сделаю "эмулятор ПЗУ" я хочу попробовать доработать его до "эмулятора ОЗУ", хотя бы на окно размером 2-4Кб, чтобы данные можно было передавать между Микрошей и Arduino в обе стороны. После этого можно будет пробовать сделать поддержку SD-карты, но это уже отдельный разговор.
Изобретаем велосипед ? https://github.com/andykarpov/radio-86rk-sdcard
Прерывание Arduino UNO я вешаю на передний фронт сигнала выбора нужного мне диапазона. В этом прерывании я считываю адрес с шины адреса с помощью четырех коммутаторов 4-1 с двухбитным адресом (555КП2),
Ок. А задний фронт зачем ловить? И в цифрах, пожалуйста
> Изобретаем велосипед ? https://github.com/andykarpov/radio-86rk-sdcard
Если почитать документацию, то увидим это:
Проблема в том, что в Мониторе заводской Микроши нет директивы работы с COM-портом R. А так же, до кучи, нет директив X и U. Для владельцев Радио-86РК это неожиданность, но это так.
Я, естественно, хочу сделать устройство, которое просто подключается к Микроше, без переделок/перепрошивки ROM самой Микроши.
Ок. А задний фронт зачем ловить? И в цифрах, пожалуйста
Вторым прерыванием, на Arduino UNO их два вроде как. Или тем же самым в режиме CHANGE, пока не понял как правильно. В цифрах ничего не скажу, я их не знаю. Смог замерить только самую короткую длительность сигнала выборки /32K, она составила 500нс, причем эта длительность замеряется в режиме, когда фактически к диапазону 8000-BFFF обращений нет. Возможно, этот короткий импульс нужен для регенерации потенциально подключенного ОЗУ, я не знаю точно. Если же сделать команду D8000,BFFF то длительность сигнала выборки /32К рандомно возрастает, причем по всей видимости кратно более чем в 10 раз, но точнее сказать не могу, мне мозгов не хватает понять как захватывать рандомные длительности на осциллографе, хотя он вроде как это могет.
Блин, только сейчас увидел что "зачем" а не "чем". Зачем - я уже написал в предыдущем сообщении, чтобы шину данных не оставлять включенной когда идет опрос других диапазонов адресов, например 0000-7FFF, чтобы эти данные не мешали штатной работе компьютера.
Не по Сеньке шапка.
Блин, только сейчас увидел что "зачем" а не "чем". Зачем - я уже написал в предыдущем сообщении, чтобы шину данных не оставлять включенной когда идет опрос других диапазонов адресов, например 0000-7FFF, чтобы эти данные не мешали штатной работе компьютера.
То есть ты собрался за 500нс успеть просканировать 4 коммутатора, потом сформировать результат, а потом еще и выплюнуть его? Причем раз задний фронт не заложен на чтение, значит результат должен быть выплюнут фактически по переднему фронту?
> То есть ты собрался за 500нс успеть просканировать 4 коммутатора, потом сформировать результат, а потом еще и выплюнуть его? Причем раз задний фронт не заложен на чтение, значит результат должен быть выплюнут фактически по переднему фронту?
Я же написал, что 500нс - это когда нет обращения к обслуживаемому диапазону. Когда идет обращение - в разы больше. По заднему фронту нужно всего лишь перевести шину данных в Z состояние, и то это происходит только в случае, если обращение реальное, а значит длинное, гораздо длиннее чем 500нс.
По переднему фронту смотришь по адресам - куда стучится микроша. Если не к вам - отбой. Если к вам, то выставляешь данные и переназначаешь прерывание на задний фронт. Ловишь задний фронт - снимаешь данные и переназначаешь прерывание на передний фронт.
И насколько я помню - там еще был сигнал готовности данных. Пока его на выставишь - микроша на паузе. Главное не растягивать процесс - регенерация заряда в ОЗУ нарушится и данные пропадут.
> И насколько я помню - там еще был сигнал готовности данных. Пока его на выставишь - Микроша на паузе. Главное не растягивать процесс - регенерация заряда в ОЗУ нарушится и данные пропадут.
Вот тут список всех сигналов:
https://webhamster.ru/mytetrashare/index/mtb0/163621373041975uf2oz
Какой из них больше похож на тот что вы помните?
Я не уверен что он есть на этой гребенке ...
Я же написал, что 500нс - ...бла-бла-бла...
1. эмулятор 2764, а лучше сразу 27128 можно сделать не напрягаясь на STM32 практически без обвеса, кроме преобразователя уровня, и ножек хватит. В ДШ на 27128 (100 нс) не уложиться без плясок с бубном, но в 1 мкс - скорее всего выйдет.
2. подобной херней чаще всего занимаются либо когда еще не дают, либо когда уже не стоит. Сорри.
В ДШ на 27128 (100 нс)
там в зависимости от производителя, встречались и на 70 нс, а обычно 120...100 это видимо среднее по фирмам...
PS я понимаю когда ПЗУ эмулируют на статической памяти, сдохли батарейки вызывай электронщика... встречал на вязальном оборудовании
//Я раздумываю над тем, можно ли на базе Arduino UNO сделать "эмулятор ПЗУ" для советской ПЭВМ "Микроша"
Про прерывания - забудь. Не успеет. Там выше правильно писали, вход+выход около 8мксек. Прерывания запрети и прямо в лопе, напрямую работая с регистрами пиши нужное. Может и успеет. По твоему описанию до конца не понятно.
А лучше - посмотри на вывод 23 у 580-го МП. Это вход готовности данных внешнего устройства. Пока нет готовности, МП остановится и будет ждать данных с шины. С помощью этого пина МП можно тормознуть как угодно. Хоть на вечно. Вплоть что данные тумблерами нащелкать на шине и отправить ГОТОВ.
Вплоть что данные тумблерами нащелкать на шине и отправить ГОТОВ.
вот, уже и забылось, пошаговый отладчик так и работал
Если мне не изменяет мой склероз, в микроше была возможность переключения на внешнее ПЗУ. Подключите вместо него ОЗУ, загружаемое из микроконтроллера. Алгоритм такой: останавливаем процессор (сигнал HOLD), переключаем наше ОЗУ на управление с ардуинки, пишем в него чего надо, переключаем обратно. Процессор читает уже наши команды...