STM32之红外接收

摘自:http://blog.csdn.net/feilusia/article/details/53319896

一、简介

本文介绍如何在STM32上使用红外接收头接收红外信号

其中,红外协议采用为最常见的NEC协议


二、实验平台

库版本:STM32F10x_StdPeriph_Lib_V3.5.0

编译软件:MDK4.53

硬件平台:STM32开发板(主芯片stm32f103c8t6)

仿真器:JLINK


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
1)《STM8L之红外发射》:http://blog.csdn.net/feilusia/article/details/53305956

2、在进行本文步骤前,请先 实现 以下博文:
1)《STM32之系统滴答定时器》 :http://blog.csdn.net/feilusia/article/details/52835711

五、基础知识

1、硬件原理

答:

1)接收管元器件


上图的引脚从左到右依次为:OUT(空闲时为高电平,接收到载波时为低电平)、GND、VCC。

电压范围为2.7V~5.5V。


附淘宝链接:

https://detail.tmall.com/item.htm?spm=a1z10.3-b.w4011-3079905380.37.ZS9LXo&id=14265901312&rn=9fa50b1d19ad40efa6f149c454e32cfa&abbucket=14


2)硬件原理图


如上图,红外接收引脚接到PB3,PB3为JTAG使用引脚,因此在代码中要注意将引脚功能切换回普通IO口。


2、本文中红外接收的流程是如何的?

答:

1)配置红外接收引脚PB3为IO上拉中断方式。

2)当红外接收头接收到红外遥控器发出的载波信号时,PB3被拉低,代码进入中断服务函数,并依次判断时序是否满足:引导码、用户码、用户反码、键码、键码反码、停止位。

如果时序正确,则获得键值。如果时序不正确,则将此数据过滤。


六、实验步骤

注:下面的步骤为主要步骤,并不是所有步骤,编译有错误的地方请自行修改。

1、编写并添加红外接收的驱动

1)编写驱动GUA_Infrared_Receiver.c(存放在“……\HARDWARE”)

