19 августа 2012 г.

Прерывание по уровню и фронту

Программа считает количество прерываний по линии INT0 и выводит его в порт А. Я отдельно рассматриваю случаи, когда прерывание вызывается низким уровнем сигнала, передним или задним фронтом и изменением уровня.

В табл. 1 приведены виды активности, которые могут привести к возникновению прерывания, и соответствующие им коды в MCUCR (биты Interrupt Sense Control: ISC00 и ISC01).

Таблица 1.
ISC01 ISC00 Описание
0 0 Низкий уровень на INT0 вызывает прерывание.
0 1 Любое изменение на INT0 вызывает прерывание.
1 0 Прерывание возникает по заднему фронту на INT0.
1 1 Прерывание возникает по переднему фронту на INT0.

Перед изменением битов ISC00/ISC00 прерывание INT0 нужно отключить путем сброса соответствующего бита в регистре GIMSK. В противном случае в момент изменения может возникнуть прерывание. Поскольку по умолчанию прерывание INT0 запрещено, сброс не требуется. Я просто сначала произвожу манипуляции с битами ISC, а потом разрешаю INT0.

Я отключаю аналоговый компаратор записью единицы в бит ACD регистра ACSR, чтобы уменьшить энергопотребление. Правда, это даст выигрыш только когда МК работает в одном из режимов энергосбережения. И вообще, это не имеет никакого значения для нашей программы.

Листинг программы привожу ниже. Строки, в которых производятся манипуляции с битами ISC закомментированы. В ISC01 и ISC00 по умолчанию нули, таким образом, прерывание будет вызвано низким уровнем на контакте INT0.

Листинг 1.
.device ATiny26
.include "tn26def.inc"

.def temp = r16
.def Counter = r17

rjmp RESET ; Reset handler
rjmp EXT_INT0 ; IRQ0 handler
reti; rjmp PIN_CHANGE ; Pin change handler
reti; rjmp TIM1_CMP1A ; Timer1 compare match 1A
reti; rjmp TIM1_CMP1B ; Timer1 compare match 1B
reti; rjmp TIM1_OVF ; Timer1 overflow handler
reti; rjmp TIM0_OVF ; Timer0 overflow handler
reti; rjmp USI_STRT ; USI Start handler
reti; rjmp USI_OVF ; USI Overflow handler
reti; rjmp EE_RDY ; EEPROM Ready handler
reti; rjmp ANA_COMP ; Analog Comparator handler
reti; rjmp ADC ; ADC Conversion Handler
;

EXT_INT0:
    inc Counter
    out PORTA, Counter

RESET:
    ldi r16, RAMEND ; Main program start
    out SP, r16

    ;set all A port contacts to OUT mode
    ldi temp, 0b11111111
    out DDRA, temp

    ;turn off Analog Comparator
    ldi temp, (1<<ACD)
    out ACSR, temp

    ;pull-up resistor
    ldi temp, 0b00000010
    out PORTB, temp

    ;ldi temp, (1<<ISC00)
    ;out MCUCR, temp

    ;ldi temp, (1<<ISC01)
    ;out MCUCR, temp

    ;allow external interrupt interrupt INT0
    ldi temp, (1<<INT0)
    out GIMSK, temp
    sei

MAIN_CYCLE:
rjmp MAIN_CYCLE

Поочередно или одновременно включая строки с записью единиц в ISC01 и ISC00, активируем остальные 3 режима (табл. 1).

Ниже можно посмотреть видео с демонстрацией работы программы в разных режимах. В режиме прерывания по фронту можно видеть увеличение счетчика на 2 при однократном нажатии кнопки из-за дребезга контактов. В режиме прерывания по низкому уровню, когда кнопка нажата и на INT0 низкий уровень, прерывания генерируются постоянно. В режиме прерывания по изменению уровня прерывание генерируется как при нажатии кнопки (уровень меняется с высокого на низкий), так и при отпускании (уровень меняется с низкого на высокий).

1. Прерывание по низкому уровню на INT0.

2. Прерывание по изменению уровня на INT0.

3. Прерывание по заднему фронту на INT0.

4. Прерывание по переднему фронту на INT0. 

Комментариев нет:

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