STM32CUBEME--自定义红外NEC解码,定时器TIM捕获方式 概述 本篇文章主要介绍如何使用STM32CubeMX对红外波形进行解码,并通过串口打印。硬件准备 首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板: 选择芯片型号 使用STM32CUBEMX选择芯片stm32f030r8,如下所示:配置时钟源 HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:配置时钟树 STM32F0的最高主频到48M,所以配置48即可:串口配置 本次实验使用的串口1进行串口通信,波特率配置为115200。定时器配置 本次使用定时器1的通道2进行检测,配置入下。红外接收管 这里使用VS838的接收管,如下所示:红外编码 这里使用VS838的接收管,如下所示:NEC协议载波:38khz自定义红外编码 本文中数据1的低占空比设置为1120us,总时间为1.68ms,不是上图的2.25ms。 协议如下:生成工程设置 注意在生产工程设置中不能出现中文,不然会报错。代码生成设置 最后设置生成独立的初始化文件:生成代码 配置keil 在main.c中,添加头文件,若不添加会出现 identifier "FILE" is undefined报错。- /* USER CODE BEGIN Includes */
- #include "stdio.h"
- /* USER CODE END Includes */
复制代码 红外接收口定义 。- /* USER CODE BEGIN PTD */
- #define IR_IN1 HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_9)
- /* USER CODE END PTD */
复制代码 函数声明和串口重定向:- /* USER CODE BEGIN PFP */
- #ifdef __GNUC__
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
- #else
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
- #endif /* __GNUC__ */
- PUTCHAR_PROTOTYPE
- {
- HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
- return ch;
- }
- /* USER CODE END PFP */
复制代码 定时器配置:- /* USER CODE BEGIN 2 */
- HAL_TIM_Base_Start_IT(&htim1);//启动定时器
- HAL_TIM_IC_Start_IT(&htim1,TIM_CHANNEL_2);//函数用于使能定时器某一通道的输入捕获功能,并使能相应的中断
- printf("IR Capture !! \r\n");
- /* USER CODE END 2 *
复制代码 红外接收代码[4400,5000]是用于捕获4.5ms的信号[550,700]是用于捕获560us的数据0信号[1100,1250]是用于捕获1120us的数据1信号[2000,2500]是用于捕获2240us的截止位信号- /* USER CODE BEGIN 4 */
- // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
- void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
- {
- uint32_t fallingCount = 0 ; // 下降沿计数
- uint8_t temp = 0 ;
- // 判断是否是定时器1的外部捕获口2
- if(htim->Instance == TIM1)
- {
- // 捕获到了上升沿
- if(IR_IN1)
- {
- __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_FALLING); // 改变捕获极性为下降沿捕获
- __HAL_TIM_SET_COUNTER(htim, 0); // 计数清零,从头开始计
- }
- else
- {
- fallingCount = HAL_TIM_ReadCapturedValue(htim,TIM_CHANNEL_2); // 读取捕获计数,这个时间即为上升沿持续的时间
- __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_2, TIM_INPUTCHANNELPOLARITY_RISING); // 改变捕获极性为上升沿捕获
- if( ((fallingCount > 4400) && (fallingCount <5000)))
- OK = 1;/// 4.5ms引导电平
- else if (((fallingCount > 550) && (fallingCount < 700)))
- {
- temp = 0;//560 us,数据为0
- }
- else if (((fallingCount > 1100) && (fallingCount < 1250)))
- {
- temp = 1;//1120 us,数据为1
- }
- else if (ReadyFlag==0&& ((fallingCount > 2000) && (fallingCount < 2500))) //2.240ms截止码
- {
- ReadyFlag = 1 ;
- OK = 0;
- }
- if(OK)
- {
- OrderData <<= 1 ;
- OrderData += temp ;
- KeyCount = 0; // 按键次数
- }
- }
- }
- }
- /* USER CODE END 4 */
复制代码 主函数。- /* USER CODE BEGIN WHILE */
- while (1)
- {
- /* USER CODE END WHILE */
- /* USER CODE BEGIN 3 */
- if(ReadyFlag)
- {
- printf("order=%08X , code=%d\r\n",OrderData,OrderData);
- OrderData = 0;
- OK = 0;
- ReadyFlag = 0;
- }
- }
复制代码演示效果 红外连续发送5次码值,发送分别为:1011(11)11 1010(58)11 0001(49)11 1111(63)11 0011(51) 分别如下所示: |