Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: рекурсивное прерывание
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры > MCS51
ytkopobot
Надо реализовать по нажатию на кнопочку рекурсивное прерывание.
Не совсем представляю как из обычного сделать рекурсивное? То есть чтоб могло само себя прерывать..
_Pasha
Код
CSEG

org 0

ajmp start

ORG 3

ajmp intr

ORG 25H

start:

; не помню, что там настраивать, чтоб int0 работал

eall:

    setb EA; разрешили прер

forever: ajmp forever

intr:

   clr r0

dbnc: djnz r0,dbnc; антидребезг

   ajmp eall


Жирновато для 51-й - стек переполнится в моментsad.gif
ytkopobot
ааа. я извиняюсь, clr r0 что делает с р0? Я знаю что оно работает с битами, или очищает А.
И честно говоря не пойму, за счёт чего разрешится прерывание самого себя?
_Pasha
Цитата(ytkopobot @ Feb 19 2009, 15:43) *
И честно говоря не пойму, за счёт чего разрешится прерывание самого себя?


Протупил : mov r0,#0


прерывание разрешается битом EA

Надо добавить clr IE0 если будет прерывание по уровню, а не перепаду
Палыч
Цитата(ytkopobot @ Feb 19 2009, 14:16) *
Надо реализовать по нажатию на кнопочку рекурсивное прерывание. Не совсем представляю как из обычного сделать рекурсивное? То есть чтоб могло само себя прерывать..
Не совсем понял - что нужно то? Чтобы процедура обработки прерывания могла бы прерваться этим же событием? Какое прерывание? INT0? Другое?
Если в процедуре обработки прерывания не нужно сбрасывать флаги (как, например, для UART сбрасывают RI/TI), то первой же командой нужно разрешить прерывания. Иначе - сделать это после сброса флагов. Вот только смысл рекурсивного прерывания - не понимаю... Зачем???
тау
ytkopobot, не забудьте про команду
reti
без её исполнения повторно войти в прерывание такого же или низшего приоритета невозможно.
То есть, внутри процедуры обработки прерывания нужно исполнить команду "reti" с заранее подготовленным стеком, чтобы не вернуться случайно в исходную программу а остаться в обработчике прерывания , дабы обеспечить рекурсию.
_Pasha
Цитата(тау @ Feb 19 2009, 16:59) *
ytkopobot, не забудьте про команду
reti

Это делается так

Код
intr:
     mov r0,#0
     dbnc: djnz r0,dbnc; антидребезг
     acall dummy_proc


forever_intr: rjmp forever_intr; здесь остались в прерывании

dummy_proc: reti
Палыч
Стоп! Кажется, выше - наврал... В голове перепутались МК51 и AVR... Если в очередной раз не путаю - в МК51 есть внутренний, недоступный стек уровня прерывания, который не даёт прервать свою же процедуру обработки прерывания. Тогда - выход один: имитация выхода из прерывания по IRET с целью перехода системы прерывания МК на более низкий уровень. Получится - геморой... Нужно затолкнуть в стек адрес той части обработчика, где будет обрабатываться прерывание уже при разрешенном прерывании; и выполнить IRET. По IRET Вы заставите систему прерывания понизить уровень прерывания и перейти на процедуру обработки, из которой выходить нужно уже не по IRET, а по RET...
Т.е. что-то такое:
Код
;Обработчик прерывания
;Сохранение PSW, ACC, других регистров
  push PSW
  push A
  .....
  mov A, #LOW Continue
  push A
  mov A, #HIGH Continue
  push A
  iret
;Продолжение обработки прерывания
Continue:
; Что-то там выполняем
  .....
;Восстановление регистров, ACC, PSW
  .....
  pop A
  pop PSW
  ret
ytkopobot
На самом деле что нужно:
Есть кнопочка, её нажатие инициирует внешнее прерывание 1, кнопочка для перелистывания номеров телефонной книги. При нажатии на кнопочку светится номер. Ну допустим минуту он светится. Но допустим я не хочу ждать минуту, а сразу же снова жму на кнопочку, чтобы загорелся следующий.
Спросила- сказали рекурсивное прерывание...

Палыч, что значит
mov A, #LOW Continue ?

====
кстати второй раз сказали что можно и без рекурсивного. Просто флаг выставлять и всё smile.gif Буду пробовать smile.gif
Сергей Борщ
Цитата(ytkopobot @ Feb 19 2009, 16:49) *
На самом деле что нужно:
Классический пример картинки из соседней ветки: 




Цитата(ytkopobot @ Feb 19 2009, 16:49) *
Есть кнопочка, её нажатие инициирует внешнее прерывание 1, кнопочка для перелистывания номеров телефонной книги. При нажатии на кнопочку светится номер. Ну допустим минуту он светится. Но допустим я не хочу ждать минуту, а сразу же снова жму на кнопочку, чтобы загорелся следующий.
Нажали кнопку, получили прерывание. Выставили флаг "показать номер". В основном цикле:

1) если нет флага, поделать что-то полезное. Если есть - шаг 3
2) перейти на шаг 1
3) заряжаете счетчик на 1 минуту, сбрасываете флаг, показываете номер.
4) если счетчик отсчитал минуту, то шаг 6
5) Если увидели флаг "показать номер" - передвигаете указатель на следующий номер и переходите к шагу 3
6) переходите к шагу 4
7) Гасите номер, переходите к шагу 1.
Цитата(ytkopobot @ Feb 19 2009, 16:49) *
Спросила- сказали рекурсивное прерывание...
Ага, и через несколько номеров получаете переполнение стека с вылетом программы. Рекурсивные (вложенные) прерывания бывают нужны, но не в этом случае.
ytkopobot
Да, и правда smile.gif
Сначала себе голову заморочила, потом другим smile.gif
На самом деле мне когда сказали про флаг, я уже и сама поняла что это очень просто smile.gif)))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.