/*
* 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 */