Перейти к содержанию
    

Прерывания на PIC16F628

НЕдавно начал знакомиться с PIC.

Хочу научиться работать с прерываниями.

Скажите правильно ли я понимаю и, пожалуйста, подскажите в чем дело.

 

Написал кусок кода, который разбит на 2 части + подпрограмма обрабоки прерываения.

1-ая часть глобально прерывания запрещены.

2-ая часть глобально прерываения разрешены + разрешено прерывание по входу RB0/INT.

 

Прерывание настраиваю по спаду, т.е. из 1 в 0.

Инициализирую прерывания путем коммутации 0 двухпозиционной кнопкой

(в моем понимании это ключ).

 

Для наглядности подключаю 2 светодиода на RB1 и RB2.

 

RB1 - c определенной частотой мигает - основная часть программы.

RB1 =1 - (светодиод горит) - тогда прерывания запрещены (1-ая часть).

RB1=0 - (светодиод не горит) - тогда прерывания разарешены (2-ая часть).

 

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

При выходе из подпрограммы обработки прерывания светодиод гаснет.

Выход из прерывания - при смене на входе RB0/INT уровня из 0 в 1 (кнопка нажата снова - ключ разомкнут).

 

Дело в том, что если нажата кнопка в момент разрешения прерываний ( светодиод на RB1 не горит),

то все работает как надо, т.е. загорается светодиод на RB2 (уход прерывание) и горит до тех пор, пока кнопка не возвращена в исходное положение.

 

Но вот когда кнопка нажата в момент запрещения прерываения (светодиод на RB1 горит), в момент, когда он на RB1 гаснет - прерывание почему-то не следует,

т.е. не загоратется светодод на RB2.

 

Т.е. я так понимаю.

Если кнопка нажата в момент разрешения прерываения (переход из 1 в 0) - то без вопросов произходит уход в прерываение.

Если кнопка нажата когда прерываения запрещены (переход из 1 в 0) - то два варианта:

 

а) Если 0 провисит до момента когда прерывания разрешены (собственно как я и хочу зымыкаю ключ и жду когда загорится светодиод на RB2) - дожно произойти прерываения. (У меня его почему-то нет???? В этом вся проблема. Не понимаю почему...)

б) Если нет (кнопку нажали и вернули еще раз, т.е 1->0->1) то прерывания не должно последовать.

 

И еще, когда разрешаю прерывения всегда, т.е. неважно горит или не горит светодиод на RB1 - то все работает, т.е. уходит в прерываение.

 

 

Объясните, пожалуйста, в чем трабл. Может я что не так понимаю?

 

 

Текст программы в данным момент прикрепить не могу (с собой просто не имею), прикреплю по возможности как тока так сразу.

Про дребезг контактов слышал, пытаюсь с ним бороться не программно, а при помощи схемы (На рисунке - вариант д, т.е

на неинвертирующем логическом элементе)

 

Контроллер PIC16F628.

 

Заранее благодарен.

 

post-30034-1197280701_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а) Если 0 провисит до момента когда прерывания разрешены (собственно как я и хочу зымыкаю ключ и жду когда загорится светодиод на RB2) - дожно произойти прерываения. (У меня его почему-то нет???? В этом вся проблема. Не понимаю почему...)

б) Если нет (кнопку нажали и вернули еще раз, т.е 1->0->1) то прерывания не должно последовать.

 

Прерывание генерируется если INTF && INTE && GIE = 1.

в случе а и б флаг INTF регистра INTCON поднимается в 1, а GIE равен 0. Т.е. условие не выполняется.

После установки бита GIE в 1 прерывание должно возникнуть, независимо от логического уровня на порту RB0/INT.

