基于stm32f103zet6之红外遥控解码的学习

发布者:asd123yui最新更新时间:2017-09-07 来源: eefocus关键字:stm32f103zet6  红外遥控  解码 手机看文章 扫描二维码
随时随地手机看文章

一、红外遥控解码部分从昨天开始整,一直到现在才解码成功!中途遇到了不少问题,结果出来后还是觉得有必要总结一下,唉!

1、首先我又是怀疑我硬件电平不兼容德问题,后来给接上3.3V的电压,还是不行,好吧,算失败了,在网上查阅了比较多的帖子,也找了比较多的资料,最终还是决定用原本那个生了锈的遥控来解码!

2、然后准备参照着原来51的思想来移植代码,也确实找到类似的代码貌似使用的2.0的库写的,单步调试了半天,总感觉在延时部分出了点问题,所以比较郁闷,好吧,分析来分析去的,结果真的是没有半点现象啊!果断网上求助,游荡了一会,压根没人理,高手不屑一顾呀!!偶然间让我遇到了原子哥的那段红外的代码,拖出来分析,所以就有了今晚解码成功的结果!

3、我照着原子的移植,我用的是自己的延时,也就是系统定时器,MTD,单步调试的时候,发现居然死在了systick那里,进不了中断,一步步观察,好像导致进不了中断的原因就是:我已经进了外部中断,心想,没道理啊,系统定时器的优先级不应该是高于外部中断的么,因为他是核决定的呀(至少我是这么想的),然后又查了相关资料,据说系统定时器的中断优先级是最低的,这时候我才恍然大悟!

现在开始分析代码,虽然说原子的代码风格不怎么样,但是个人觉得他真的好牛逼,库函数是人家ST公司搞出来的,我想,原子的这套代码,应该基本上是他自己一个人整出来的吧!

二、所谓红外遥控!(针对我手上的红外遥控)

1、红外解码一直是单片机中应用较多的,需要设备加装专用解码芯片,这就大大减轻了单片机的负担。需要单片机样例使用延时做红外解码,比较容易理解,
下面通过TC9012和uPD6121芯片为例大致了解解码原理:
先看一接收头产生的波形图,这是原子的一张图


         % U, K" ?3 K2 _( j' a! e: K: o
