Тоже столкнулась с необходимостью использования ИК-пульта.
Купила набор: маленький пульт с пленочными кнопками и плату с ИК-приемником.
Стала бороться с граблями.
Баском поддерживает альтернативный, фоновый режим - то, что нужно!
Однако для этого приемник следует подключать к выводу запуска таймера ICP.
В моем случае это был PORTB.0.
Все ок, но не понравилось то, что не работало повторение. Пульт при удержании кнопок продолжает посылать команды, но штатными средствами принимается только первая.
К тому же оказалось, что нет никакого прерывания, и я должна отслеживать состояние битов внутренней переменной в цикле. Решение так себе, критичное к задержкам в цикле (если выполняется еще какая-то работа), и глючное: иногда принималось по одной команде, иногда по две...
Как обычно, пришлось разбираться.
На ту же ногу, куда подключен ИК-приемник, назначила прерывание PCINT.
В обработчике ставится флаг плюс происходит еще некоторое шаманство с дополнительным флагом. Для контроля приема в примере задействована штатная лампочка Arduino Nano на порту PORTB.5.
Что имеем в итоге:
При однократном нажатии кнопки ловим АДРЕС1 + КОМАНДА, при удержании начинаются посылки АДРЕС2 + КОМАНДА.
Это выводится в тестовом примере в UART.
Пример:
0x0723 - адрес однократного нажатия 0x07, команда 0x23
0x0D23 - адрес повторных посылок 0xD0, команда та же, 0x23
0x0D23 - " - и так далее, пока кнопка не будет отпущена.
Пульт также посылал для каждой кнопки одинаковые посылки 0x1F / 0x2A, которые в примере отсеиваются.
Никакой корреляции битов АДРЕС1 и АДРЕС2 я не обнаружила, такое впечатление, что все они от балды (парочка даже одинаковые). Так что если в программе хотим раздельно обрабатывать однократное и повторное нажатие, придется держать два адреса. Правда, некоторые кнопки имеют одинаковый адрес нажатия и повтора - их между собой отличить не получится. Также не исключено, что у кнопок будет совпадать КОМАНДА (но будут разные адреса).
Код примера:
$regfile = "m328pdef.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 128
config RC5 = PinB.0 , timer = 1 , prescaler = 64 , mode = background ' (D12)
config PORTB.5 = output
dim a as byte, c as byte, flag_rc5_recieved as bit, flag_rc5_toggle as bit
'В ATmega328 есть три группы прерываний PCINT, управление которыми осуществляется регистром PCICR:
'7 6 5 4 3 2 1 0
'- - - - - PCIE2 PCIE1 PCIE0
' PCMSK0 отвечает за PORTB, PCMSK1 - PORTC, PCMSK2 - PORTD.
'От какой группы выводов поступило прерывание, показывает регистр PCIFR:
'7 6 5 4 3 2 1 0
'- - - - - PCIF2 PCIF1 PCIF0
'Прерывание вызывает любое изменение на выводе. Выводы включаются через регистры-маски PCMSK2, PCMSK1, PCMSK0.
'Регистр PCMSK2:
'7 6 5 4 3 2 1 0
'PCINT23 PCINT22 PCINT21 PCINT20 PCINT19 PCINT18 PCINT17 PCINT16
'Регистр PCMSK1:
'7 6 5 4 3 2 1 0
'- PCINT14 PCINT13 PCINT12 PCINT11 PCINT10 PCINT9 PCINT8
'Регистр PCMSK0:
'7 6 5 4 3 2 1 0
'PCINT7 PCINT6 PCINT5 PCINT4 PCINT3 PCINT2 PCINT1 PCINT0
pcmsk0 = &b000_0001 ' маска разрешает прерывание от PORTB.0, на которую подключен RC5
set pcicr.pcie0 ' включим группу 0 прерываний (порт B)
on PCINT0 int_rc5 save
enable PCINT0 ' разрешим прерывания от группы 0
enable interrupts
do
if flag_rc5_recieved = 1 then
_rc5_bits.4 = 0
a = RC5_address
c = RC5_command
if _rc5_bits.2 = 0 and a <> 0x1F and c <> 0x2A then
print "0x"; hex(a); hex(c)
end if
flag_rc5_recieved = 0
end if
loop
end
int_rc5:
toggle PORTB.5
toggle flag_rc5_toggle
if flag_rc5_recieved = 0 then
if flag_rc5_toggle = 1 then
set flag_rc5_recieved
end if
end if
return
P.S. Собственно, зачем в обработчике шаманство в виде toggle flag_rc5_toggle? Дело в том, что прерывания PCINT срабатывают на любое изменение сигнала на ножке, и это никак не регулируется (PCINT и значит Pin Change INTerrupt). Поэтому мы будем ловить прерывание дважды, и по фронту, и по спаду имульса. Переключение бита позволяет нам отсеять лишние срабатывания. В принципе, с той же целью мы могли бы просто проверять ножку на уровень: =0 или =1.

Ничего не менял, просто скопировал и нажал кнопочку "Компилировать". Bascom 2.0.8.1




Завтра продолжу поиск.