Сейчас хочу создать центр управления аквариумом и появился такой вопрос.
Раньше мне хватало 3 кнопок с комбинациями короткого, длинного и одновременного нажатия.
Принцип простой - таймер на 100Гц в таймере обновляется структура состояния кнопки (для меня в норме 3 задетектированых нажатия и 2 задетиктированных отпускания или 50мс на короткое нажатие тогда засчитывается клик).
А уже в основном цикле атомарно читается эта структура и выполняется инструкция(или анализируется набор структур для одновременного нажатия). Если инструкция долгая, некоторые клики пропускаются, но я считаю, что так лучше иначе могут быть неприятные эффекты, когда пойдут клики из буфера. (особенно если было зависание и пользователь начал тыкать любые кнопки).
Обработка счётчиков и состояния довольно длинная - около 70 строк ассемблерного кода от avr-gcc:
Спойлер
Код: Выделить всё
update_btn:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
movw r30,r24
ldd r24,Z+3
cpi r24,lo8(0)
breq .L3
cpse r22,__zero_reg__
rjmp .L2
st Z,__zero_reg__
std Z+1,__zero_reg__
std Z+2,__zero_reg__
std Z+3,__zero_reg__
ret
.L3:
ld r24,Z
cpi r22,lo8(0)
breq .L6
cpi r24,lo8(-1)
breq .L7
ld r24,Z
subi r24,lo8(-(1))
st Z,r24
.L7:
ld r24,Z
cpi r24,lo8(40)
brlo .L8
ldi r24,lo8(2)
.L26:
std Z+2,r24
.L9:
ldd r24,Z+1
cpi r24,lo8(0)
breq .L2
ldd r24,Z+1
subi r24,lo8(-(-1))
std Z+1,r24
ret
.L8:
ld r24,Z
cpi r24,lo8(3)
brlo .L9
ldi r24,lo8(1)
rjmp .L26
.L6:
cpi r24,lo8(0)
breq .L11
ld r24,Z
subi r24,lo8(-(-1))
st Z,r24
.L11:
ldd r24,Z+2
cpi r24,lo8(0)
breq .L2
ldd r24,Z+1
subi r24,lo8(-(1))
std Z+1,r24
ldd r24,Z+1
cpi r24,lo8(2)
brlo .L2
ldd r24,Z+2
cpi r24,lo8(1)
breq .L13
cpi r24,lo8(2)
breq .L13
ret
.L13:
std Z+3,r24
.L2:
/* epilogue start */
ret
.size update_btn, .-update_btn
.global proc_btn
.type proc_btn, @functionДля трёх кнопок, это не было проблемой.
Но теперь, если у меня будет 16 кнопок, то в прерывании задержусь на 1600тактов, плюс, допустим, 400 тактов на всякую другую фигню.
В итоге получаю 2K тактов, это много или мало? Стоит ли того чтобы переписать отлаженную библиотеку и вынести больше обработки в основной цикл?
Допустим для atmega328 на 20MHz? Вроде должно получиться 100us.
Заранее благодарен!
P.S. Пока на другие прерывания ничего сильно ответственного вешать не планирую.
P.P.S. Если можно подскажите на сколько в норме можно занимать прерывание в тактах или в миллисекундах в условиях когда в других прерываниях нет ничего важного и в условиях когда что-то есть. Желательно с конкретными примерами - например если используется UART на скорости 19200, то не больше столько-то.