Использование TSOP4836 для считывания кодов с ИК-пульта на микроконтроллере PIC18F2520

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

схема подключения TSOP4836 к микроконтроллеру PIC18F2520

распиновка 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”

Пульт телевизора 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”

ИК-пульт 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

ИК-пульт 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:

ИК-пульт к плате видео-захвата 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

Оставьте комментарий

Ваш адрес email не будет опубликован.