[cpp]  view plain  copy
  1. //******************************************************************************                
  2. //name:             GUA_Infrared_Receiver.c               
  3. //introduce:        红外传感器接收驱动        
  4. //author:           甜甜的大香瓜                       
  5. //email:            897503845@qq.com           
  6. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  7. //changetime:       2016.12.29        
  8. //******************************************************************************     
  9. #include "stm32f10x.h"   
  10. #include "GUA_Infrared_Receiver.h"  
  11. #include "GUA_SysTick.h"  
  12.   
  13. /*********************宏定义************************/  
  14. #define TRUE            0  
  15. #define FALSE           1  
  16.   
  17. //红外接收引脚  
  18. //IO  
  19. #define GUA_INFRARED_RECEIVER_PORT               GPIOB  
  20. #define GUA_INFRARED_RECEIVER_PIN                GPIO_Pin_3  
  21. #define GUA_INFRARED_RECEIVER_RCC                RCC_APB2Periph_GPIOB  
  22.   
  23. //中断  
  24. #define GUA_INFRARED_RECEIVER_EXTI_LINE          EXTI_Line3  
  25. #define GUA_INFRARED_RECEIVER_PORTSOURCE         GPIO_PortSourceGPIOB  
  26. #define GUA_INFRARED_RECEIVER_PINSOURCE          GPIO_PinSource3   
  27. /*********************外部变量************************/  
  28. GUA_U32 gGUA_InfraredReceiver_Data = 0;  
  29.   
  30. /*********************内部函数************************/   
  31. static void GUA_Infrared_Receiver_IO_Init(void);  
  32. static GUA_U16 GUA_Infrared_Receiver_GetHighLevelTime(void);  
  33. static GUA_U16 GUA_Infrared_Receiver_GetLowLevelTime(void);  
  34.   
  35. //******************************************************************************          
  36. //name:             GUA_Infrared_Receiver_IO_Init          
  37. //introduce:        红外接收的IO初始化       
  38. //parameter:        none         
  39. //return:           none        
  40. //author:           甜甜的大香瓜               
  41. //email:            897503845@qq.com           
  42. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  43. //changetime:       2016.12.29        
  44. //******************************************************************************    
  45. static void GUA_Infrared_Receiver_IO_Init(void)  
  46. {     
  47.     //IO结构体  
  48.     GPIO_InitTypeDef GPIO_InitStructure;  
  49.   
  50.     //失能JTAG和SWD在PB3上的功能使用  
  51.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);  
  52.     GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  
  53.       
  54.     //时钟使能  
  55.     RCC_APB2PeriphClockCmd(GUA_INFRARED_RECEIVER_RCC | RCC_APB2Periph_AFIO, ENABLE);      
  56.       
  57.     //红外接收IO配置  
  58.     GPIO_InitStructure.GPIO_Pin = GUA_INFRARED_RECEIVER_PIN;          
  59.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;   
  60.     GPIO_Init(GUA_INFRARED_RECEIVER_PORT, &GPIO_InitStructure);   
  61. }  
  62.   
  63. //******************************************************************************              
  64. //name:             GUA_Infrared_Receiver_Exti_Init             
  65. //introduce:        红外接收的IO中断初始化           
  66. //parameter:        none                   
  67. //return:           none           
  68. //author:           甜甜的大香瓜                   
  69. //email:            897503845@qq.com       
  70. //QQ group          香瓜单片机之STM8/STM32(164311667)                    
  71. //changetime:       2016.12.29                    
  72. //******************************************************************************  
  73. static void GUA_Infrared_Receiver_Exti_Init(void)  
  74. {     
  75.     EXTI_InitTypeDef EXTI_InitStructure;  
  76.   
  77.     //中断配置  
  78.     EXTI_ClearITPendingBit(GUA_INFRARED_RECEIVER_EXTI_LINE);  
  79.     GPIO_EXTILineConfig(GUA_INFRARED_RECEIVER_PORTSOURCE, GUA_INFRARED_RECEIVER_PINSOURCE);    
  80.   
  81.     EXTI_InitStructure.EXTI_Line = GUA_INFRARED_RECEIVER_EXTI_LINE;  
  82.     EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
  83.     EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;    
  84.     EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
  85.     EXTI_Init(&EXTI_InitStructure);  
  86. }  
  87.   
  88. //******************************************************************************          
  89. //name:             GUA_Infrared_Receiver_Init          
  90. //introduce:        红外接收初始化       
  91. //parameter:        none         
  92. //return:           none        
  93. //author:           甜甜的大香瓜               
  94. //email:            897503845@qq.com           
  95. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  96. //changetime:       2016.12.29       
  97. //******************************************************************************    
  98. void GUA_Infrared_Receiver_Init(void)  
  99. {  
  100.   //初始化IO  
  101.   GUA_Infrared_Receiver_IO_Init();  
  102.   
  103.   //初始化中断配置  
  104.     GUA_Infrared_Receiver_Exti_Init();    
  105. }  
  106.   
  107. //******************************************************************************          
  108. //name:             GUA_Infrared_Receiver_GetHighLevelTime          
  109. //introduce:        红外接收获取高电平维持时间     
  110. //parameter:        none         
  111. //return:           nNum:返回20us的个数        
  112. //author:           甜甜的大香瓜               
  113. //email:            897503845@qq.com           
  114. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  115. //changetime:       2016.12.29        
  116. //******************************************************************************   
  117. static GUA_U16 GUA_Infrared_Receiver_GetHighLevelTime(void)  
  118. {  
  119.     GUA_U16 nGUA_Num = 0;  
  120.       
  121.     //判断是否一直为高电平  
  122.     while(GPIO_ReadInputDataBit(GUA_INFRARED_RECEIVER_PORT, GUA_INFRARED_RECEIVER_PIN) == Bit_SET)  
  123.     {  
  124.         //超时超时溢出  
  125.         if(nGUA_Num >= 250)   
  126.         {  
  127.             return nGUA_Num;  
  128.         }  
  129.       
  130.         //计延时20us的次数  
  131.         nGUA_Num++;  
  132.           
  133.         //延时  
  134.         GUA_Delay_Us(17);             
  135.     }  
  136.       
  137.     return nGUA_Num;  
  138. }  
  139.   
  140. //******************************************************************************          
  141. //name:             GUA_Infrared_Receiver_GetLowLevelTime          
  142. //introduce:        红外接收获取低电平维持时间     
  143. //parameter:        none         
  144. //return:           nNum:返回20us的个数         
  145. //author:           甜甜的大香瓜               
  146. //email:            897503845@qq.com           
  147. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  148. //changetime:       2016.12.29         
  149. //******************************************************************************   
  150. static GUA_U16 GUA_Infrared_Receiver_GetLowLevelTime(void)  
  151. {  
  152.     GUA_U16 nGUA_Num = 0;  
  153.       
  154.     //判断是否一直为低电平  
  155.     while(GPIO_ReadInputDataBit(GUA_INFRARED_RECEIVER_PORT, GUA_INFRARED_RECEIVER_PIN) == Bit_RESET)  
  156.     {  
  157.         //超时超时溢出  
  158.         if(nGUA_Num >= 500)   
  159.         {  
  160.             return nGUA_Num;  
  161.         }  
  162.       
  163.         //计延时20us的次数  
  164.         nGUA_Num++;  
  165.           
  166.         //延时  
  167.         GUA_Delay_Us(17);             
  168.     }  
  169.       
  170.     return nGUA_Num;  
  171. }  
  172. //******************************************************************************              
  173. //name:             GUA_Infrared_Receiver_Process             
  174. //introduce:        红外接收的处理函数           
  175. //parameter:        none                   
  176. //return:           GUA_INFRARED_RECEIVER_OK or GUA_INFRARED_RECEIVER_ERROR           
  177. //author:           甜甜的大香瓜                   
  178. //email:            897503845@qq.com       
  179. //QQ group          香瓜单片机之STM8/STM32(164311667)                    
  180. //changetime:       2016.12.29                     
  181. //******************************************************************************  
  182. GUA_U8 GUA_Infrared_Receiver_Process(void)  
  183. {  
  184.     GUA_U16 nGUA_Time_Num = 0;  
  185.     GUA_U8 nGUA_Data = 0;  
  186.     GUA_U8 nGUA_Byte_Num = 0;  
  187.     GUA_U8 nGUA_Bit_Num = 0;      
  188.       
  189.     //接收引导码9ms的低电平,过滤无用信号>10ms或<8ms  
  190.     nGUA_Time_Num = GUA_Infrared_Receiver_GetLowLevelTime();  
  191.     if((nGUA_Time_Num >= 500) || (nGUA_Time_Num <= 400))  
  192.     {  
  193.         return GUA_INFRARED_RECEIVER_ERROR;  
  194.     }     
  195.       
  196.     //接收引导码4.5ms的高电平,过滤无用信号>5ms或<4ms  
  197.     nGUA_Time_Num = GUA_Infrared_Receiver_GetHighLevelTime();  
  198.     if((nGUA_Time_Num >= 250) || (nGUA_Time_Num <= 200))  
  199.     {  
  200.         return GUA_INFRARED_RECEIVER_ERROR;  
  201.     }     
  202.               
  203.     //接收后4字节数据  
  204.     for(nGUA_Byte_Num = 0; nGUA_Byte_Num < 4; nGUA_Byte_Num++)  
  205.     {  
  206.         //接收每字节8位数据  
  207.         for(nGUA_Bit_Num = 0; nGUA_Bit_Num < 8; nGUA_Bit_Num++)  
  208.         {  
  209.             //接收每bit的前0.56ms的低电平,过滤无用信号>1.2ms或<0.40ms  
  210.             nGUA_Time_Num = GUA_Infrared_Receiver_GetLowLevelTime();  
  211.             if((nGUA_Time_Num >= 60) || (nGUA_Time_Num <= 20))  
  212.             {  
  213.                 return GUA_INFRARED_RECEIVER_ERROR;  
  214.             }     
  215.   
  216.             //接收每bit的后高电平时长:高电平数据,1.68ms(1.2ms~2.0ms),低电平数据,0.56ms(0.2ms~1ms),过滤其他无用信号  
  217.             nGUA_Time_Num = GUA_Infrared_Receiver_GetHighLevelTime();  
  218.             if((nGUA_Time_Num >=60) && (nGUA_Time_Num < 100))  
  219.             {  
  220.                 nGUA_Data = 1;  
  221.             }             
  222.             else if((nGUA_Time_Num >=10) && (nGUA_Time_Num < 50))  
  223.             {  
  224.                 nGUA_Data = 0;  
  225.             }  
  226.             else  
  227.             {  
  228.                 return GUA_INFRARED_RECEIVER_ERROR;  
  229.             }  
  230.   
  231.             //保存数据  
  232.             gGUA_InfraredReceiver_Data <<= 1;   
  233.             gGUA_InfraredReceiver_Data |= nGUA_Data;                          
  234.         }  
  235.     }  
  236.   
  237.     return GUA_INFRARED_RECEIVER_OK;      
  238. }  
