您的位置:首页 > 其它

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

2014-10-03 11:24 267 查看
一直对红外遥控很好奇,这次总算测试通过了。再看完红外遥控的原理后,我大概想了一下该如何实现解码,在参考了网上一些资料后,我发现原来有些想法是过于严苛的,实际解码是很简单的事情,只要适当采样就可以正确解码了。在本程序中,将忽略不同遥控器的干扰,不考虑其他协议的遥控器,红外遥控使用最广泛的协议时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 3
4 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/
******************************************************************************************************************
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: