关于红外捕获与发射,也就是红外学习等文章网上很多地方都有,原理基本一致:获取红外高低电平时间值,然后根据这些高低电平的时间值控制38KHZ的导通时间来还原波形。下面我说一下我自己的见解吧。
第一部分:捕获
1.捕获的实现比较简单。将红外接收头的数据输出脚接至单片机的外部中断0或1脚,当它接收到红外脉冲时,就会产生低电平,没有时就是高电平。可以在外部中断0或1的中断函数中实现脉冲高低时间的捕获。
unsigned int Get_Low_Time()
{
TH0 = 0;
TL0 = 0;
TR0 = 1;
while(!IRIN && (TH0&0x80)==0);
TR0 = 0;
return (TH0*256+TL0);
}
unsigned int Get_High_Time()
{
TH0 = 0;
TL0 = 0;
TR0 = 1;
while(IRIN && (TH0&0x80)==0);
TR0 = 0;
return (TH0*256+TL0);
}
void exint0() interrupt 0
{
unsigned int tmp;
IRInFlag = 1;
tmp = Get_Low_Time(); //先接收引导码低电平
IrPlusTime[IrPlusNum] = tmp;
IrPlusNum++; //红外脉冲计数
tmp = Get_High_Time();
IrPlusTime[IrPlusNum] = tmp;
IrPlusNum++;
}
这样就获取到了时间值,保存在IrPlusTime数组中。
有人就会问这个数据中的时间值是什么意思?
比如我的数组中第一个值为0x3646,这是第一个低电平的时间,它一定是跟引导码的时间有关。对的,0x3646=13894,我的晶振是18.432MHZ,定时器0用的是12T计时。所以一个机器周期就是:12/18.432≈0.651us,13894*0.651=9045us,这刚好就是NEC引导码的接收后的低电平时间。所以,具体数值跟你的晶振,单片机速度,也即是机器周期有关。
第二部分:还原发射
1.38KHZ载波产生,此处用的是定时器2,自动重装,每隔13us翻转IO。此处计时有0.16%的误差。建议能精确的尽量精确,而且占空比在1:3或1:4。
void Timer2_isr() interrupt 5 using 1
{
TF2 = 0;
OUT38K = ~OUT38K;
}
2.发射
从数组中逐个按时间控制38KHZ的通断。
TR2 = ET2 = Flag;//Flag初始值为0 TR2,ET2控制定时器2的运行和中断运行。
for(i=0;i<len;i++)//len存储时间的数组长度
{
Flag = ~Flag;
TH0 = 0;
TL0 = 0;
TR0 = 1;
while( (TH0*256+TL0) < IrPlusTime[i] );//IrPlusTime[0]保存的是数组长度
TR2 = ET2 = Flag;
}
这样就可以将数组时间发射出去了,能否还原还需要示波器抓一下与之前的对比下。