注意,“GUA_Delay_Us(17);”函数实测为20us左右,我们想要延时的就是20us,因此形参为17。

2)编写驱动头文件GUA_Infrared_Receiver.h(存放在“……\HARDWARE”)

[cpp]  view plain  copy
  1. //******************************************************************************                
  2. //name:             GUA_Infrared_Receiver.h               
  3. //introduce:        红外传感器接收驱动的头文件        
  4. //author:           甜甜的大香瓜                       
  5. //email:            897503845@qq.com           
  6. //QQ group          香瓜单片机之STM8/STM32(164311667)                        
  7. //changetime:       2016.12.29       
  8. //******************************************************************************      
  9. #ifndef _GUA_INFRARED_RECEIVER_H_  
  10. #define _GUA_INFRARED_RECEIVER_H_  
  11.   
  12. /*********************宏定义************************/  
  13. #ifndef GUA_U8          
  14. typedef unsigned char GUA_U8;          
  15. #endif      
  16.   
  17. #ifndef GUA_8          
  18. typedef signed char GUA_8;          
  19. #endif        
  20.         
  21. #ifndef GUA_U16          
  22. typedef unsigned short GUA_U16;          
  23. #endif   
  24.   
  25. #ifndef GUA_16          
  26. typedef signed short GUA_16;          
  27. #endif           
  28.         
  29. #ifndef GUA_U32          
  30. typedef unsigned long GUA_U32;          
  31. #endif   
  32.   
  33. #ifndef GUA_32          
  34. typedef signed long GUA_32;         
  35. #endif  
  36.   
  37. #ifndef GUA_U64      
  38. typedef unsigned long long GUA_U64;    
  39. #endif  
  40.   
  41. #ifndef GUA_64      
  42. typedef signed long long GUA_64;    
  43. #endif  
  44.   
  45. #define GUA_INFRARED_RECEIVER_OK                    0  
  46. #define GUA_INFRARED_RECEIVER_ERROR             1  
  47.   
  48. #define GUA_INFRARED_RECEIVER_KEY1              0x00FF00FF  
  49. #define GUA_INFRARED_RECEIVER_KEY2              0x00FF01FE  
  50. #define GUA_INFRARED_RECEIVER_KEY3              0x00FF02FD  
  51. #define GUA_INFRARED_RECEIVER_KEY4              0x00FF03FC  
  52.   
  53. /*********************外部变量************************/  
  54. extern GUA_U32 gGUA_InfraredReceiver_Data;  
  55.   
  56. /*********************外部函数声明************************/    
  57. extern void GUA_Infrared_Receiver_Init(void);  
  58. extern GUA_U8 GUA_Infrared_Receiver_Process(void);  
  59.   
  60. #endif  
