Программа считает количество прерываний по линии INT0 и выводит его в порт А. Я отдельно рассматриваю случаи, когда прерывание вызывается низким уровнем сигнала, передним или задним фронтом и изменением уровня.
В табл. 1 приведены виды активности, которые могут привести к возникновению прерывания, и соответствующие им коды в MCUCR (биты Interrupt Sense Control: ISC00 и ISC01).
Таблица 1.
Листинг 1.
В табл. 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.
Комментариев нет:
Отправить комментарий