Вот бывает так, что мозги отказываются работать и всё тут. Приспичило тут сделать некое устройство, которое подсчитывает импульсы от внешних устройств.
Так как МК в основном спит, то прицепил эти устройства на прерывания PCINT1, в частности 1-й счётчик на PCINT8 (PB0), а второй на PCINT10 (PB1).
Всё хорошо срабатывает, но тупо уткнулся на распознавание фронта и спада импульсов, ведь прерывания происходят и по фронту и по спаду.
Бьюсь второй день, короче упёрся в тупик.
Вот часть кода:
$regfile = "m644Pdef.dat"
$crystal = 1843200
$baud = 9600
$hwstack = 16
$swstack = 32
$framesize = 64
CONFIG SUBMODE = NEW
'------------------------------------- Главный цикл ------------------------------------------------
Main:
'------------- Процедура обработки прерываний от счётчиков ------------------
If CNT_int = 1 Then
CNT_int = 0
If StatusCNT1 = 1 Then
Incr CNT1
Call Led(1 , 1 , 50) 'Моргнём светодиодом
End If
If StatusCNT2 = 1 Then
Incr CNT2
Call Led(2 , 1 , 50) 'Моргнём светодиодом
End If
GoTo Main
End If
'---------------------------------------------------------- Спим дальше -----------------------------------
CONFIG POWERMODE = IDLE
GoTo Main
End
'---------------------------------------------------------- Прерывания -------------------------------------
'Прерывание от счётчиков
CNT:
$asm
push R24 'Сохраним регист R24
in R24,sreg 'Сохраним регистр SREG
push R24 'Сохраним регистры R24,R25,R26
push R25
push R26
push R27
'Читаем порт B
in R25,pinB
'Загрузим значение статусов
lds R26,{StatusCNT1}
lds R27,{StatusCNT2}
'Начали проверку первого входа
andi R25,1 'Проверяем первый вход маской на порт 001
cpi R25,1 'Если в регистре 1
brEq A1 'Идём на обработку
sbrC R26,1 'Если бит в статусе =0 то пропустим следующую команду
rjmp A2 'Уходим на продолжение
LDI R26,0 'Загрузим в статус 0
sts {StatusCNT1},R26
rjmp A2 'Идём дальше
A1:
cpi R26,1 'Проверяем что там 1
breq A2 'Да, 1, уходим на проверку второго входа
ldi R26,1 'Загрузим в статус 1
sts {StatusCNT1},R26
'Начали проверку второго входа
A2:
andi R25,4 'Проверяем первый вход маской на порт 100
cpi R25,1 'Если в регистре 1
brEq A3 'Идём на обработку
sbrC R27,1 'Если бит в статусе =0 то пропустим следующую команду
rjmp A4 'Уходим на продолжение
LDI R27,0 'Загрузим в статус 0
sts {StatusCNT1},R27
rjmp A4 'Идём дальше
A3:
cpi R27,1 'Проверяем что там 1
breq A4 'Да, 1, уходим на проверку второго входа
ldi R27,1 'Загрузим в статус 1
sts {StatusCNT2},R27
A4:
'Покажем, что было прерывание от счётчиков, установим флаг прерывания
ldi R25 , 1
sts {CNT_int} , R25
'Восстановим все регистры
pop R27
pop R26
pop R25
pop R24
out sreg , R24
pop R24
$end asm
Return
Короче полный абзац.