由于发送端自定义了四个按键,因此香瓜在这里将这四个按键键值写在这里,此处可自行修改。

3)工程中添加GUA_Infrared_Receiver.c



4)在MDK设置中添加驱动源文件路径



2、设置NVIC中断优先级(GUA_NVIC.c的GUA_NVIC_Init中

[cpp]  view plain  copy
  1. //红外接收  
  2. GUA_NVIC_Config(NVIC_PriorityGroup_2, EXTI3_IRQn, 2, 2, ENABLE);  

3、写中断服务函数(stm32f10x_it.c中)
1)添加头文件

[cpp]  view plain  copy
  1. #include "GUA_Infrared_Receiver.h"  

2)编写中断服务函数

[cpp]  view plain  copy
  1. //******************************************************************************              
  2. //name:             EXTI3_IRQHandler             
  3. //introduce:        红外接收的处理函数          
  4. //parameter:        none                   
  5. //return:           none           
  6. //author:           甜甜的大香瓜                   
  7. //email:            897503845@qq.com       
  8. //QQ group          香瓜单片机之STM8/STM32(164311667)                    
  9. //changetime:       2016.11.21                       
  10. //******************************************************************************  
  11. void EXTI3_IRQHandler(void)  
  12. {  
  13.     //红外  
  14.   if(EXTI_GetITStatus(EXTI_Line3) != RESET)  
  15.   {  
  16.         //接收红外数据正确  
  17.         if(GUA_Infrared_Receiver_Process() == GUA_INFRARED_RECEIVER_OK)  
  18.         {  
  19.             function = FUNC_INFRARED_RECEIVER_EVENT;      
  20.         }                 
  21.       
  22.     //清除标志位    
  23.     EXTI_ClearITPendingBit(EXTI_Line3);  
  24.   }  
  25. }  

