Использования внешнего прерывания INT0 и INT1.

В этой части разберем простой пример использования внешнего прерывания INT0 и INT1.

Если посмотрим на прошлую программу, то видно, что микроконтроллер практические все свои ресурсы тратит на отслеживание срабатывания порта PD0. Таким образом наша программа не может быть расширена, так как нужно будет все время возращаться к проверке порта ввода. Чтобы от этого избавиться, нужно задействовать внутренний модуль внешнего прерывания INTx.

Первым делом необходимо в технической документации МК посмотреть адрес вектора прерывания «External Interrupt Request 0».

1

В программе адрес INT0 нужно прописать сразу же после метки Reset. Так как наша программа будет обрабатываться в цикле аппаратного прерывания, то цикл «main» остается пустым. Важно помнить, что при использовании прерываний, цикл main должен присутствовать в программе. Не зависимо от того будет ли там что-то написано или нет.

Так как вывод прерывания INT0 припадает на порт PD2, то нужно перенести кнопку с PD0 на PD2 и произвести настройку порта на ввод.

Чтобы разрешить использование прерывания INT0, необходимо внести данные в регистр GIMSK, согласно таблице ниже.

2

Следующим шагом будет настройка условий прерывания. Параметры записываются в регистр MCUCR.

3

Как видно из таблицы, с помощью битов ISCxx можно настроить условие прерывания по переднему фронту, по заднему и по изменению логического состояния пина.

Перенесем нашу прошлую программу в прерывание INT0 и проверим ее работу в Proteus.

.device Attiny2313 ; указываем тип устройства

.include “tn2313def.inc” ; подключаем файл директив МК ATtiny2313

.def temp = r16 ; задаем имя нашему регистру общего назначения

.org 0x0000 ; начало программы с 0 адреса
rjmp reset

.org 0x001 ;адрес нашего прерывания

rjmp INT_0

reset:

ldi temp,ramend ; грузим значение ramend в регистр temp

out $3d, temp ;

ser temp ; настраиваем все выводы порта В на выход

out DDRB, temp ;

ldi temp,0b00000100;настрйока PD2 на вход

out PORTD,temp

ldi temp,(1<

out GIMSK,temp

ldi temp,(1<

out MCUCR,temp

sei

ldi r22,1

out PORTB,r22

main:

rjmp main

INT_0:

rcall delay

rol r22

out PORTB,r22

reti

delay:

clr r20

clr r21

d_1:

inc r20

cpi r20,200

brne d_1

d_2:

inc r21

cpi r21,50

brne d_1

ret

Как видим программа сильно упростилась. Сейчас нет необходимости отслеживать состояние выходного сигнала, тем самым мы экономим производительность время микроконтроллера.

В данном примере настроили прерывание по заднему фронту сигнала с порта PD2. Задержка delay предотвращает дребезг контакта и ложное выполнение программы.

На рисунке ниже видно срабатывание кнопки (канал А) и включение светодиода на порте B. Апааратное прерывание настроено на задний фронт сигнала, поэтому выполнение программы началось только после отпускания кнопки. Перед тем как на PВ2 установилась логическая единица, была выполнена задержка длительностью 100мс. Такого интервала вполне достаточно для предотвращения дребезга контакта.

4

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

Чтобы применить прерывание INT1 нужно внести дополнительные настройки в регистры GIMSK и MCUCR.

ldi temp,(1<

out GIMSK,temp

ldi temp,(1<

out MCUCR,temp

Таким образом, мы разрешили использование двух меток прерываний. Если в МК имеется вектор INT2 то по такому же образу можно добавить следующую метку.




Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *


Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>