基于单片机控制红外通信.docx
《基于单片机控制红外通信.docx》由会员分享,可在线阅读,更多相关《基于单片机控制红外通信.docx(9页珍藏版)》请在冰点文库上搜索。
![基于单片机控制红外通信.docx](https://file1.bingdoc.com/fileroot1/2023-5/19/5c44679c-a470-47e3-b491-bae2b00b9a82/5c44679c-a470-47e3-b491-bae2b00b9a821.gif)
基于单片机控制红外通信
ThismodelpaperwasrevisedbyLINDAonDecember15,2012.
基于单片机控制红外通信
红外通信原理
红外遥控有发送和接收两个组成部分。
发送端采用单片机将待发送的二进制信号编码调制为一系列的脉冲串信号,通过红外发射管发射红外信号。
红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。
为了减少干扰,采用的是价格便宜性能可靠的一体化红外接收头(HS0038,它接收红外信号频率为38kHz,周期约26μs)接收红外信号,它同时对信号进行放大、检波、整形得到TTL电平的编码信号,再送给单片机,经单片机解码并执行去控制相关对象。
具体实现过程如下:
(在这里特别强调:
编码与解码是一对逆过程,不仅在原理上是一对逆过程,在码的发收过程也是互反的,即以前发射端原始信号是高电平,那接收头输出的就是低电平,反之亦然。
因此为了保证解码过程简单方便,在编码时应该直接换算成其反码。
)
1.红外发射部分:
下图为红外发射部分的电路拟图:
编码过程:
(1)二进制信号的调制
二进制信号的调制由单片机来完成,它把编码后的二进制信号调制成频率为38kHz的间断脉冲串(用定时器来完成),相当于用二进制信号的编码乘以频率为38kHz的脉冲信号得到的间断脉冲串,即是调制后用于红外发射二极管发送的信号。
(2)PPM编码
这种遥控编码具有以下特征:
遥控编码脉冲由前导码、16位地址码(8位地址码、8位地址码的反码)和16位操作码(8位操作码、8位操作码的反码)组成。
前导码:
是一个遥控码的起始部分,由一个9ms的高电平(起始码)和一个4.5ms的低电平(结果码)组成,作为接受数据的准备脉冲。
16位地址码:
能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。
16位操作码:
用来执行不同的操作。
采用脉宽调制的串行码,以脉宽为、间隔、周期为的组合表示二进制的“0”;以脉宽为、间隔、周期为的组合表示二进制的“1”。
(3)发送程序
#include<>
staticbitOP;
外接收部分:
红外接收完成对红外信号的接收、放大、检波、整形,并解调出遥控编码脉冲。
为了减少干扰,采用的是价格便宜性能可靠的一体化红外接收头(HS0038,它接收红外信号频率为38kHz,周期约26us)接收红外信号,它同时对信号进行放大、检波、整形得到TTL电平的编码信号,再送给单片机,经单片机解码并执行去控制相关对象。
接收部分的电路拟图为:
HS0038的典型应用电路为:
其应用程序为:
#include""
#defineucharunsignedchar
#defineuintunsignedint
#include""
#defineucharunsignedchar
#defineuintunsignedint
ucharram[4]={0,0,0,0};//存放接受到的4个数据地址码16位+按键码8位+按键码取反的8位
voiddelaytime(uinttime)//延迟90uS
{uchara,b;
for(a=time;a>0;a--)
{for(b=40;b>0;b--);}
}
voidrem()interrupt0//中断函数
{
ucharramc=0;//定义接收了4个字节的变量
ucharcount=0;//定义现在接收第几位变量
uinti=0;//此处变量用来在下面配合连续监测9MS内是否有高电平
prem=1;
for(i=0;i<1100;i++)//以下FOR语句执行时间为8MS左右
{
if(prem)//进入遥控接收程序首先进入引导码的前半部判断,即:
是否有9MS左右的低电平
return;//引导码错误则退出,注意与break语句的区别
}
while(prem!
=1);//等待引导码的后半部MS高电平开始的到来。
delaytime(50);//延时大于时间,跨过引导码的后半部分,来到真正遥控数据32位中
//第一位数据的开始脉冲
for(ramc=0;ramc<4;ramc++)//循环4次接收4个字节
{for(count=0;count<8;count++)//循环8次接收8位(一个字节)
{
while(prem!
=1);//开始判断现在接收到的数据是0或者1,首先在这行本句话时,
//保已经进入数据的低电平阶段
//等待本次接受数据的高电平的到来。
delaytime(9);//高电平到来后,数据0高电平最多延续,而数据1,高电平可延续大于后我们可以再判断遥控接收脚的电平。
if(prem)//如果这时高电平仍然在继续那么接收到的数据是1的编码
{ram[ramc]=(ram[ramc]<<1)+1;//将目前接收到的数据位1放到对应的字节中
delaytime(11);//如果本次接受到的数据是1,那么要继续延迟1MS,这样才能跨
//下个位编码的低电平中(即是开始的中)
}
else//否则目前接收到的是数据0的编码
ram[ramc]=ram[ramc]<<1;//将目前接收到的数据位0放到对应的字节中
}//本次接收结束,进行下次位接收,此接收动作进行32次,正好完成4个字节的接收
}
if(ram[2]!
=(~(ram[3]&0x7f)))//本次接收码的判断
{for(i=0;i<4;i++)//没有此对应关系则表明接收失败,清除接受到的数据
ram[i]=0;
returned;}
main()
{
IT0=1;//设定INT0为边沿触发
EX0=1;//打开外部中断0
EA=1;//全局中断开关打开
while
(1)
{
switch(dis_num)
{
case0x81:
num=0;break;
case0xcf:
num=1;break;
case0x92:
num=2;break;
case0x86:
num=3;break;
case0xcc:
num=4;break;
case0xa4:
num=5;break;
case0xa0:
num=6;break;
case0x8f:
num=7;break;
case0x80:
num=8;break;
case0x84:
num=9;break;
case0x88:
num=10;break;
case0xe0:
num=11;break;
case0xb1:
num=12;break;
case0xc2:
num=13;break;
case0xb0:
num=14;break;
case0xb8:
num=15;break;
}
P2=table[num];
P1=0x01;
delaytime(5);
}
}