4、在应用层中调用

1)添加头文件(main.c中)

[cpp]  view plain  copy
  1. #include "GUA_Infrared_Receiver.h"  

2) 添加驱动初始化代码(main.c的main函数中)

[cpp]  view plain  copy
  1. //红外接收初始化  
  2. GUA_Infrared_Receiver_Init();  

3) 添加测试代码

①写红外接收处理事件(main.c的main函数中)

[cpp]  view plain  copy
  1.    //红外接收处理           
  2.    case FUNC_INFRARED_RECEIVER_EVENT:   
  3.    {  
  4. //键值处理  
  5. switch(gGUA_InfraredReceiver_Data)  
  6. {  
  7.     //红外按键1  
  8.     case GUA_INFRARED_RECEIVER_KEY1:  
  9.     {  
  10.         break;  
  11.     }  
  12.   
  13.     //红外按键2  
  14.     case GUA_INFRARED_RECEIVER_KEY2:  
  15.     {  
  16.         break;  
  17.     }  
  18.       
  19.     //红外按键3  
  20.     case GUA_INFRARED_RECEIVER_KEY3:  
  21.     {  
  22.         break;  
  23.     }  
  24.   
  25.     //红外按键4  
  26.     case GUA_INFRARED_RECEIVER_KEY4:  
  27.     {  
  28.         break;  
  29.     }     
  30.   
  31.     //其他  
  32.     default:  
  33.     {  
  34.         break;  
  35.     }                                     
  36. }  
  37.   
  38.        //返回空闲状态  
  39.        function = FUNC_IDLE_EVENT;                 
  40.        break;                 
  41.    }  

②写红外处理事件宏(main.h中)

[cpp]  view plain  copy
  1. //主轮询的宏  
  2. #define FUNC_IDLE_EVENT                       0x00    //空闲  
  3. #define FUNC_INFRARED_RECEIVER_EVENT                  0x16    //红外接收处理  


七、注意事项

暂无。


八、实验结果

仿真并设置断点在红外接收处理事件中,全速运行。

当遥控器发送0x00FF00FF的键值时,代码会停止在断点处,并且gGUA_InfraredReceiver_Data的值为0x00FF00FF。

  • 3
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值