红外线遥控数据的学习和转发(基于新唐M0单片机实现)本文只是研发的一点心得,是产品化证明了非常实用的东西,文字组织相对不那么严谨,适合有一定经验的自动控制工程师借鉴。红外线遥控的基础知识有不太多的阐述,目前为止我所见到的红外线遥控器基本都是基于送脉冲+停止等待的循环,所以学习红外线遥控数据主要是要获取如下参数1.送出脉冲的脉冲频率(就是所谓载波)2.送出脉冲的宽度3.停止等待到下一个送出脉冲的宽度采样就会有误差,实际测试过程中发现实际红外解码设备其实比较粗糙,即使有点误差也能100%动作执行单元,毕竟我们学习的过程中没有累计误差。要采样到数据必须有合适的硬件电路,其实最简单的方法就是用一个家电用的接收管来实现,里面有现成的带通滤波器出来就是方波不过载波就没法学习了,因为家电一般都是用一个频率所以也基本可以实现,因为我们设计产品时是定位于万能遥控器,要做好就必须要采集载波,为此采用的是不过硬件带通的办法实现采集的,算法麻烦一点,但是可以实现所有红外信号的复制。由于采样数据时数据序列是整块发下来的,有的遥控器发出来的数据比较长,所以在单片机选型时要选择内存相对大一点的,想一边接受数据一边往FLASH写是比较困难的,我觉得不太容易实现,现在单片机也不是很贵这个费用还是值得的,否则整个开发过程会很费劲。实战中我们采用如下的硬件电路:---本文来源于网络,仅供参考,勿照抄,如有侵权请联系删除---实现的效果如下---本文来源于网络,仅供参考,勿照抄,如有侵权请联系删除---经过大量的验证,学习的方法可以适应所有红外遥控器,目前还没有发现学习后转发出来会有问题的设备。下面一段代码是主程序中启动红外学习的过程,供参考U8learning(MENU_HEADm_head,CONTROL_HEAD*ctr_head,U8Continue){U16x,y,count;U8flag;CONTROL_HEADctr_head_copy;IFR_IN_POWER=0;OpenInt1();flag=TRUE;---本文来源于网络,仅供参考,勿照抄,如有侵权请联系删除---touch_flag=TOUCH_RELEASE;count=0;if(Continue==TRUE){MY_PICTUREpic;ReadGD25Q16B(ctr_head->address,(U8*)&pic,sizeof(MY_PICTURE));//ShowLearning(ctr_head->x,ctr_head->y+pic.y_size+20,0,0xffff);#ifdefCHINESEShowString(ctr_head->x,ctr_head->y-24,"学习中",0,0xffff);#elseShowString(ctr_head->x,ctr_head->y-24,"leaning",0,0xffff);#endif}//while(touch_flag==TOUCH_PRESS);while(flag)//flag为按键退出的标志{//IFR_LEARN_TOO_LONG:TIMER_Reset(TIMER2);learn_step=0;learn_count=0;memset((U8*)&learn.InfraredBuf,0,MAX_BUF*2);while(1)//等待中断中获取脉冲数据(等待MAX_LEARN_IDLE){if(learn_step>1){/*if(InfraredBuf[0]<30)//起始最小脉冲判断(去毛刺){learn_step=0;continue;}*/if(Timer2Count>MAX_LEARN_IDLE)//空闲大于100ms退出等待break;}//if(learn_step>(MAX_BUF-1))if(learn_step>get_learn_step_length(m_head.attribute)){#ifdefCHINESEMessageBox("学习数据太长",2);#elseMessageBox("learntoolong",2);#endifbreak;}if(learn_step==0)---本文来源于网络,仅供参考,勿照抄,如有侵权请联系删除---{if(GetTouchxy(&x,&y,TRUE)){U16x1,y1;while(GetTouchxy(&x1,&y1,TRUE));//确实释放触摸了才能往下执行flag=FALSE;//学习时收到按键信号if(Continue==TRUE)break;//连续学习状态遇到键盘就退出学习状态if(juge_press(m_head,x,y,&ctr_head_copy)){//if(!IsFunctionKey(ctr_head_copy.attribute)||(ctr_head_copy.attribute==ESC_CTRL)){memcpy(ctr_head,&ctr_head_copy,sizeof(CONTROL_HEAD));//有效按键则返回被点击的控件头部break;}}}}}if(flag)//是否按键退出{if((learn_step>20)&&(learn.InfraredBuf[0]>5))//获得最少脉冲才有用,第一个脉冲没有小于这个的{Timer1Count=0;CloseInt1();//保证数据处理完成前不会改变学习到的红外数据TIMER_Reset(TIMER2);if(Continue==TRUE){chartempbuf[16];if((gCmd.cmd==HID_CMD_READ)&&(gCmd.chip_name==LEARN_INFRARED)){l...