完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
这篇文章是我学习红外模块的时候的一些心得和体会,并附带个人对于这块的理解,希望能够对大家有帮助。 首先一点的就是红外发射信号后,单片机上接受数据部分 这是常见的接收模块,负责接受发射出的调制波,还有整个遥控部分的示意图 这个就是调制后的波,我们可以看到,最开始有一个引导码,这个是由NEC协议决定的,然后是客户码,可以类比为钥匙,这个对孔后就可以开门了,最重要的就是操作码,这个就是要发送的信息,最后有一个操作反码,用于校验操作码是否正确。 接着就到了红外接收部分,先看一下流程: 引导码出现以后,进行一下延时判断(代码没有判断,因为比较简单), 然后,重点就来了 主要过程看下边信号的时间轴,发生事件后去看timer0的时间轴,很容易就能理解了 一开始的跳变沿产生一次中断,但这时候flag = 0,所以就进入timer0 = 0,flag = 1,注意!!!!这时候信号已经在传输了,timer0正在计时,当下一个跳变沿产生,也就是这一位信号传输完成时,又一次进入中断,这时候flag = 1,所以就进入到保存timer0的值,i++,然后把timer0重新置零,然后timer0 重新计时,传输下一位数据,再产生一次跳变沿,再读走时间,重复下去,直到i=33,也就是传了33位数据之后,停止接受,并将接受完成位置一。 之后对数据进行解码,也就是根据时间长短,判断数据是0还是1,并将数据按8位,一字节存入之前定义的数组中,这时候数组中第三个就是要传输的数据了,整个过程完成。 #include #define uchar unsigned char #define uint unsigned int ***it IR=P3^2; #define DataPort P0 //定义数据端口 ***it du=P2^6;// 段锁存 ***it we=P2^7;// 位锁存 uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};// 显示段码值0~9 uchar irtime;//红外用全局变量,存储红外带宽 bit ir_ok;//存储完成标志位 bit irpro_ok; //解码完成标志位 uchar irdata[33]; uchar irbyte[4]; void inter0_init() //定时器0初始化 ok { TMOD |= 0X02; TH0 = TL0 = 0; ET0 = 1; TR0 = 1; } void timer0() interrupt 1 using 1 //ok { irtime++; } void inter0_ex() //外部中断0初始化函数 { EA = 1; IT0 = 1; EX0 = 1; //开外部中断0 } void ex0_play()interrupt 0 //外部中断0处理函数 ok { static bit flag;//开始处理标志位 static uchar i;//存储33位数据 if(flag) { if(irtime<63&&irtime>=33)//开始标志信号持续时间,这个和具体晶振频率有关 i = 0; irdata = irtime; irtime=0; i++;//处理下一位 if(i == 33) { ir_ok = 1; i = 0; } } else { flag = 1; //开始标志位置1 irtime = 0; //重新计时 } } void Ir_work(void)//红外键值码 //ok { switch(irbyte[2])//判断第三个数码值,第三个为数据位,第四个是数据码取反校验位 { case 0x0c:DataPort=table[1];break;//1 case 0x18:DataPort=table[2];break;//2 case 0x5e:DataPort=table[3];break;//3 case 0x08:DataPort=table[4];break;//4 case 0x1c:DataPort=table[5];break;//5 case 0x5a:DataPort=table[6];break;//6 case 0x42:DataPort=table[7];break;//7 case 0x52:DataPort=table[8];break;//8 case 0x4a:DataPort=table[9];break;//9 default:break; } irpro_ok=0;//处理完成标志 } void Ircordpro(void)//解码函数 //ok { unsigned char i, j, k; unsigned char byte,value; k=1; for(i=0;i<4;i++) //处理4个字节 { for(j=1;j<=8;j++) //处理1个字节8位 { byte=irdata[k]; if(byte>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差 value|=0x80; if(j<8) { value>>=1; } k++; } irbyte=value; //存储解码值 value=0; } irpro_ok=1;//处理完毕标志位置1 } void main() { inter0_init(); inter0_ex(); we = 1; P0 = 0x00; we = 0; while(1) { if(ir_ok) { Ircordpro(); ir_ok = 0; } if(irpro_ok) { Ir_work(); } } } |
|
|
|
只有小组成员才能发言,加入小组>>
2549 浏览 0 评论
1149浏览 2评论
748浏览 1评论
501浏览 0评论
267浏览 0评论
430浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 21:42 , Processed in 1.423529 second(s), Total 79, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号