Скорее всего где-то в программе чистится бит INTF до того как GIE устанавливается в 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Постарайтесь разобраться что такое флаг (XXIF) прерывания и маска (GIE или XXIE) прерывания. Это разные вещи и они по-разному работают. Флаг - это индикатор, что событие наступило. Он будет выставляться вне зависимости от того, запрещено ли это прерывание или нет. Причем ведет себя как триггер - раз событие наступило, флаг выставляется и это вам его сбросить. Если в регистре масок прерываний напротив этого флага (соответствующий ему бит XXIE) стоит 0 - запрос прерывания маскированный, и не будет вызывать прерывание, пока вы не поставите на это место 1, но в тот же момент, если флаг уже выставлен, произойдет прерывание. Общий бит запрещения прерывания GIE, маскирует (запрещает) сразу все прерывания.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вроде бы понял и нашел ошибку в коде. Запрещая и разрешая прерывания я портил флаг внешнего прерывания, записывая в его "0" командами clrf IntCon , movlw B'10010000';

movwf IntCon; и снова clrf IntCon .

 

 

Я хотел проверить как раз тот случай, когда прерываение поступило в момент его запрета, а выполнилось сразу же после разрешения (для этого все это с морганием диодов).

 

А на самом деле получалось, что перед самым разрешением прерываентя я обнулял флаг внешнего прерывания, т.е. даже если оно и было - МК считал, что его оне было. Тем самым прерывание не наступало.

 

Я так понимаю, единственным местом где флаг прерывания необходимо сбрасывать в нуль - это при выходе из подпрограммы обработки прерывания.

 

 

 

Код программы в приложении.

Вроде бы правильно рассуждаю, если что поправьте. Домой приду сразу же проверю.

 

Заранее благодарен!

Preriv.asm.txt

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Я так понимаю, единственным местом где флаг прерывания необходимо сбрасывать в нуль - это при выходе из подпрограммы обработки прерывания...

 

Очень даже правильно вы поняли. :) Если вам нужно все равно этого события обработать. Иногда бывает, что на определенное время отпадает нужда в обработки прерывания, вот тогда тоже можно флаги обнулить, чтобы потом (когда прерывания снова разрешить) не было лишнее вхождение в процедуру обработки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Места, где портится флаг прерывания исправил. Заработало!!!! Но только когда уровень 0 сохраняется до момента разрешения прерывания. Т.е. нажал кнопку в момент запрета прерывания и жду момента разрешения прерывания, в этом момент оно возникает. Потом возвращаю кнопку в исходное состояние происходит выход из подпрограммы обработки прерывания.

 

Возник новый вопрос.

Если в момент запрета прерываний скоммутировать кнопку и вернуть ее в исходное сосстояние (1->0->1 на входе INT), то по идее флаг то все равно выставится в 1 и в момент разрешения прерывания БУДЕТ : GIE=1 , INTE=1 и сам флаг INTF=1, должно прерваться. Но не прерывается почему-то.Возникает ощущения, что к тому что GIE=1 , INTE=1 и INTF=1 должен еще висеть необходимый уровень (Если по спаду прерывание,то уровень 0). Так ли это?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если в момент запрета прерываний скоммутировать кнопку и вернуть ее в исходное сосстояние (1->0->1 на входе INT), то по идее флаг то все равно выставится в 1 и в момент разрешения прерывания БУДЕТ : GIE=1 , INTE=1 и сам флаг INTF=1, должно прерваться. Но не прерывается почему-то. Возникает ощущения, что к тому что GIE=1 , INTE=1 и INTF=1 должен еще висеть необходимый уровень (Если по спаду прерывание,то уровень 0). Так ли это?

Нет. Вам уже рассказали про необходимое и достаточное условие возникновения прерывания от ноги RB0. В даташите на картинке FIGURE 14-14: INTERRUPT LOGIC видно, что текущий уровень на RB0 никаким образом на это не влияет.

Где сбрасывать флаг прерывания - на входе в п/п его обработки или на выходе, - зависит от того, собираетесь ли Вы обрабатывать повторное событие, вызывающее прерывание, возникшее во время обработки предыдущего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос решился сам , все верно. Прерываение было просто я его зрительно не мог наблюдать. Ведь выход из подпрограммы по уровню "1" на входе INT , а еще до разрешения прерывания эта еденица уже висела. Т.е. прерывалось и сразу выходило, а я визуально не мог его наблюдать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...