Наверное многие из любителей разработок на микроконтроллерах хоть пару раз но задумывались над возможностью управления устройством при помощи обычного ИК-пульта от телевизора. Особо подкупает то, что для подключения ИК-датчика TSOP4836 требуется всего навсего один свободный пин и два резистора! Когда-то и я пробовал такой вариант.


Распиновка TSOP4836
Я собрал простую схему на 18F2520 и разобрался как декодировать сигналы и написал код, при помощи которого получил сигнатуры для всех доступных мне на тот момент ИК-пультов.
Далее приведу исходники, при помощи которых можно получать 32-битные сигнатуры для разных кнопок пульта:
#include <18f2520.h>
#define FCONST OSC_8MHZ // эту частоту будем устанавливать программно (используя PLL)
#define FREQ 8000000 // используемая частота
#pragma config WDT = OFF
#pragma config LVP = OFF
#fuses INTRC_IO
#use delay (clock=FREQ)
#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3)
#define LED PIN_A0
INT1 Received=false;
long t;
int8 i;
// настройка прерывания на нужный фронт импульса
#define LH_Edge 0
#define HL_Edge 1
int8 edge; // показывает на какой фронт импульса мы настроили прерывание 0 - L_to_H, 1 - H_to_L
void setEdge(int1 e) {
edge=e;
if (e==LH_Edge) {
ext_int_edge(0, L_TO_H);
} else {
ext_int_edge(0, H_TO_L);
}
}
int32 t0,t1; // для сохранения длительности 0 и 1
int32 code; // расшифрованный код с пульта ДУ
int8 timerov; // количество переполнений таймера
int8 cnt=0xFF; // количество принятых импульсов (если FF то счет не идет, это знак сброса)
#define MIN_LEAD_IN 1000 // 4 ms
#define MAX_LEAD_IN 1500 // 6 ms
#define MIN_TIME 60 // 0.24 ms
#define MID_TIME 200 // 0.8 ms
#define MAX_TIME 800 // 3.2 ms
#int_EXT
EXT_isr() {
if (!received) { // если код уже считан, но не обработан основной программой - ничего не делаем
if (edge==HL_Edge) { // если словили 1->0
t1=(0x10000*timerov+get_timer0()); // запоминаем сколько длилась 1
} else { // если словили 0->1
t0=(0x10000*timerov+get_timer0()); // запоминаем сколько длился 0
if (cnt==0xFF) {
if ((t1>MIN_LEAD_IN)&&(t1<MAX_LEAD_IN)) { // словили сигнал начала передачи
cnt=0;
code=0;
}
} else {
// приняли очередную пару 0->1
if ((t1<MAX_TIME)&&(t1>MIN_TIME)&&(t0>MIN_TIME)&&(t0<MAX_TIME)) { // параметры сигнала в норме, анализируем
if ((t1<MID_TIME)&&(t0<MID_TIME)) { // это 0
} else { // это 1
bit_set(code,cnt);
}
cnt++;
} else { // параметры вышли за границу, делаем сброс
cnt=0xFF;
}
}
if (cnt==23) { // приняли все 23 бит
received=TRUE;
cnt=0xFF;
}
}
}
setEdge(!edge); // теперь будем ловить другой фронт импульса
timerov=0;
set_timer0(0);
}
#int_TIMER0
// происходит по переполнению 16 бит таймера
TIMER0_isr() {
if (timerov<255)
timerov++;
}
void main()
{
setup_oscillator(FCONST);
delay_ms(5000);
printf("initr");
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
setEdge(HL_Edge);
set_timer0(0);
delay_ms(10);
t=get_timer0();
printf("%Lu",t);
printf("00 tick/sec");
printf("gor");
DO
{
IF (received) {
disable_interrupts(GLOBAL);
printf("%lx ",code);
printf("r");
enable_interrupts(GLOBAL);
received=false;
}
}
WHILE (true);
}
Далее приведу таблицы ИК-кодов для исследованных мной пультов. Коды в таблице визуально располагаются в соответствии с расположением кнопок на пультах.
Таблица кодов пульта “TOSHIBA CT-90119”
![]() |
0016bf40 | 0012bf40 | |
| 0013bf40 | 0017bf40 | 0010bf40 | |
| 0001bf40 | 0002bf40 | 0003bf40 | |
| 0004bf40 | 0005bf40 | 0006bf40 | |
| 0007bf40 | 0008bf40 | 0009bf40 | |
| 000bbf40 | 0000bf40 | 0014bf40 | |
| 001bbf40 | |||
| 001ebf40 | 001abf40 | ||
| 001fbf40 | |||
| 005bbf40 | 0018bf40 | 001cbf40 | |
| 0053bf40 | 0054bf40 | 000dbf40 | |
| 0048bf40 | 0015bf40 | 004bbf40 | |
| 0049bf40 | 004abf40 |
Таблица кодов пульта “Twinhan-DVB”
![]() |
004dff00 | 0016ff00 | |
| 0003ff00 | 0001ff00 | 0006ff00 | |
| 0009ff00 | 001dff00 | 001fff00 | |
| 000dff00 | 0019ff00 | 001bff00 | |
| 0011ff00 | 0015ff00 | 0017ff00 | |
| 0040ff00 | 0005ff00 | 0012ff00 | |
| 000aff00 | 0014ff00 | 001eff00 | |
| 000eff00 | 0002ff00 | 001aff00 | |
| 004cff00 | 0010ff00 | 000cff00 | |
| 0054ff00 | 0048ff00 | 001cff00 | |
| 0004ff00 | 0000ff00 | 000fff00 |
Таблица кодов для пульта ORION-DVD
![]() |
0054bf40 | 005bbf40 | ||
| 0014bf40 | 0057bf40 | 0041bf40 | 0046bf40 | |
| 0009bf40 | 001dbf40 | 001fbf40 | 000dbf40 | |
| 0019bf40 | 001bbf40 | 0011bf40 | 0015bf40 | |
| 0017bf40 | 0012bf40 | 0059bf40 | 0008bf40 | |
| 0050bf40 | 0055bf40 | 0048bf40 | 004abf40 | |
| 005ebf40 | 0006bf40 | 0005bf40 | 0003bf40 | |
| 0047bf40 | 0007bf40 | 0040bf40 | 0002bf40 | |
| 0018bf40 | 0044bf40 | 000fbf40 | 0051bf40 | |
| 000abf40 | 001ebf40 | 000ebf40 | 001abf40 | |
| 0053bf40 | 0052bf40 | 0001bf40 | 0045bf40 |
Таблица кодов для ИК-пульта AVerMedia:
![]() |
0001fd02 | 0002fd02 | 0003fd02 | 0000fd02 |
| 0005fd02 | 0006fd02 | 0007fd02 | 0004fd02 | |
| 0009fd02 | 000afd02 | 000bfd02 | 0008fd02 | |
| 000dfd02 | 000efd02 | 000ffd02 | 000cfd02 | |
| 0011fd02 | 0012fd02 | 0013fd02 | 0010fd02 | |
| 0015fd02 | 0016fd02 | 0017fd02 | 0014fd02 | |
| 0019fd02 | 001afd02 | 001bfd02 | 0018fd02 | |
| 001dfd02 | 001efd02 | 001ffd02 | 001cfd02 | |
| 0001fc03 | 0002fc03 | 0003fc03 | 0000fc03 |




