资讯详情

51红外解码调试笔记

转自:http://blog.sina.com.cn/s/blog_6b86b0f20101iq0q.html

前阵子帮他们做实习小车的买东西,看着便宜就顺便买了个红外的遥控器和1838的红外接收头子。这两天闲着没事,看了很多资料才终于完成了红外解码,的确是久了没玩51,好多东西生疏了导致调试过程几经挫折,经过这次复习了好多51的东西,受益匪浅。

查阅资料得知常见红外编码为PPM制式。红外发射端以脉宽0.565ms、间隔0.56ms的脉冲信号表示二进制“0”,以脉宽0.565ms,间隔1.65ms的脉冲信号为“1”。如下图. 上述“0”、“1”组成的32位二进制码经过38KHz的载波进行二次调制以提高发射效率、降低电源功耗。 32位二进制码组中,前16位为用户识别码,能区别不同电气设备防止不同机种遥控码相互干扰。后16位为8位操作码极其反码。遥控器在按下后周期性的发出一种32位二进制码,周期108ms。这108ms由一个起始码(9ms),一个结果码(4.5ms),低8位地址码、高8位地址码、8位数据码极其8位数据反码组成。 接受时使用1838通用红外 红外接头将38K载波信号过滤掉,得到与发射代码反向接受码。 上述是我自己整理的资料。后经 验证大致是这样的,便开始编写程序。

红外解码的关键就是识别“0”和“1”。以下是具体代码,通过51单片机接受红外信号,解码后将8位操作码通过串口以十六进制发送给电脑(比较粗糙,还没来得及完善,仅供参考)

#include//单片机型号 C89C52 #define uchar unsigned char #define uint unsigned int sbit =P3^2;//位定义,使用P3^2口外部中断0 uint lowtime,hightime; uchar a[4],m,flag; bit decode();//解码程序 void sci();//串口初始化 void main() { // delay_ms(100); TR0=0; TH0=0; TL0=0; sci(); EA=1; IT0=1;//设置外部中断0为下降沿触发方式 EX0=1;//开外部中断0 while(1) { if(flag==1) //验证前导码正确后才开始解码并向串口发送数据 { decode(); for(m=0;m<1;m++)//向串口发射a[2],及8位操作码 { SBUF=a[2]; while(! ); TI=0; } while(1); } } } void ext0() interrupt 0 { EX0=0;//进外部中断0后立即关闭中断0,防止二次中断 TR0=1;//开定时器0 while(IR==0);//一直计数,直到IR由0跳变到1 TR0=0;//关闭定时器0 lowtime=256*TH0+TL0;//lowtime储存引导码低电平持续时间 TH0=0; TL0=0;//清空定时器0寄存器值,以备下一次计数 TR0=1; while(IR==1);//等待IR由1跳表到0 TR0=0;//关闭定时器0 hightime=256*TH0+TL0;//hightime存储结果码高电平持续时间 if((lowtime>7800)&&(lowtime<8800)&&(hightime>3600)&&(hightime<4700)) //9000us/1.085=8294,判断区间8800-7800 //4500us/1.085=4100,判断区间3600-4700 //此值为11.0592MHz晶振时的值。 flag=1;//符合判断条件则将flag标志置1,否则认为是干扰信号不予解码 } bit decode() { uchar temp; uchar i,j; for(i=0;i<4;i++) { for(j=0;j<7;j++) { temp>>=1; TH0=0; TL0=0; TR0=1; while(IR==0); TR0=0; lowtime=256*TH0+TL0; TH0=0; TL0=0; TR0=1; while(IR==1); TR0=0; hightime=256*TH0+TL0; if((lowtime<370)||(lowtime>640))//低电平时间长度不合理 return 0; if((hightime>420)&&(hightime<620))//高电平持续时间560us左右即位“0” temp&=0x7f; if((hightime>1300)&&(hightime<1800))//高电平持续时间1680us左右即位“1” temp|=0x80; } a[i]=temp; } } void sci() { SM0=0; SM1=1; REN=1; TMOD=0x21;//此处注意设置定时器0的方式为工作方式1 TH1=0xfd; =0xfd; TR1=1; ES=1; } 串口显示出的十六进制的编码(每次单片机断电的时候都会向电脑发送00,不知道为什么...) 这只是初步的程序,调试过程中状况百出。显示串口显示问题,SBUFS是8位寄存器,只能存储8位二进制数据,故32位二进制需要发送四次,每次到串口为1位十六进制数据。还有定时器0的模式,之前一直没有设置,结果郁闷了一晚上。 另外,关于红外的用途的话,有人说这东西接受距离不远,也就几米(有资料说在输出段并上1uf 可将接收距离增加至十多米,待验证),最致命的是它是红外线,必须要将发射端对准接收端才能接收到信号,这就是它比不上蓝牙、NRF24L01等无线通信最主要的原因。不过,NRF24L01之麻烦,以我的智商估计没有半个月是做不出来的。 -电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台