好文档 - 专业文书写作范文服务资料分享网站

基于STC89C52的红外遥控器编程

天下 分享 时间: 加入收藏 我要投稿 点赞

基于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() //发送用户码 11111111 00000000 { unsigned char i;

for(i=0;i<8;i++) { SendCodeOne(); } for(i=0;i<8;i++) { SendCodeZero(); } }

/*********键值1函数********/

void Key1() //0x3d 0011 1101 ~0x3d 1100 0010 { SendCodeZero();

SendCodeZero(); SendCodeOne(); SendCodeOne(); SendCodeOne(); SendCodeOne();

SendCodeZero(); SendCodeOne(); SendCodeOne(); SendCodeOne(); SendCodeZero();

SendCodeZero(); SendCodeZero(); SendCodeZero(); SendCodeOne(); SendCodeZero(); }

/*********键值2函数********/

void Key2() //0xe3 1110 0011 ~0xe3 0001 1100 { SendCodeOne();

SendCodeOne(); SendCodeOne();

SendCodeZero(); SendCodeZero(); SendCodeZero(); SendCodeOne(); SendCodeOne();

SendCodeZero(); SendCodeZero(); SendCodeZero(); SendCodeOne(); SendCodeOne(); SendCodeOne(); SendCodeZero(); SendCodeZero();

}

这样,红外发送相关的函数都完成了,剩下的就是按键扫描了。函数如下。 /*********按键扫描函数********/ unsigned char KeyScan() //返回值是按下按键的按键值,没按下返回100,即不发送 { unsigned char key = 100;

unsigned char keybuf [2]={ 1,1};

static unsigned char backup[2]= { 1,1};

keybuf [0]= key1; if(keybuf[0] != backup[0]) { delay(100); if(keybuf[0] == key1) {

if(backup[0] == 0)

key = 1; } } if(keybuf[1] != backup[1]) { delay(100); if(keybuf[1] == key2) {

if(backup[1] == 0)

key = 2; } } return key;

基于STC89C52的红外遥控器编程

基于STC89C52的红外遥控器编程硬件及原理基于单片机的红外通信是遵循NEC协议的一种通信,本篇文章主要讲述如何遵循NEC协议设计一个简易的遥控器,在软件编程之前,先将我们的硬件设计介绍如下。上图是一个红外发送电路,这个电路是整个遥控器的核心。我们所发送的0和1就是通过发射管TSAL6200来发送出去的。网络标号TXD接我
推荐度:
点击下载文档文档为doc格式
4u46g2pf2903ypj6btal
领取福利

微信扫码领取福利

微信扫码分享