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();
}
}
}