Сделать прерывание по FALLING и RISING на одном пине

xintrea
Offline
Зарегистрирован: 01.08.2011

Здравствуйте!

Имеется Arduino UNO. Нужно сделать два аппаратных прерывания на пине D2. Один обработчик должен обрабатывать FALLING на этом пине, второй обработчик должен обрабатывать RISING на этом же пине.

Возможно ли такое сделать? Судя по документации, определить можно только одно прерывание на одном пине, если определить второе, оно отменит первое.

Может быть, есть способы как-то обойти эту проблему?

 

 

 

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Может не маяться фигней и использовать CHANGE?

А в обработчике запоминать состояние порта. Если он HIGH - значит было с LOW на HIGH и наоборот. 
Так, вроде бы, логичнее. Не?

Green
Offline
Зарегистрирован: 01.10.2015

Либо использовать один обработчик в котором переключаться с FALLING на RISING и наоборот.

sadman41
Offline
Зарегистрирован: 19.10.2016

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

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Если очень хочется именно два разных прерывания - то соединить физически пины D2 и D3, и настроить их по-разному :)

xintrea
Offline
Зарегистрирован: 01.08.2011

Я не написал, что время между фронтами "спада" и "подъема" где-то 500нс.

Arduino UNO в дефолте работает вроде как на 8МГц.

Вопрос в том, если настроить прерывание на CANGE, хватит ли времени в прерывании еще и вызывать чтение значения с пина, чтобы понимать какое состояние - FALLING или RISING?

 

Kakmyc
Offline
Зарегистрирован: 15.01.2018

Времени в прерывании будет столько , сколько потребуется на выполнение кода в прерывании .
Вопрос лишь в том, не повлияет ли долгое нахождение в прерывании на работу основной программы.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

xintrea, с такими короткими импульсами даже первое прерывание не успеет завершиться.
Да и начаться толком тоже не успеет..

Upper
Offline
Зарегистрирован: 23.06.2020

xintrea

Вы можете написать планируемый алгоритм работы, и возможные варианты входных сигналов?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Теоретически минимально возможное прерывание занимает на AVR  восемь тактов: 3 на вход, 4 на выход и один на исполняемую команду. То есть на частоте 16 МГц требует как раз 500 нс. ;)))))))

----------------

Ведь уже 100500 раз сталкивались с тем, что не стоит давать ответы на абстрактные вопросы, типа "Интересуюсь Симочка - а скоки стоит океянский пароход?". А то потом выяснится, что на 16 МГц контроллере собираются ловить 500 нс импульсы!

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Наплыв жаждущих НАНОСЕКУНД ...

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

xintrea пишет:

Я не написал, что время между фронтами "спада" и "подъема" где-то 500нс.

Arduino UNO в дефолте работает вроде как на 8МГц.

Вопрос в том, если настроить прерывание на CANGE, хватит ли времени в прерывании еще и вызывать чтение значения с пина, чтобы понимать какое состояние - FALLING или RISING?

xintrea, как Вы думаете, сколько времени нужно камню, чтобы войти в прерывание (в частности, сохранить содержимое всех регистров в стеке), и сколько - чтобы выйти (в т.ч. восстановить значения всех регистров их стека)?

(по моим прикидкам порядка 4000 нс в каждую сторону. Да, это на частоте 16 МГц)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

wdrakula пишет:

А то потом выяснится, что на 16 МГц контроллере собираются ловить 500 нс импульсы!

Оптимист!

Автор имеет в виду 8 МГц (см. сообщение №5).

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

Получается, что под задачи ТС даже предложение dimax не годится?

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

xintrea пишет:

Может быть, есть способы как-то обойти эту проблему?

Может быть изложите общую задачу? Глядишь и без обработки 500нс импульсов в прерывании удастся обойтись.

xintrea
Offline
Зарегистрирован: 01.08.2011

> Может быть изложите общую задачу? Глядишь и без обработки 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-карты, но это уже отдельный разговор.

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Изобретаем велосипед ? https://github.com/andykarpov/radio-86rk-sdcard

rkit
Offline
Зарегистрирован: 23.11.2016

xintrea пишет:

Прерывание Arduino UNO я вешаю на передний фронт сигнала выбора нужного мне диапазона. В этом прерывании я считываю адрес с шины адреса с помощью четырех коммутаторов 4-1 с двухбитным адресом (555КП2),

Ок. А задний фронт зачем ловить? И в цифрах, пожалуйста

xintrea
Offline
Зарегистрирован: 01.08.2011

> Изобретаем велосипед ? https://github.com/andykarpov/radio-86rk-sdcard

Если почитать документацию, то увидим это:
 

Плата подключается к _параллельному_ порту компьютера.
На плате находится микроконтроллер, внутри которого находится эмулятор ПЗУ.
Загрузить программу из ПЗУ можно с помощью стандартной директивы R0,100 G.

Проблема в том, что в Мониторе заводской Микроши нет директивы работы с COM-портом R. А так же, до кучи, нет директив X и U. Для владельцев Радио-86РК это неожиданность, но это так.

Я, естественно, хочу сделать устройство, которое просто подключается к Микроше, без переделок/перепрошивки ROM самой Микроши.

 

xintrea
Offline
Зарегистрирован: 01.08.2011

rkit пишет:

Ок. А задний фронт зачем ловить? И в цифрах, пожалуйста

