红外遥控对单片机的控制(测试成功)

来源:互联网 发布:cacti 162端口 编辑:程序博客网 时间:2024/04/26 13:31

一直对红外遥控很好奇,这次总算测试通过了。再看完红外遥控的原理后,我大概想了一下该如何实现解码,在参考了网上一些资料后,我发现原来有些想法是过于严苛的,实际解码是很简单的事情,只要适当采样就可以正确解码了。在本程序中,将忽略不同遥控器的干扰,不考虑其他协议的遥控器,红外遥控使用最广泛的协议时NEC协议,这次只是就如何实现NEC协议的遥控器实现解码。我相信只要会了NEC解码,其他协议也就不是问题,只要改动采样时间就好了。

本遥控器型号:KM-001,采用的是NEC协议。

实现功能:按住不同的遥控数字键,在开发板的数码管上显示按住的数字。

一、红外遥控原理

1>红外遥控的发送和接收

将要发送的二进制码调制到38KHZ的载波上通过红外线发送出去,对于为什么要使用载波,这是因为信号源不能传输的很远,而载波能远距离传送,所以要使用载波。原理图示:

                                    

左边是经过调制的编码经过发射器发送出去,右边是红外接收头通过解调,将发送过来的二进制码解调出来后的波形。这就是发送和接收的大概思路了。

***********************************************************************************************************************

详情请咨询:                                                 http://shop108408772.taobao.com/

******************************************************************************************************************

2>NEC协议

发送桢格式如下:

一个完整的全码=引导码+用户码+用户反码+数据码+数据反码。

                       

                             13.5ms引导码                 1字节                 1字节                  1字节                     1字节

在对引导码进行识别后,程序需要将后面的4字节解码出来。NEC协议中规定的0和1波形如下:

(图形来自changing)

发送端未调制之前波形:

                                          

接收端调制出来后波形:


注意我们需要解码的是接收端调制出来后波形,而这跟发送端之前的波形是反向的。

3>控制器按键与控制码对应图


(这个图全部数字键经过测试是正确的)

***********************************************************************************************************************

详情请咨询:                                                 http://shop108408772.taobao.com/

******************************************************************************************************************

二、解码程序

因为引导码在接收端是9ms的低电平在加上4.5ms的高电平,而单片机各引脚在初始状态时为高电平。所以使用中断方式下触发方式采用跳变沿触发。

#include <reg51.h>
sbit IRPORT = P3^2;
unsigned char ircode[4];
// 此表为 LED 的字模(共阴极)      0 1     2     3     4     5     6     7    8     9  a     b     c    d     e      f
unsigned char code LED7Code[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char key[10]={0x16,0x0C,0x18,0x5E,0x08,0x1C,0x5A,0x42,0x52,0x4A};
//                0   1 2 34 5 6 7 8 9
void delayms1()//延时1ms
{unsigned int i=100;
while((i--)!=1);
}
void delayus842()//延时842us
{unsigned int i=105;
while(--i);
}
void inter() interrupt 0 //中断服务子程序
{unsigned char i,j;
unsigned char temp;
EX0=0;//中断关闭,防止后续在同一个桢的跳变沿干扰中断
delayms1(); //延时2ms
delayms1();
while(IRPORT!=0)
{EX0=1;//中断打开
return;
}
while(IRPORT==0);
while(IRPORT==1);//跳过引导4.5ms
for(i=0;i<=3;i++)
{temp=0;
    for(j=0;j<=7;j++)
{
while(IRPORT==0);
temp=temp>>1;
delayus842();//延时842us判断是0还是1?
if(IRPORT==1)
{delayms1();
temp=temp|0x80;//先接受低位数据
}
}
ircode[i]=temp;
}
EX0=1;//中断打开
}

***********************************************************************************************************************

详情请咨询:                                                 http://shop108408772.taobao.com/

******************************************************************************************************************

void main()
{
unsigned char i,temp=0xFF;
EA=1; //中断总开关
EX0=1; //外部中断打开
IT0=1; //负跳变促发方式
do
{
if(ircode[2]=~ircode[3])//判断接收到的控制码是否正确
{
   for(i=0;i<=9;i++)
   {if(ircode[2]==key[i])
temp=i;
   }
P2=(temp<<2)&0x1c;//使用LED动态显示,LED数码的片选控制,使用了38译码器
P1=(LED7Code[temp])&0x7f; //LED数据送入,使用了锁存器
 //将数据送往LED显示
 for(i=0;i<=100;i++);//短暂延时
}
}while(1);
}

三、测试结果


***********************************************************************************************************************

详情请咨询:                                                 http://shop108408772.taobao.com/

******************************************************************************************************************


0 0
原创粉丝点击