基于单片机模拟红外编码解码的设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
开放实验报告
课题名称基于单片机的红外解码器的设计学生姓名
系、年级专业信息工程系、11、12级电子信息工程指导教师江世明
2014年 5 月20日
基于单片机的红外解码器的设计
一.实验目的
1、了解红外编码原理,模拟红外发射信号;
2、用程序实现红外编码的解码;
二.实验内容
设计基于单片机的红外解码器,实现红外遥控信号智能解码,要求制作出实物,实现解码功能。
三.电路设计
1、红外编码原理
在实际应用中红外编码将二进制码调制到38MHz的载波频率上,通过在空中传播,由红外接收头接收之后,由内部的解调电路进行解调, 解调出来的就是我们发送的那些二进制码。红外编码方式根据日本NEC 协议编码。每次发送四个字节:用户码,用户反码,数据码,数据反码。数据 0和 1的区别通常体现在高低电平的时间长短上。一次按键首先发送9ms的低电平和4.5ms的高电平的引导码。
实际生活中,用遥控器发出的信号与上面的信号是相反的,经过红外线接收头解码以后就和上图一样了,值得大家注意的是发射模块的芯片不同,引导区的时间和数据都有所不同,但解决的方法都是一样的。
引导码后就是用户码。但是怎么来区分0和1呢?前面我们提到了PWM(脉宽调制)。根据脉冲的宽度来区别0和1.0.56ms低电平之后接0.56ms高电平为0,接1.12ms高电平为1.
2、红外解码方法
在实际生活中红外解码一般由红外接收头接收并解码。解码时先跳过9ms 高电平和4.5ms的低电平,然后跳过0.56ms的低电平,最后通过循环等待搞电平的结束并计时。通过判断高电平时间的长短来区分0(0.56ms)和1(1.12ms)。最后判断接收到的四个字节(用户码,用户反码,数据码,数据反码)中数据码和取反后的数据反码相不相等。
3、红外编解码电路
四、程序设计
见附录
五、系统仿真
仿真分析:
仿真照片如上图,当从4*4键盘按下K5时,单片机U1的数码管显示5,同时P3.0发送出如下图所示的脉冲。
上图包含了9ms高电平和4.5ms低电平的引导码和4字节(32位)的信息码,包括用户码(00000000),用户反码(11111111),数据码(00001001),数据反码(11110110)。
六、结论
通过本次试验用软件模拟了红外发送编码与接收解码的过程。基本上可以脱离硬件实现红外的发送与接收。但是本实验还是存在一些问题,发送信号没有用38Khz的载波频率载波和实际的发送信号应该与本实验相反。所以做实物时应该考虑这些问题。
附录:
发送程序:
#include
#define uchar unsigned char
#define uint unsigned int
uchar IR[4]; //全局变量存放发送数据
sbit IRIN=P3^4;// 发送脚
sbit BEEP = P3^0;// 蜂鸣器
void SendData();
void Delay(uint x);
void Delay_112();
void Delay_56();
void Delay_50();
void Key_scan();
void Beep();
uchar DM[] =
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1 ,0x86,0x8e,0xff};
void main()
{
uchar t=16;
IR[2]=16;
while(1)
{
Key_scan();
P0 = DM[IR[2]];
if(t!=IR[2]) //保证每次只发送一个数据缺点:每个键不能重复发送
{
t=IR[2]; //保护IR[2]的值
Beep();
SendData();
IR[2]=t; //还原IR[2]的值
}
Delay(100);
}
}
void SendData()
{
uchar k,i,t;
IR[1]=~IR[0]; //用户码取反
IR[3]=~IR[2]; //数据码取反
IRIN=0;
Delay(9); //假设9ms低电平发射
IRIN=1;
Delay(4); //4.5ms高电平
Delay_50();
for(k=0;k<4;k++)
for(i=0;i<8;i++)
{
IRIN=0;
Delay_56();
t=IR[k]; //保存IR[k]的值
if(IR[k]>>=7) //取最高位
{
IRIN=1;
Delay_112();
}
else
{
IRIN=1;
Delay_56();
}
t<<=1; //次高位变为最高位
IR[k]=t;
}
IRIN=0;//保证最后一个脉冲的高电平时间
Delay_56();
IRIN=1;
}
void Key_scan()
{
uchar i;
P1=0x0f;
if(P1!=0X0f)
{
Delay(2); //消抖
if(P1!=0x0f)
switch(P1)
{
case 0x0e: i=0;break;
case 0x0d: i=1;break;
case 0x0b: i=2;break;
case 0x07: i=3;
}
Delay(1);
P1=0xf0;
switch(P1)
{
case 0xe0: i+=0;break;
case 0xd0: i+=4;break;
case 0xb0: i+=8;break;
case 0x70: i+=12;
}