你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CUBEMX(5)--自定义红外NEC解码,定时器TIM捕获方式

[复制链接]
STMCU小助手 发布时间:2022-8-19 13:56
概述
本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。

硬件准备
首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:

20200616155255613.jpg

选择芯片型号

20200616155328854.png

配置时钟源
HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:

20200616155740119.png

配置时钟树
STM32F0的最高主频到48M,所以配置48即可:

20200616155804751.png

串口配置
本次实验使用的串口1进行串口通信,波特率配置为115200。

20201130105900346.png

定时器配置
本次使用定时器1的通道2进行检测,配置入下。

20200616162851204.png

红外接收管
这里使用VS838的接收管,如下所示:

20200623160226119.png

红外编码
NEC协议载波:38khz
其逻辑1与逻辑0的表示如图所示:

20200623165733766.png

NEC协议格式:

20200623165807215.png

自定义红外编码
协议如下:

20201127160644531.jpg

代码
在main.c中,添加头文件,若不添加会出现 identifier “FILE” is undefined报错。

  1. /* USER CODE BEGIN Includes */
  2. #include "stdio.h"
  3. /* USER CODE END Includes */
复制代码

红外接收口定义
  1. /* USER CODE BEGIN PTD */
  2. #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)
  3. /* USER CODE END PTD */
复制代码

函数声明和串口重定向:
  1. /* USER CODE BEGIN PFP */
  2. #ifdef __GNUC__
  3. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
  4. #else
  5. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
  6. #endif /* __GNUC__ */
  7. PUTCHAR_PROTOTYPE
  8. {
  9.     HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
  10.     return ch;
  11. }
  12. /* USER CODE END PFP */
复制代码
  1. /* USER CODE BEGIN 0 */
  2. uint32_t OrderData = 0;
  3. uint8_t ReadyFlag = 0;
  4. uint8_t OK = 0;
  5. /* USER CODE END 0 */
复制代码

定时器配置

  1.   /* USER CODE BEGIN 2 */
  2.         HAL_TIM_Base_Start_IT(&htim1);//启动定时器
  3.         HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
  4.         printf("IR Capture !! \r\n");
  5.   /* USER CODE END 2 *
复制代码

红外接收代码

[4400,5000]是用于捕获4.5ms的信号
[550,700]是用于捕获560us的数据0信号
[1100,1250]是用于捕获1120us的数据1信号
[2000,2500]是用于捕获2240us的截止位信号
  1. /* USER CODE BEGIN 4 */
  2. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
  3. void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
  4. {
  5.         uint32_t fallingCount = 0 ; // 下降沿计数
  6.         uint8_t temp = 0 ;
  7.         // 判断是否是定时器1的外部捕获口2
  8.         if(htim->Instance == TIM1)
  9.         {
  10.                 // 捕获到了上升沿
  11.                 if(IR_IN1)
  12.                 {
  13.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
  14.                         __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
  15.                 }
  16.                 else
  17.                 {
  18.                         fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
  19.                         __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
  20.                         if( ((fallingCount > 4400) && (fallingCount <5000)))
  21.                                 OK = 1;/// 4.5ms引导电平
  22.                         else if (((fallingCount > 550) && (fallingCount < 700)))        
  23.                         {
  24.                                 temp = 0;//560 us,数据为0
  25.                         }        
  26.                         else if (((fallingCount > 1100) && (fallingCount < 1250)))
  27.                         {
  28.                         
  29.                                 temp = 1;//1120 us,数据为1
  30.                         }
  31.                         
  32.                         else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500)))        //2.240ms截止码
  33.                         {
  34.                           ReadyFlag = 1 ;
  35.                                 OK = 0;
  36.                         }
  37.                         if(OK)
  38.                         {
  39.                                 OrderData <<= 1 ;
  40.                                 OrderData += temp ;
  41.                                 KeyCount = 0; // 按键次数
  42.                         }
  43.                 }
  44.         }
  45. }
  46. /* USER CODE END 4 */
复制代码

主函数

  1.   /* USER CODE BEGIN WHILE */
  2.   while (1)
  3.   {
  4.     /* USER CODE END WHILE */

  5.     /* USER CODE BEGIN 3 */
  6.                 if(ReadyFlag)
  7.                 {
  8.                         printf("order=%08X , code=%d\r\n",OrderData,OrderData);
  9.                         OrderData = 0;
  10.                         OK = 0;
  11.                         ReadyFlag = 0;               
  12.                 }
  13.   }
  14.   /* USER CODE END 3 */
复制代码

结果演示
红外连续发送5次码值,发送分别为

1011(11)
11 1010(58)
11 0001(49)
11 1111(63)
11 0011(51)
分别如下所示:

20201128092712393.png



收藏 评论0 发布时间:2022-8-19 13:56

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版