реклама на сайте
подробности

 
 
> рекурсивное прерывание, Как оно из себя выглядит?
ytkopobot
сообщение Feb 19 2009, 11:16
Сообщение #1





Группа: Новичок
Сообщений: 11
Регистрация: 2-06-08
Пользователь №: 38 002



Надо реализовать по нажатию на кнопочку рекурсивное прерывание.
Не совсем представляю как из обычного сделать рекурсивное? То есть чтоб могло само себя прерывать..
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 10)
_Pasha
сообщение Feb 19 2009, 11:31
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Код
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
Go to the top of the page
 
+Quote Post
ytkopobot
сообщение Feb 19 2009, 11:43
Сообщение #3





Группа: Новичок
Сообщений: 11
Регистрация: 2-06-08
Пользователь №: 38 002



ааа. я извиняюсь, clr r0 что делает с р0? Я знаю что оно работает с битами, или очищает А.
И честно говоря не пойму, за счёт чего разрешится прерывание самого себя?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 19 2009, 12:20
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ytkopobot @ Feb 19 2009, 15:43) *
И честно говоря не пойму, за счёт чего разрешится прерывание самого себя?


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


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

Надо добавить clr IE0 если будет прерывание по уровню, а не перепаду
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 19 2009, 12:24
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(ytkopobot @ Feb 19 2009, 14:16) *
Надо реализовать по нажатию на кнопочку рекурсивное прерывание. Не совсем представляю как из обычного сделать рекурсивное? То есть чтоб могло само себя прерывать..
Не совсем понял - что нужно то? Чтобы процедура обработки прерывания могла бы прерваться этим же событием? Какое прерывание? INT0? Другое?
Если в процедуре обработки прерывания не нужно сбрасывать флаги (как, например, для UART сбрасывают RI/TI), то первой же командой нужно разрешить прерывания. Иначе - сделать это после сброса флагов. Вот только смысл рекурсивного прерывания - не понимаю... Зачем???
Go to the top of the page
 
+Quote Post
тау
сообщение Feb 19 2009, 12:59
Сообщение #6


.
******

Группа: Участник
Сообщений: 2 424
Регистрация: 25-12-08
Пользователь №: 42 757



ytkopobot, не забудьте про команду
reti
без её исполнения повторно войти в прерывание такого же или низшего приоритета невозможно.
То есть, внутри процедуры обработки прерывания нужно исполнить команду "reti" с заранее подготовленным стеком, чтобы не вернуться случайно в исходную программу а остаться в обработчике прерывания , дабы обеспечить рекурсию.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 19 2009, 13:09
Сообщение #7


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(тау @ 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
Go to the top of the page
 
+Quote Post
Палыч
сообщение Feb 19 2009, 13:23
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Стоп! Кажется, выше - наврал... В голове перепутались МК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
Go to the top of the page
 
+Quote Post
ytkopobot
сообщение Feb 19 2009, 14:49
Сообщение #9





Группа: Новичок
Сообщений: 11
Регистрация: 2-06-08
Пользователь №: 38 002



На самом деле что нужно:
Есть кнопочка, её нажатие инициирует внешнее прерывание 1, кнопочка для перелистывания номеров телефонной книги. При нажатии на кнопочку светится номер. Ну допустим минуту он светится. Но допустим я не хочу ждать минуту, а сразу же снова жму на кнопочку, чтобы загорелся следующий.
Спросила- сказали рекурсивное прерывание...

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

====
кстати второй раз сказали что можно и без рекурсивного. Просто флаг выставлять и всё smile.gif Буду пробовать smile.gif

Сообщение отредактировал ytkopobot - Feb 19 2009, 15:03
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 19 2009, 15:04
Сообщение #10


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(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) *
Спросила- сказали рекурсивное прерывание...
Ага, и через несколько номеров получаете переполнение стека с вылетом программы. Рекурсивные (вложенные) прерывания бывают нужны, но не в этом случае.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ytkopobot
сообщение Feb 19 2009, 15:45
Сообщение #11





Группа: Новичок
Сообщений: 11
Регистрация: 2-06-08
Пользователь №: 38 002



Да, и правда smile.gif
Сначала себе голову заморочила, потом другим smile.gif
На самом деле мне когда сказали про флаг, я уже и сама поняла что это очень просто smile.gif)))
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 21:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01443 секунд с 7
ELECTRONIX ©2004-2016