Вторым прерыванием, на Arduino UNO их два вроде как. Или тем же самым в режиме CHANGE, пока не понял как правильно. В цифрах ничего не скажу, я их не знаю. Смог замерить только самую короткую длительность сигнала выборки /32K, она составила 500нс, причем эта длительность замеряется в режиме, когда фактически к диапазону 8000-BFFF обращений нет. Возможно, этот короткий импульс нужен для регенерации потенциально подключенного ОЗУ, я не знаю точно. Если же сделать команду D8000,BFFF то длительность сигнала выборки /32К рандомно возрастает, причем по всей видимости кратно более чем в 10 раз, но точнее сказать не могу, мне мозгов не хватает понять как захватывать рандомные длительности на осциллографе, хотя он вроде как это могет.

Блин, только сейчас увидел что "зачем" а не "чем". Зачем - я уже написал в предыдущем сообщении, чтобы шину данных не оставлять включенной когда идет опрос других диапазонов адресов, например 0000-7FFF, чтобы эти данные не мешали штатной работе компьютера.

 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Не по Сеньке шапка. 

rkit
Offline
Зарегистрирован: 23.11.2016

xintrea пишет:

Блин, только сейчас увидел что "зачем" а не "чем". Зачем - я уже написал в предыдущем сообщении, чтобы шину данных не оставлять включенной когда идет опрос других диапазонов адресов, например 0000-7FFF, чтобы эти данные не мешали штатной работе компьютера.

 

То есть ты собрался за 500нс успеть просканировать 4 коммутатора, потом сформировать результат, а потом еще и выплюнуть его? Причем раз задний фронт не заложен на чтение, значит результат должен быть выплюнут фактически по переднему фронту?

xintrea
Offline
Зарегистрирован: 01.08.2011

> То есть ты собрался за 500нс успеть просканировать 4 коммутатора, потом сформировать результат, а потом еще и выплюнуть его? Причем раз задний фронт не заложен на чтение, значит результат должен быть выплюнут фактически по переднему фронту?

Я же написал, что 500нс - это когда нет обращения к обслуживаемому диапазону. Когда идет обращение - в разы больше. По заднему фронту нужно всего лишь перевести шину данных в Z состояние, и то это происходит только в случае, если обращение реальное, а значит длинное, гораздо длиннее чем 500нс.

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

По переднему фронту смотришь по адресам - куда стучится микроша. Если не к вам - отбой. Если к вам, то выставляешь данные и переназначаешь прерывание на задний фронт. Ловишь задний фронт - снимаешь данные и переназначаешь прерывание на передний фронт.

И насколько я помню - там еще был сигнал готовности данных. Пока его на выставишь - микроша на паузе. Главное не растягивать процесс - регенерация заряда в ОЗУ нарушится и данные пропадут.

xintrea
Offline
Зарегистрирован: 01.08.2011

> И насколько я помню - там еще был сигнал готовности данных. Пока его на выставишь - Микроша на паузе. Главное не растягивать процесс - регенерация заряда в ОЗУ нарушится и данные пропадут.

Вот тут список всех сигналов:

https://webhamster.ru/mytetrashare/index/mtb0/163621373041975uf2oz

Какой из них больше похож на тот что вы помните?

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Я не уверен что он есть на этой гребенке ...

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

xintrea пишет:

Я же написал, что 500нс - ...бла-бла-бла...

1. эмулятор 2764, а лучше сразу 27128 можно сделать не напрягаясь на STM32 практически без обвеса, кроме преобразователя уровня, и ножек хватит.  В ДШ на 27128 (100 нс) не уложиться без плясок с бубном, но в 1 мкс - скорее всего выйдет.

2. подобной херней чаще всего занимаются либо когда еще не дают, либо когда уже не стоит. Сорри.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

wdrakula пишет:

В ДШ на 27128 (100 нс)

там в зависимости от производителя, встречались и на 70 нс, а обычно 120...100 это видимо среднее по фирмам...
PS я понимаю когда ПЗУ эмулируют на статической памяти, сдохли батарейки вызывай электронщика... встречал на вязальном оборудовании

Logik
Offline
Зарегистрирован: 05.08.2014

//Я раздумываю над тем, можно ли на базе Arduino UNO сделать "эмулятор ПЗУ" для советской ПЭВМ "Микроша" 

Про прерывания - забудь. Не успеет. Там выше правильно писали, вход+выход около 8мксек. Прерывания запрети и прямо в лопе, напрямую работая с регистрами пиши нужное. Может и успеет. По твоему описанию до конца не понятно.

 А лучше - посмотри на вывод 23 у 580-го МП. Это вход готовности данных внешнего устройства. Пока нет готовности, МП остановится и будет ждать данных с шины.  С помощью этого пина МП можно тормознуть как угодно. Хоть на вечно. Вплоть что данные тумблерами нащелкать на шине и отправить ГОТОВ.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Logik пишет:

 Вплоть что данные тумблерами нащелкать на шине и отправить ГОТОВ.

вот, уже и забылось, пошаговый отладчик так и работал

imp
Offline
Зарегистрирован: 20.06.2020

Если мне не изменяет мой склероз, в микроше была возможность переключения на внешнее ПЗУ. Подключите вместо него ОЗУ, загружаемое из микроконтроллера. Алгоритм такой: останавливаем процессор (сигнал HOLD), переключаем наше ОЗУ на управление с ардуинки, пишем в него чего надо, переключаем обратно. Процессор читает уже наши команды...