从上图可以看出 9.0ms高电平+4.5ms低电平称为头码,用于识别是否遥控码开始,这是一张连续发射码的波形图(就是一直按下某一遥控器按键)。; n5 [
+ z; ^4 d( T# L) h" Y6 B5 j3 T
头码过后会出现4个8位的数据,我们最终目的就是要把这个 32位(4x8)从一体化红外接收头提取出来,并转换成16进制数,用于区分不同按键按下得出的不同数值。
在遥控器发射波形中,可以知道,8位数中的0或者1不是用高低电平表示,而是用不同的低电平的宽度表示,0.565ms表示0,1.69ms表示1,2个位中间还会有一个0.56ms的高电平
     看到如上图波形,表示单片机引脚可以接收到的波形,我们只要通过单片机读取波形并分析波形的宽度,然后分辨出是头码,还是0或者1,最后整理出这组码的16进制组合。正确的解码结果是按同一个按键得出的16进制数值是不变化的。通过这个原理,我们可以分辨出每个按键的键值。
! z7 B/ `2 Q: z
基本原理分析如下,如接收到头码是4.5ms低电平+4.5ms高电平,我们分析 第一个下降沿到第二个下降沿的宽度是 9ms,我们判断这个头码可以给定一个范围,只要数据在这个范围内则认为头码是正确的,检测头码正确后接着检测剩下的32位数值。

2、用自己的话概括就是:平常是高电平 --->按键按下 --->产生引导码(9+4.5)ms--->然后判断是不是连续发送--->1还是0--->存储码值--->转换码值!简单就是这样!

3、首先是我的主程序,代码注释都非常详细,不解释了!注意码值需要依据自己的遥控而定,我就是单步测试出来的!


  1. #include "stm32f10x.h"      

  2. #include "Usart.h"  

  3. #include "stdio.h"  

  4. #include "Remote_Control.h"  

  5. #include "Delay.h"  

  6.   

  7. /**************************PA1接红外接收端************************************/  

  8. /************由于没有做外设测试的程序是:按键PA0仅一个LED灯*******************/  

  9. /*******由于没有做外设测试的程序是:串口采用的是PA9->(T<->T),PA9->(R<->R)*****/  

  10.   

  11.   

  12. int main(void)  

  13. {  

  14.     u8 key;  

  15.     USART1_Config();  

  16.     delay_init(72);                                 //延时初始化  

  17.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级  

  18.     printf("\r\n ("__DATE__ " - " __TIME__ ") \r\n");  

  19.     Remote_Init();  

  20.     while(1)  

  21.     {       

  22.         if(Remote_Rdy)  

  23.         {  

  24.             key=Remote_Process();  

  25.             switch(key)  

  26.             {  

  27.              case 0x68:printf("0\n");break;//0      

  28.              case 0x30:printf("1\n");break;//1   

  29.              case 0x18:printf("2\n");break;//2  

  30.              case 0x7a:printf("3\n");break;//3  

  31.              case 0x10:printf("4\n");break;//4  

  32.              case 0x38:printf("5\n");break;//5  

  33.              case 0x5a:printf("6\n");break;//6  

  34.              case 0x42:printf("7\n");break;//7  

  35.              case 0x4a:printf("8\n");break;//8  

  36.              case 0x52:printf("9\n");break;//9  

  37.              default:break;  

  38.             }  

  39.         }  

  40.     }  

  41. }  


4、然后是驱动程序


  1. /*-------------------------协议-------------------------- 

  2. 开始拉低9ms,接着是一个4.5ms的高脉冲,通知器件开始传送数据了 

  3. 接着是发送4个8位二进制码,第一二个是遥控识别码(REMOTE_ID),第一个为 

  4. 正码(0),第二个为反码(255),接着两个数据是键值,第一个为正码 

  5. 第二个为反码.发送完后40ms,遥控再发送一个9ms低,2ms高的脉冲, 

  6. 表示按键的次数,出现一次则证明只按下了一次,如果出现多次,则可 

  7. 以认为是持续按下该键. 

  8. ---------------------------------------------------------*/   

  9. #include "Remote_Control.h"  

  10. #include "Delay.h"  

  11.                 

  12. u32 Remote_Odr=0;    //命令暂存处              

  13. u8  Remote_Cnt=0;    //按键次数,此次按下键的次数  

  14. u8  Remote_Rdy=0;    //红外接收到数据      

  15. /************************初始化红外接收引脚的设置**********************************/  

  16. /******************选择PA1脚作为外部中断,用于红外输入*****************************/  

  17. void Remote_Init(void)  

  18. {                              

  19.     GPIO_InitTypeDef GPIO_InitStructure;    //GPIO  

  20.     NVIC_InitTypeDef NVIC_InitStructure;    //中断  

  21.     EXTI_InitTypeDef EXTI_InitStructure;    //外部中断线  

  22.            

  23.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO, ENABLE );     

  24.    

  25.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;  

  26.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;              //注意需要上拉输入  

  27.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  

  28.     GPIO_Init(GPIOA, &GPIO_InitStructure);    

  29.    

  30.     GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1);       //选择PA1所在的GPIO管脚用作外部中断线路EXIT1          

  31.    

  32.     EXTI_InitStructure.EXTI_Line = EXTI_Line1;              //外部线路EXIT1  

  33.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;         //设外外部中断模式:EXTI线路为中断请求  EXTI_Mode_Event ;//设置 EXTI线路为事件请求   

  34.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;         //外部中断触发沿选择:设置输入线路下降沿为中断请求  

  35.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;               //使能外部中断新状态  

  36.     EXTI_Init(&EXTI_InitStructure);                     //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器     

  37.    

  38.     NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;            //使能按键所在的外部中断通道  

  39.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;       //先占优先级2级  

  40.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;          //从优先级1级  

  41.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             //使能外部中断通道  

  42.     NVIC_Init(&NVIC_InitStructure);                     //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器  

  43. }     

  44. /*功能    :检测脉冲宽度*****************************************/  

  45. /*说明    :最长脉宽为5ms 

  46. /*返回值: t代表脉宽为t*20us(T=1~250); *************************/  

  47. u8 Pulse_Width_Check(void)  

  48. {  

  49.     u8 t=0;    

  50.     while(RDATA)  

  51.     {      

  52.         t++;  

  53.         delay_us(20);                      

  54.         if(t==250)  

  55.         return t;           //超时溢出  

  56.     }  

  57.     return t;  

  58. }                

  59.    

  60.        

  61. /*功能    : 中断函数*****************************************/  

  62. /*说明    :检测是否有中断 

  63. /*返回值: 无************************************************/    

  64. void EXTI1_IRQHandler(void)  

  65. {         

  66.     u8 res=0;  

  67.     u8 OK=0;   

  68.     u8 RODATA=0;   

  69.     EXTI_ClearITPendingBit(EXTI_Line1);     //清除EXTI1线路挂起位                     

  70.     while(1)  

  71.     {          

  72.         if(RDATA)//有高脉冲出现  

  73.         {  

  74.             res=Pulse_Width_Check();        //获得此次高脉冲宽度         

  75.             if(res==250)break;          //非有用信号  

  76.             if(res>=200&&res<250)OK=1;    //获得前导位(4.5ms)  

  77.             else if(res>=85&&res<200)     //按键次数加一(2ms)  

  78.             {                                          

  79.                 Remote_Rdy=1;           //接受到数据  

  80.                 Remote_Cnt++;           //按键次数增加  

  81.                 break;  

  82.             }  

  83.             else if(res>=50&&res<85)RODATA=1;//1.5ms  

  84.             else if(res>=10&&res<50)RODATA=0;//500us      

  85.             if(OK)  

  86.             {  

  87.                 Remote_Odr<<=1;                             

  88.                 Remote_Odr+=RODATA;     //这里得到的是一个32位的码值,   //地址码、地址反码、控制码、控制反码  

  89.                 Remote_Cnt=0;         //按键次数清零  

  90.             }     

  91.         }                                      

  92.     }             

  93. }    

  94.   

  95. /*功能    : 处理红外键盘*****************************************/  

  96. /*说明    :无 

  97. /*返回值: 键值************************************************/  

  98. u8 Remote_Process(void)  

  99. {                 

  100.     u8 t1,t2;     

  101.     t1 = ((Remote_Odr >> 8)&(0xff));  //得到控制码  

  102.     t2=(Remote_Odr >> 0)&0xff;        //得到控制反码   

  103.     Remote_Rdy=0;           //清除标记              

  104. //    if(t1==(u8)~t2&&t1==REMOTE_ID)  //检验遥控识别码(ID)及地址   

  105. //    {   

  106. //        t1=Remote_Odr>>8;  

  107. //        t2=Remote_Odr;      

  108. //    }       

  109.     if(t1==(u8)~t2)  

  110.         return t1;      //处理键值   

  111.     return 0xff;   

  112. }  

5、延时函数也采用用原子的!有时间自己改成定时器的!


  1. //延时nus  

  2. //nus为要延时的us数.                                               

  3. void delay_us(u32 nus)  

  4. {         

  5.     u32 temp;              

  6.     SysTick->LOAD=nus*fac_us; //时间加载            

  7.     SysTick->VAL=0x00;        //清空计数器  

  8.     SysTick->CTRL=0x01 ;      //开始倒数        

  9.     do  

  10.     {  

  11.         temp=SysTick->CTRL;  

  12.     }  

  13.     while(temp&0x01&&!(temp&(1<<16)));//等待时间到达     

  14.     SysTick->CTRL=0x00;       //关闭计数器  

  15.     SysTick->VAL =0X00;       //清空计数器       

  16. }  

6.算是要注意的地方吧,有些地方还是不习惯原子的代码风格,比如:



  1. #define RDATA GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)    //红外数据输入脚  


当然,这只是个人感觉!


就弄到这里吧!!!


关键字:stm32f103zet6  红外遥控  解码 引用地址:基于stm32f103zet6之红外遥控解码的学习

上一篇:基于stm32f103zet6之使用FSMC驱动TFT的学习
下一篇:基于stm32f103zet6的定时器的学习3(定时器产生4路PWM)

推荐阅读最新更新时间:2024-03-16 15:36

解码恒大全球电池研究院
恒大汽车不仅造车,还在研发电池。今天,随着许家印视察恒大全球电池研究院,恒大电池研发的最新进展也随之曝光。 据了解,目前恒大汽车已在人才、研发技术等方面大力布局,积极提升电池研发实力。 据透露,恒大电池技术预计明年下半年将打造成为世界领先水平。对计划在明年陆续量产的恒驰来说,这无疑将极大提升自身核心竞争力,助力其快速抢攻新能源汽车市场。
[汽车电子]
<font color='red'>解码</font>恒大全球电池研究院
Vishay为Minimold红外接收器增加侧开支架,降低组装成本
日前,Vishay Intertechnology, Inc.(NYSE 股市代号:VSH)宣布,针对用于红外遥控应用的TSOP33xxx和TSOP53xxx系列小型Minimold红外接收器模块,推出新款侧开金属支架,扩大了其光电子产品组合。Vishay Semiconductors P1xP支架的优点是支持红外回流焊,实现引脚浸锡膏(PiP)焊,从而降低组装成本,提高可靠性。   设计者不断用更高温的元器件替换通孔器件,因此具有良好性价比的PiP技术通过回流焊,作为一种贴装元器件的新方法与表面贴装封装一起出现在市场上。在PiP工艺中,后道的元器件被定位在PCB上,整个电路板用回流炉一次焊完,省掉了对通孔器件的波峰焊步骤。这样就
[半导体设计/制造]
具有红外遥控功能的寻迹小车控制设计
主要内容和要求: 1.红外遥控装置能控制单片机,使之发出进、退、左转、右转控制(并给出动作指示)。 2.使用红外对管设计寻迹电路(即自动区别黑白道标记)。 3.根据寻迹信号设计单片机对电机的控制电路。 4.单片机采用汇编及C51进行编制,程序的下载为ISP方式。 参考文献及资料: MCS-51单片机及接口技术 单片机C51编程 需要人数:一人 对学生的要求:对单片机感兴趣并有一定的动手能力。 ORG 0000H START:    MOV P0,#0FFH;开机初始化   MOV P2,#00H   MOV P3,#0FFH RECE:   MOV R5,#8   JB P0.7,$   MOV R7,#15
[单片机]
单片机做红外遥控解码
你家里是否有一个电视机遥控器或者空调机遥控器呢?你是否也想让它遥控其他的电器甚至让它遥控您的电脑呢?那好,跟我一起做这个“红外遥控解码器”。 该小制作所需要的元件很少:单片机TA89C2051一只,RS232接口电平与TTL电平转换心片MAX232CPE 一只,红外接收管一只,晶振11.0592MHz,电解电容10uF4只,10uF一只,电阻1K1个,300欧姆左右1个,瓷片电容30P2个。发光二极管8个。价钱不足20元。 电路原理介绍: 主控制单元是单片机AT89C2051,中断口INT0跟红外接受管U1相连,接收红外信号的脉冲,8个发光二极管作为显示解码输出(也可以用来扩展接其他控制电路),U3是跟电脑串行口RS232相连
[单片机]
嵌入式DSP上的视频编解码
随着数字多媒体的应用日渐广泛,视频解码在嵌入式系统设计中变成一个基本要素。视频标准有多种,依赖于产品可实施其中的一个或者多个标准。当然这不是全部,视频仅仅是多媒体码流的一部分,另外还有音频或者语音需要并行处理。因此,一个精确的处理存储或数据流的同步层是必需的。此外,视频解码本身对性能要求较高,需要不同于先前基于语音和信息应用的系统架构;这就对便携系统提出了特殊挑战,而桌面应用同样面临这些问题。 通用视频标准和编解码器 联合视频组(Joint Video Team, JVT)由ITU的视频编码专家组(Video Coding Experts Group, VCEG)和ISO/IEC运动图像专家组(Moving Picture E
[嵌入式]
红外遥控器信号的接收和转发
摘要:介绍用51系列单片机采集家用电器红外遥控器信号,并将其转发原理。文中给出红外接收芯片的外围电路和测量接收波形的程序。 关键词:红外遥控 单片机系统 转发 红外遥控在家电产品中有广泛应用,但各产生的遥控器不能相互兼容。目前市场上常见的万能遥控器只能对某几种产品进行控制,不是真正的“万能”,而且不能对新上市的产品进行控制。本文介绍一种用单片机对红外遥控器信号接收和转发的方法,由于只关心发射信号波形中的高低电平的宽度,不管其如何编码,因此可以用来实现自学习万能遥控器。 一、红外信号的接收和波形测量 所有红外遥控器的输出都是用编码后串行数据对38~40kHz的方波进行脉冲幅度调制而产生的。如果直接对已调波进行测量,由于单片机
[网络通信]
PQA500为编解码器提供准确可重复的质量评测
泰克公日前宣布,Rai Way已决定采用泰克公司获奖的PQA500图像质量分析仪,为他们的高清视频分配和传输系统中的高清晰度(HD)视频编码器和解码器提供可靠的质量评测和质量鉴定。Rai Way拥有和运营意大利公共广播业主RAI集团下的广播部门,PQA500帮助Rai Way在购置HD设备时做出了明智选择。 随着更多的广播电视业主转向高清输出,新设备和现有设备能够为最高质量的图像提供支持成为必须。泰克公司的PQA500,采用了模拟人类视觉系统的准确算法,提供了一整套可重复的客观图像质量测量技术,非常符合人类的主观视觉评测结果。利用PQA500,广播电视业主和其它用户能够对编码设备和解码设备的图像质量进行准确地、全面地评
[测试测量]
一种基于CPLD的曼彻斯特编解码器设计
引言 虽然计算机通信的方法和手段多种多样,但都必须依靠数据通信技术。数据通信就是将数据信号加到数据传输信道上进行传输,并在接收点将原始发送的数据正确地恢复过来。由于计算机产生的一般都是数字信号,因此计算机之间的通信实际上都属于数据通信。曼彻斯特码编解码器是1553B总线接口中不可缺少的重要组成部分。曼彻斯特码编解码器设计的好坏直接影响总线接口的性能。在数控测井系统和无线监控等领域,曼彻斯特码编解码器都有广泛应用。 1 数据通信系统结构 图1所示是数据通信系统的基本构成。在计算机通信中,通信双方传递的信息必须进行量化并以某种形式进行编码后才能进行传输。机内信号不论采用哪一种编码方法,它们的基本信号都是脉冲信号,为了减少信号在传
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved