.cseg
.ORG 0 ; векторы прерываний
rjmp reset
reti
reti
reti
reti
rjmp tick16 ; прерывание по переполнению таймера T1
reti ; прерывание по переполнению таймера T0 ($006)
reti
reti
reti
rjmp comp_isr ; по прерыванию от аналогового компаратора
reti
reti
reti
reti
reti
reti
reti
retireset: ; *** Действия после включения или сброса
; * ИНИЦИАЛИЗАЦИЯ СТЕКА
ldi temp,RAMEND
out SPL,temp
; * инициализация оборудования
reset2:
; * компаратор
ldi temp,(1 << ACBG)|(1 << ACI)|(1 << ACIE) | (1 << ACIS1)|(1 << ACIS0)
out ACSR,temp ; AIN0 подключен к ИОН 1.2Вmax, очищаем флаг прерывания
; разрешаем прерывания от компаратора, прерывание - по переднему фронту
ldi temp,0b00000010 ; выключаем цифровой буфер на входе PB1(AIN1)
out DIDR,temp
; инициализация портов
ldi temp,0b11111101 ;
out DDRB,temp ;
ldi temp,0b00000011 ;
out DDRD,temp ;
;
ldi temp,0b00111001 ;
out PORTB,temp ;
ldi temp,0b01111100 ;
out PORTD,temp ;
; * Инициализация таймеров
; ...
; * инициализация переменных
; ... занимает > 70 мкс
; первая проверка
sbis ACSR,ACO
rjmp label_ok
ldi temp,0x0C
rcall outchar
ldi temp,0b00101001
out PORTB,temp
l_loop:
; проверяем состояние компаратора
sbic ACSR,ACO
rjmp l_loop
label_ok:
; ...
; >1000 строк кода
; прерывание от компаратора
comp_isr:
ldi temp,0b00111001
out PORTB,temp
ldi temp,0b01111100
out PORTD,temp
; неинтересный код, выполняющийся как минимум 20 мс
; ...
ldi temp,0x0E
rcall outchar
ldi temp,0b00011001
out PORTB,temp
comp_isr_loop1:
; проверяем состояние компаратора
sbic ACSR,ACO
rjmp comp_isr_loop1
rjmp reset ; идем на инициализацию при включении
После обработки прерывания МК уходит на reset: независимо от состояния AIN1
причем код после reset:
l_loop:
; проверяем состояние компаратора
sbic ACSR,ACO
rjmp l_loop
выполняется верно
Выключение и включение компаратора в ISR не помогает