Изучаем работу прерывания с помощью языка программирования Assembler на микроконтроллере Atmega8.

Страница на этапе разработки

В данном уроке мы с Вами изучим механизм работы прерываний. У нас будет настроено два прерывания: Reset (которое происходит при перезагрузке микроконтроллера) и INT0 которое срабатывает при изменении уровня сигнала на ножке PD2.

.include «m8def.inc»

.macro Delay;процедура задержки
ldi Razr1, @0;старший бит задержки
ldi Razr0, @1;младший байт задержки
R_sub:
subi Razr0,1
sbci Razr1,0
brcc R_sub
.endm

.def temp = r16; рабочая переменная
.def Razr0 = r17; разряды задержки
.def Razr1 = r18
;========прерывание==========
rjmp RESET
rjmp EXT_INT0

EXT_INT0: ;кнопка нажата
clr temp ;запрещаем прерывание INT0
out GICR, temp
Delay 1,$F4; задержка 2мс
sbic PinD,2 ;пропустить если нажата
rjmp push_butt ; иначе ничего не делаем
sbi PORTD, PORTD0 ; подача на пин PD0 высокого уровня
cbi PORTD, PORTD1 ; подача на пин PD1 низкого уровня
Delay $FF,$FF
Delay $FF,$FF
Delay $FF,$FF
push_butt:
ldi temp,(1<<INT0);разрешаем прерывание INT0
out GICR,temp
reti ;конец прерывания INT0

Reset:
; — инициализация стека —
LDI temp, Low(RAMEND) ; младший байт конечного адреса ОЗУ в R16
OUT SPL, temp ; установка младшего байта указателя стека
LDI temp, High(RAMEND) ; старший байт конечного адреса ОЗУ в R16
OUT SPH, temp ; установка старшего байта указателя стека


; — устанавливаем пины PD0 и PD1 порта PORTD (PD) на вывод, остальные на вход.
ldi temp, 0b00000011 ; поместим в регистр R16 число 3 (0x3)
out DDRD, temp ; загрузим значение из регистра R16 в порт DDRD
ldi temp, 0b00000100 ; подтягивающий резистор
out PORTD, temp; подтягивающий резистор
ldi temp, (1<<ISC01)|(1<<ISC00); пре. INT0 по фронту
out MCUCR, temp
ldi temp, (1<<INT0) ; разрешаем прерывание INT0
out GICR, temp
sei ; разрешаем прерывание

Gcykle: ;цикл отслеживания кнопки
sbi PORTD, PORTD1 ; подача на пин PD0 высокого уровня
cbi PORTD, PORTD0 ; подача на пин PD1 низкого уровня
rjmp Gcykle ;вернуться обратно, если не нажата