docs

a slatepencil documentail site

View on GitHub

Infrared transmit & receiver

NEC Infrared Transmission Protocol

IR Transmit

/************************
AT89S51
Infrared Transmit
OSC 11.0592 MHz
*************************/

#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit k1 = P3 ^ 4;
sbit k2 = P3 ^ 5;
sbit k3 = P3 ^ 6;
sbit k4 = P3 ^ 7;
sbit out = P1 ^ 5;

const uchar TablHL1[12] = {0x30, 0x18, 0x7a, 0x10, 0x38, 0x5a, 0x42, 0x4a, 0x52, 0x00, 0xff, 0xa6}; // 1~9  + 2bit user code

void delay(uint xms)
{
    uint i, j;
    for (i = xms; i > 0; i--)
    {
        for (j = 112; j > 0; j--)
            ;
    }
}

void delay560us(void) // 0.56ms delay
{
    uint j;
    for (j = 63; j > 0; j--)
        ;
}

void delay4500us(void) // 4.5ms delay
{
    uint j;
    for (j = 516; j > 0; j--)
        ;
}

void khz_2(uint num) // 38kHz pulse ratio 1:2
{
    for (; num > 0; num--)
    {
        // _nop();
        out = ~out;
    }
}

void send0(void)
{
    khz_2(42);
    // khz_2(21);
    out = 1;
    delay560us();
}
void send1(void)
{
    khz_2(42);
    out = 1;
    delay560us();
    delay560us();
    delay560us();
}

void send8Bit(uchar dat)
{
    if (dat & 0x80)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x40)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x20)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x10)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x08)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x04)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x02)
    {
        send1();
    }
    else
    {
        send0();
    }

    if (dat & 0x01)
    {
        send1();
    }
    else
    {
        send0();
    }
}

void usercode() // send user code 00ff
{
    send8Bit(TablHL1[9]);
    send8Bit(TablHL1[10]);
}

void leadcode(void)
{
    khz_2(690);
    // khz_2(345);
    out = 1;
    delay4500us();
}

void send_1() // 0011 0000
{
    leadcode();
    usercode();
    send8Bit(TablHL1[0]);
    send8Bit(~TablHL1[0]);
}

void send_2() // 0001 1000
{
    leadcode();
    usercode();
    send8Bit(TablHL1[1]);
    send8Bit(~TablHL1[1]);
}

void send_3() // 0111 1010
{
    leadcode();
    usercode();
    send8Bit(TablHL1[2]);
    send8Bit(~TablHL1[2]);
}

void send_4() // 0001 0000
{
    leadcode();
    usercode();
    send8Bit(TablHL1[3]);
    send8Bit(~TablHL1[3]);
}

void keyscan()
{
    while (1)
    {
        if (k1 == 0)
        {
            delay(10);
            if (k1 == 0)
            {
                while (k1 == 0)
                    ;
                send_1();
            }
        }

        if (k2 == 0)
        {
            delay(10);
            if (k2 == 0)
            {
                while (k2 == 0)
                    ;
                send_2();
            }
        }

        if (k3 == 0)
        {
            delay(10);
            if (k3 == 0)
            {
                while (k3 == 0)
                    ;
                send_3();
            }
        }

        if (k4 == 0)
        {
            delay(10);
            if (k4 == 0)
            {
                while (k4 == 0)
                    ;
                send_4();
            }
        }
    }
}

void main(void)
{
    while (1)
    {
        keyscan();
    }
}

IR Receive

/************************
AT89S51
Infrared Receiver
OSC 11.0592 MHz
*************************/

#include <reg52.h>

sbit IR = P3 ^ 2;

#define DataPort P0

sbit wei1 = P2 ^ 4;
sbit wei2 = P2 ^ 5;
sbit wei3 = P2 ^ 6;
sbit wei4 = P2 ^ 7;

const unsigned char code DuanMa[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 0 ~ 9

unsigned char irtime; // IR global variable

bit irpro_ok, irok;
unsigned char Ircord[4];
unsigned char irdata[33];

void Ir_work(void);
void Ircordpro(void);

// Timer T0 interrupt process
void tim0_isr(void) interrupt 1 using 1
{
    irtime++;
}

// external 0 interrupt process
void EX0_ISR(void) interrupt 0
{
    static unsigned char i;
    static bit startflag;
    if (startflag)
    {
        if (irtime < 63 & &irtime >= 33) // leadcode TC9012 header, 9ms + 4.5ms
            i = 0;
        irdata[i] = irtime; // 存储每个电平的持续时间,用于以后判断是0,还是1
        irtime = 0;
        i++;
        if (i == 33)
        {
            irok = 1;
            i = 0;
        }
    }
    else
    {
        irtime = 0;
        startflag = 1;
    }
}

// timer T0 init
void TIM0init(void)
{
    TMOD = 0x02; // set T0 mode as 2
    TH0 = 0x00;  // 重载值
    TL0 = 0x00;  // init value
    ET0 = 1;     // open interrupt
    TR0 = 1;
}

void EX0init(void)
{
    IT0 = 1;
    EX0 = 1;
    EA = 1;
}

void Ir_work(void)
{
    switch (IRcord[2])
    {
    case 0x0c:
        DataPort = DuanMa[1];
        break;
    case 0x18:
        DataPort = DuanMa[2];
        break;
    case 0x5e:
        DataPort = DuanMa[3];
        break;
    case 0x08:
        DataPort = DuanMa[4];
        break;
    case 0x1c:
        DataPort = DuanMa[5];
        break;
    case 0x5a:
        DataPort = DuanMa[6];
        break;
    case 0x42:
        DataPort = DuanMa[7];
        break;
    case 0x52:
        DataPort = DuanMa[8];
        break;
    case 0x4a:
        DataPort = DuanMa[9];
        break;
    default:
        break;
    }
    irpro_ok = 0;
}

void Ircordpro(void)
{
    unsigned char i, j, k;
    unsigned char cord, value;

    k = 1;
    for (i = 0; i < 4; i++) // process 4 bit
    {
        for (j = 1; j <= 8; j++) // process 1bit 8 digit
        {
            cord = irdata[k];
            if (cord > 7) // 大于某值为1,这个和晶振有绝对关系,这里使用12MHz计算,有一定误差
                value |= 0x80;
            if (j < 8)
            {
                value >>= 1;
            }
            k++;
        }
        IRcord[i] = value;
        value = 0;
    }
    irpro_ok = 1; // 处理完毕标志位置1
}
void main(void)
{
    EX0init();  // 初始化外部中断
    TIM0init(); // 初始化定时器

    wei1 = 1;
    wei2 = 1;
    wei3 = 1;
    wei4 = 1;

    while (1)
    {
        if (irok)
        {
            Ircordpro();
            irok = 0;
        }
        if (irpro_ok)
        {
            Ir_work();
        }
    }
}