Появилась задача немного ускорить обработку прерывания. Естественно переходим на ассемблер.
Прерывание PCINT0, обработка не сложная, нужно ловить и фронт и спад.
На BASCOM это выглядит так (приведу адреса куда компилятор расположил переменные):
k = PINB.6 'Адрес К - 013A
If k = 0 Then 'Сигнал через транзисторный ключ, поэтому инверсный
Flag_On = 1 'Адрес - 0140
Flag_Full = 1 'Адрес - 013F
Flag_Off = 1 'Адрес - 013Е
Else
Flag_On = 0
End If
Компилируем и смотрим что же нам предложил BASCOM. Не стал переписывать, а приведу скриншот.
Еще и куча PUSH и POP. NoSave в данном случае не канает.
Нда, разработчик явно был под мухой, когда это писал. Ладно, сделаем по своему.
$Asm
push R24
in R24,sreg
push R24
'Начало работы
in R24,pinB 'Читаем пины порта B
andi R24,&B01000000 'Маска на выводы PINB.6
'Проверка состояния вывода
cpi R24,0 'Проверяем состояние PINB.6. На нём сигнал инверсный, значит при включении 0
breq Yes 'Пин = 0, установим флаги
jmp No 'Нет, идём дальше
Yes:
LDI R24,1 'Установим флаги в 1
sts {Flag_On},R24
sts {Flag_Full},R24
sts {Flag_Off},R24
jmp Exit
No:
clr R24 'Установим флаг в 0
sts {Flag_On},R24
Exit:
'Восстановим регистры
pop R24
out sreg , R24
pop R24
$End Asm
Получилось чтение пина и проверка его состояния 5 операций вместо 13 в оригинале. 4 операции установки флагов вместо 6.
Само собой исчезли лишние PUSH и POP.
Смотрим прикуп:
BASCOM предложил решить задачу 88 операторами (включая PUSH и POP).
Я обошёлся всего 18-ю. Игра стоила свеч.
Вот как то так получилось.
Отредактировано sva-don (2024-04-17 12:58:44)