Страница 1 из 1

Проблема с прерыванием PCINT

Добавлено: Вс сен 11, 2011 12:19:29
iustat
Здравствуйте,

К пинам PORTB5, PORTB6, PORTB7 подключены кнопки. При нажатии на кнопку, на соответствующий пин подается логическая 1. Необходимо при нажатии любой из них вызывать прерывание. Симулирую в протеус. Дело в том что при первом нажатии любой из кнопок - прерывание отрабатывает. Когда же пытаешься нажать на эту кнопку второй, третий.. раз, то прерывание не вызывается и регистр InterrCount не инкрементируется.

Подскажите что не так, или может это очередной глюк протеуса. Контроллер attiny2313

Инициализирую прерывание таким вот образом (это в RESET):

Код: Выделить всё

	outi PCMSK, (1<<PCINT5)|(1<<PCINT6)|(1<<PCINT7)	; vkliuciaem prerivanie na opredelennih pinah
	outi GIMSK, (1<<PCIE)  ;vkliuciaem prerivanie
Обработчик прерываний:

Код: Выделить всё

EXTERN_OVF:
	cli

	inc InterrCount  ; incrementiruem registr pri kajdom vizove prerivaniya

	out PORTD, InterrCount

	outi PCMSK, (0<<PCINT5)|(0<<PCINT6)|(0<<PCINT7)	; otkliuciaem prerivanie na pinah, cito bi vernuti pin v pred. sostoianie
        outi PINB, (0<<PINB5)|(0<<PINB6)|(0<<PINB7) ; menyaem sostoianie PIN
	outi PCMSK, (1<<PCINT5)|(1<<PCINT6)|(1<<PCINT7)	; vkliuciaem prerivanie obratno

       sei

reti

Re: Проблема с прерыванием PCINT

Добавлено: Вс сен 11, 2011 15:09:27
alexx82
Подозреваю что это происходит из-за глобального отключения прерываний в самом начале функции, т.к. при этом обработка прерывания завершается, и МК возвращается к выполнению главного цикла (могу и ошибаться).

PS. Решительно не могу понять, зачем нужна эта фигня:

Код: Выделить всё

   outi PCMSK, (0<<PCINT5)|(0<<PCINT6)|(0<<PCINT7)   ; otkliuciaem prerivanie na pinah, cito bi vernuti pin v pred. sostoianie
        outi PINB, (0<<PINB5)|(0<<PINB6)|(0<<PINB7) ; menyaem sostoianie PIN
   outi PCMSK, (1<<PCINT5)|(1<<PCINT6)|(1<<PCINT7)   ; vkliuciaem prerivanie obratno

Re: Проблема с прерыванием PCINT

Добавлено: Вс сен 11, 2011 18:44:43
iustat
Прерывание PCINT вызывается при любом изменении уровня на пине. Т.к. в первый раз (при нажатии кнопки) оно устанавливается в высокий уровень - второй раз оно будет вызвано, только если подать на этот пин низкий уровень. Ессно играться совершенно не хочется, потому необходимо вернуть состояние пина в уровень 0. А если я не отключу обработку прерывания PCINT на этих пинах, то оно будет вызвано еще раз, т.к. состояние входа мы программно изменили. В общем как-то так. Но вообще я их добавил, т.к. без них не работало. И при пошаговом проходе в AVR Studio увидел что неплохо бы их добавить.

А глобальное отключение прерываний здесь не при чем, т.к. 1 раз прерывание вызывается. Даже более того, у нас 3 кнопки и прерывание вызывается, если нажать на каждую кнопку по разу. Если на кнопку, которую мы уже нажимали нажать еще раз - прерывание не вызывается (в Proteus)

Re: Проблема с прерыванием PCINT

Добавлено: Вс сен 11, 2011 20:57:00
alexx82
iustat писал(а):Прерывание PCINT вызывается при любом изменении уровня на пине. Т.к. в первый раз (при нажатии кнопки) оно устанавливается в высокий уровень - второй раз оно будет вызвано, только если подать на этот пин низкий уровень. Ессно играться совершенно не хочется, потому необходимо вернуть состояние пина в уровень 0. А если я не отключу обработку прерывания PCINT на этих пинах, то оно будет вызвано еще раз, т.к. состояние входа мы программно изменили.
Как-то все слишком закручено у Вас получилось. :facepalm:

На самом деле не нужно так извращаться. Во-первых нужно подумать об антидребезге. Если он реализован аппаратно, то без вопросов. А во-вторых, не нужно ничего никуда возвращать. Нужно просто проигнорировать прерывание в том случае, когда при его вызове на всех пинах нули, поскольку PCINT срабатывает как по фронту, так и по спаду. Иначе он будет срабатывать и при отпускании кнопки.

И кстати, не нужно ориентироваться на протеус - микроконтроллеры он эмулирует как говно.