基于STC89C52的红外遥控器编程.doc
文本预览下载声明
基于STC89C52的红外遥控器编程
硬件及原理
基于单片机的红外通信是遵循NEC协议的一种通信,本篇文章主要讲述如何遵循NEC协议设计一个简易的遥控器,在软件编程之前,先将我们的硬件设计介绍如下。
上图是一个红外发送电路,这个电路是整个遥控器的核心。我们所发送的0和1就是通过发射管TSAL6200来发送出去的。网络标号TXD接我们单片机的引脚P2^1,该引脚负责将我们所需发送的信号通过拉高或拉低实现。Ird38KHz接一个产生38KHz信号电路,38KHz信号是我们所需要的载波信号,我们的0和1(即基带信号)通过发射管将被调制成符合NEC协议下的调制信号。该38KHz信号产生电路设计如下图。
为了制作一个简易的遥控器,本文设计两个按键分别表示不同的两个按键1和2,
两个按键分别接我们单片机的引脚P1^1和P1^2。原理图如下:
下面就NEC协议做简单的分析。
NEC协议中规定,一次通信的起始是一个固定的引导码,紧接着是第一个8位的用户码,然后是第二个8位的用户码,紧跟着是我们编码后的8位的键值码,最后是键值码的反码。如下图所示:
现在的问题是,到底单片机引脚TXD(后文代码中定义成IR)所要发送的0和1(基带信号)经过发射管后怎么表示呢(即调制信号)?
好,NEC协议是这么规定的,引导码是以持续9000us时间的低电平加上持续4500us的高电平来表示的,注意,是低电平在先。而0和1呢?是这样的,持续560us的低电平加上持续560us的高电平表示0,持续560us的低电平加上持续1680us的高电平则表示1。
注意,引导码和用户码和键值码之间是没有时间间隙的,也就是说引导码过后即是用户码,再即是键值码。
深刻的理解上面的这几点后,便可以写代码实现我们制作的遥控器了。
软件设计
我的设计思想是将发送引导码封装成一个函数,将发送一个0,发送一个1分别封装成一个函数,即实现模块化。将这三个函数写出后,剩下要做的只是对键值进行编码了。而编码是可以任意的,什么意思呢?也就是说,我们可以任意使用,比如用0xff和0x00表示我们的用户码,用0x3d表示我们的1,用0xe3表示我们的2,或者其它,这是我们的自由。用户码是为了区别不一样的遥控器而设定的。
这里,时间的控制我们用定时器0实现。电路使用12M的晶振,机器周期刚好是1us。
好,下面先将三个基本函数编写如下。
/*******发送引导码函数**********/
void SendGuideCode()
{
TH0 = 0xDC; //9000us
TL0 = 0xD8;
TR0 = 1;
IR = 0; //拉低IR
while(!(TF0 == 1)); //等待定时器溢出,即使IR持续低电平9000us
IR = 1;
TF0 = 0;
TR0 = 0;
TH0 = 0xEE; //4500us
TL0 = 0x6c;
TR0 = 1;
while(!(TF0 == 1)); //等待定时器溢出,即使IR持续高电平4500us
IR = 0;
TF0 = 0;
TR0 = 0;
}
/*********发送0函数*********/
void SendCodeZero() /
{
TH0 = 0xFD; //560us
TL0 = 0xD0;
TR0 = 1;
IR = 0;
while(!(TF0 == 1));
IR = 1;
TF0 = 0;
TR0 = 0;
TH0 = 0xFD; //560us
TL0 = 0xD0;
TR0 = 1;
while(!(TF0 == 1));
IR = 0;
TF0 = 0;
TR0 = 0;
}
/*********发送1函数*********/
void SendCodeOne()
{
TH0 = 0xFD; //560us
TL0 = 0xD0;
TR0 = 1;
IR = 0;
while(!(TF0 == 1));
IR = 1;
TF0 = 0;
TR0 = 0;
TH0 = 0xF9; //1680us
TL0 = 0x70;
TR0 = 1;
while(!(TF0 == 1));
IR = 0;
TF0 = 0;
TR0 = 0;
}
完成了上面的三个基本函数,那我们就可以遵循NEC协议将每个8位一组的用户码,或者键值码进行封装了。话不多少,看代码。
/*********用户码函数*********/
void UsrCode() //发送用户码 11111
显示全部