/** Copyright (c) 2006-2018, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2018-08-26 balanceTWK the first version*/#ifndef__DRV_INFRARED_H__#define__DRV_INFRARED_H__intdrv_infrared_init(void);#endif
drv_infrared 源文件
/** Copyright (c) 2006-2019, RT-Thread Development Team** SPDX-License-Identifier: Apache-2.0** Change Logs:* Date Author Notes* 2019-03-25 balanceTWK the first version*/#include"drv_hwtimer.h"#include"infrared.h"#include"drv_infrared.h"staticstructinfrared_class* infrared;#ifdefINFRARED_SEND/* Infrared transmission configuration parameters */#definePWM_DEV_NAMEINFRARED_SEND_PWM /* PWM name */#definePWM_DEV_CHANNELINFRARED_PWM_DEV_CHANNEL#defineSEND_HWTIMERINFRARED_SEND_HWTIMER /* Timer name */#defineMAX_SEND_SIZEINFRARED_MAX_SEND_SIZEstructrt_device_pwm*pwm_dev;staticrt_uint32_t infrared_send_buf[MAX_SEND_SIZE];staticrt_device_t send_time_dev ;staticrt_hwtimerval_t timeout_s;staticrt_err_tsend_timeout_callback(rt_device_t dev,rt_size_t size){staticrt_size_t i =0;rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL);if((infrared_send_buf[i]!=0x5A5A5A5A))/* Determine if it is a stop bit */{if((infrared_send_buf[i]&0xF0000000)==0xA0000000)/* Determine if it is a carrier signal */{rt_pwm_enable(pwm_dev, PWM_DEV_CHANNEL);}timeout_s.sec =0;timeout_s.usec =(infrared_send_buf[i]&0x0FFFFFFF);/* Get the delay time */rt_device_write(send_time_dev,0,&timeout_s,sizeof(timeout_s));i++;}else{i =0;}return0;}rt_err_tinfrared_send_init(void){rt_err_t ret = RT_EOK;rt_hwtimer_mode_t mode;rt_uint32_t freq =1000000;pwm_dev =(structrt_device_pwm*)rt_device_find(PWM_DEV_NAME);if(pwm_dev == RT_NULL){LOG_E("pwm sample run failed! can't find %s device!", PWM_DEV_NAME);return RT_ERROR;}rt_pwm_set(pwm_dev, PWM_DEV_CHANNEL,26316,8770);rt_pwm_disable(pwm_dev, PWM_DEV_CHANNEL);send_time_dev =rt_device_find(SEND_HWTIMER);if(send_time_dev == RT_NULL){LOG_E("hwtimer sample run failed! can't find %s device!", SEND_HWTIMER);return RT_ERROR;}ret =rt_device_open(send_time_dev, RT_DEVICE_OFLAG_RDWR);if(ret != RT_EOK){LOG_E("open %s device failed!\n", SEND_HWTIMER);return ret;}rt_device_set_rx_indicate(send_time_dev, send_timeout_callback);ret =rt_device_control(send_time_dev, HWTIMER_CTRL_FREQ_SET,&freq);if(ret != RT_EOK){LOG_E("set frequency failed! ret is :%d", ret);return ret;}mode = HWTIMER_MODE_ONESHOT;ret =rt_device_control(send_time_dev, HWTIMER_CTRL_MODE_SET,&mode);if(ret != RT_EOK){LOG_E("set mode failed! ret is :%d", ret);return ret;}return ret;}staticrt_size_tinfrared_send(structir_raw_data* data,rt_size_t size){rt_size_t send_size;if(size >= MAX_SEND_SIZE){LOG_E("The length of the sent data exceeds the MAX_SEND_SIZE.");return0;}for(send_size =0; send_size < size; send_size++){infrared_send_buf[send_size]=(data[send_size].level<<28)+(data[send_size].us);}infrared_send_buf[size]=0x5A5A5A5A;timeout_s.sec =0;timeout_s.usec =500;rt_device_write(send_time_dev,0,&timeout_s,sizeof(timeout_s));rt_thread_mdelay(100);return send_size;}#endif/* INFRARED_SEND */#ifdefINFRARED_RECEIVE#defineRECEIVE_HWTIMEER_SEC0#defineRECEIVE_HWTIMEER_USEC1000000staticuint32_t diff_us;staticuint32_t receive_flag =0x00000000;staticstructrt_hwtimer_device* receive_time_dev =NULL;voidreceive_pin_callback(void){staticrt_hwtimerval_t receive_time;staticuint32_t last_us =0, now_us;if((receive_flag &(1<<0))){rt_hwtimer_read(receive_time_dev,&receive_time);now_us =(receive_time.sec *1000000)+ receive_time.usec;if(now_us >= last_us){diff_us = now_us - last_us;}else{diff_us = now_us + RECEIVE_HWTIMEER_SEC *1000000+ RECEIVE_HWTIMEER_USEC;}if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_8)== GPIO_PIN_SET){driver_report_raw_data(CARRIER_WAVE, diff_us);LOG_D("H%d", diff_us);}else{driver_report_raw_data(IDLE_SIGNAL, diff_us);LOG_D("L%d", diff_us);}last_us = now_us;}else{receive_time.sec = RECEIVE_HWTIMEER_SEC;receive_time.usec = RECEIVE_HWTIMEER_USEC;rt_hwtimer_write(receive_time_dev,&receive_time);receive_flag |=1<<0;last_us =0;LOG_D("Start timer");}}staticintreceive_timeout_callback(rt_hwtimer_t* rt_hwtimer){if(diff_us >(1000*1000)){rt_hwtimer_control(receive_time_dev, HWTIMER_CTRL_STOP,NULL);LOG_D("timeout and stop");receive_flag &=~(1<<0);}diff_us = diff_us + RECEIVE_HWTIMEER_SEC *1000000+ RECEIVE_HWTIMEER_USEC;return0;}intinfrared_receive_init(void){rt_hwtimer_mode_t mode;uint32_t freq =100000;// 红外接收IO 初始化// 接收定时器初始化receive_time_dev =stm32_hwtimer_get(TIM14_INDEX);if(receive_time_dev ==NULL){LOG_E("hwtimer sample run failed! can't find %s device!", RECEIVE_HWTIMER);return1;}rt_hwtimer_init(receive_time_dev);rt_hwtimer_open(receive_time_dev);receive_time_dev->rx_indicate = receive_timeout_callback;rt_hwtimer_control(receive_time_dev, HWTIMER_CTRL_FREQ_SET,&freq);mode = HWTIMER_MODE_PERIOD;rt_hwtimer_control(receive_time_dev, HWTIMER_CTRL_MODE_SET,&mode);return0;}#endif/* INFRARED_RECEIVE */intdrv_infrared_init(){infrared =infrared_init();if(infrared ==NULL){return-1;}#ifdefINFRARED_SENDinfrared_send_init();infrared->send = infrared_send;#endif/* INFRARED_SEND */#ifdefINFRARED_RECEIVEinfrared_receive_init();#endif/* INFRARED_RECEIVE */return0;}
测试
主函数
/* USER CODE BEGIN Header *//********************************************************************************* @file : main.c* @brief : Main program body******************************************************************************* @attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include"main.h"#include"dma.h"#include"tim.h"#include"usart.h"#include"gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include"infrared.h"#include"drv_hwtimer.h"#include"nec_decoder.h"#include"drv_infrared.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/voidSystemClock_Config(void);/* USER CODE BEGIN PFP */staticvoidinfrared_test(void);/* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 */intreceive_timeout_callback(rt_hwtimer_t* rt_hwtimer){printf("%d\r\n",HAL_GetTick());return0;}/* USER CODE END 0 *//*** @brief The application entry point.* @retval int*/intmain(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_DMA_Init();MX_USART1_UART_Init();MX_TIM14_Init();/* USER CODE BEGIN 2 */// 开启串口dma接收usart1_open_receive();stm32_hwtimer_init();infrared_test();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_Delay(1000);}/* USER CODE END 3 */}/*** @brief System Clock Configuration* @retval None*/voidSystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct ={0};RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};/** Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/** Initializes the RCC Oscillators according to the specified parameters* in the RCC_OscInitTypeDef structure.*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM =4;RCC_OscInitStruct.PLL.PLLN =168;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ =4;if(HAL_RCC_OscConfig(&RCC_OscInitStruct)!= HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5)!= HAL_OK){Error_Handler();}}/* USER CODE BEGIN 4 */staticvoidinfrared_test(void){nec_decoder_register();drv_infrared_init();structinfrared_decoder_data infrared_data;ir_select_decoder("nec");while(1){/* 读取数据 */if(infrared_read("nec",&infrared_data)==0){if(infrared_data.data.nec.repeat){printf("repeat%d\r\n", infrared_data.data.nec.repeat);}else{printf("APP addr:0x%02X key:0x%02X\r\n", infrared_data.data.nec.addr, infrared_data.data.nec.key);}}// HAL_Delay(10);__WFI();}}/* USER CODE END 4 *//*** @brief This function is executed in case of error occurrence.* @retval None*/voidError_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while(1){}/* USER CODE END Error_Handler_Debug */}#ifdefUSE_FULL_ASSERT/*** @brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* @param file: pointer to the source file name* @param line: assert_param error line source number* @retval None*/voidassert_failed(uint8_t*file,uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) *//* USER CODE END 6 */}#endif/* USE_FULL_ASSERT */