RT-Thread Studio学习二HWTIMER简介新建项目并使用外部时钟启用HWTIMER测试简介本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用HWTIMER设备。新建项目并使用外部时钟打开RT-Thread Studio软件新建基于芯片的项目并使用外部时钟系统具体参见《RT-Thread Studio学习之使用外部时钟系统》启用HWTIMER根据board.h文件中的描述启用HWTIMER需要完成如下四个步骤/*-------------------------- HARDWARE TIMER CONFIG BEGIN --------------------------*//** if you want to use hardware timer you can use the following instructions. * * STEP 1, open hwtimer driver framework support in the RT-Thread Settings file * * STEP 2, define macro related to the hwtimer * such as #define BSP_USING_TIM and * #define BSP_USING_TIM1 * * STEP 3, copy your hardwire timer init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file * such as void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base) * * STEP 4, modify your stm32xxxx_hal_config.h file to support hardwere timer peripherals. define macro related to the peripherals * such as #define HAL_TIM_MODULE_ENABLED * */打开HWTIMER驱动框架在RT-Thread Setting文件中借助图形化配置工具打开软件 HWTIMER的驱动框架如下图所示定义HWTIMER相关的宏在board.h中定义需要使用的定时器#defineBSP_USING_TIM#ifdefBSP_USING_TIM#defineBSP_USING_TIM1#defineBSP_USING_TIM10/*#define BSP_USING_TIM15*//*#define BSP_USING_TIM16*//*#define BSP_USING_TIM17*/#endif复制HWTIMER初始化函数打开STM32CubeMX软件根据实际情况完成对应TIM的配置。在本文中使用了TIM1和TIM10,这两个TIM的Clock Source都使用Internal Clock具体如下图从生成后的工程文件stm32xxxx_hal_msp.c中复制函数void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)到board.c的末尾。voidHAL_TIM_Base_MspInit(TIM_HandleTypeDef*htim_base){GPIO_InitTypeDef GPIO_InitStruct{0};if(htim_base-InstanceTIM1){/* USER CODE BEGIN TIM1_MspInit 0 *//* USER CODE END TIM1_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_TIM1_CLK_ENABLE();__HAL_RCC_GPIOE_CLK_ENABLE();/**TIM1 GPIO Configuration PE9 ------ TIM1_CH1 */GPIO_InitStruct.PinGPIO_PIN_9;GPIO_InitStruct.ModeGPIO_MODE_AF_PP;GPIO_InitStruct.PullGPIO_NOPULL;GPIO_InitStruct.SpeedGPIO_SPEED_FREQ_LOW;GPIO_InitStruct.AlternateGPIO_AF1_TIM1;HAL_GPIO_Init(GPIOE,GPIO_InitStruct);/* USER CODE BEGIN TIM1_MspInit 1 *//* USER CODE END TIM1_MspInit 1 */}elseif(htim_base-InstanceTIM10){/* USER CODE BEGIN TIM10_MspInit 0 *//* USER CODE END TIM10_MspInit 0 *//* Peripheral clock enable */__HAL_RCC_TIM10_CLK_ENABLE();/* USER CODE BEGIN TIM10_MspInit 1 *//* USER CODE END TIM10_MspInit 1 */}}定义stm32xxxx_hal_config.h中的相关宏在stm32f4xx_hal_conf.h中定义需要使用的模块#defineHAL_TIM_MODULE_ENABLED另外还需要修改tim_config.h和drv_hwtimer.c文件。项目中tim_config.h文件的路径为drivers\include\config\tim_config.h完整代码如下/* * Copyright (c) 2006-2018, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2018-12-11 zylx first version */#ifndef__TIM_CONFIG_H__#define__TIM_CONFIG_H__#includertthread.h#ifdef__cplusplusexternC{#endif#ifndefTIM_DEV_INFO_CONFIG#defineTIM_DEV_INFO_CONFIG\{\.maxfreq1000000,\.minfreq3000,\.maxcnt0xFFFF,\.cntmodeHWTIMER_CNTMODE_UP,\}#endif/* TIM_DEV_INFO_CONFIG */#ifdefBSP_USING_TIM1#ifndefTIM1_CONFIG#defineTIM1_CONFIG\{\.tim_handle.InstanceTIM1,\.tim_irqnTIM1_UP_TIM10_IRQn,\.nametimer1,\}#endif/* TIM11_CONFIG */#endif/* BSP_USING_TIM11 */#ifdefBSP_USING_TIM10#ifndefTIM10_CONFIG#defineTIM10_CONFIG\{\.tim_handle.InstanceTIM10,\.tim_irqnTIM1_UP_TIM10_IRQn,\.nametimer10,\}#endif/* TIM10_CONFIG */#endif/* BSP_USING_TIM10 */#ifdefBSP_USING_TIM3#ifndefTIM3_CONFIG#defineTIM3_CONFIG\{\.tim_handle.InstanceTIM3,\.tim_irqnTIM3_IRQn,\.nametimer3,\}#endif/* TIM3_CONFIG */#endif/* BSP_USING_TIM3 */#ifdefBSP_USING_TIM11#ifndefTIM11_CONFIG#defineTIM11_CONFIG\{\.tim_handle.InstanceTIM11,\.tim_irqnTIM1_TRG_COM_TIM11_IRQn,\.nametimer11,\}#endif/* TIM11_CONFIG */#endif/* BSP_USING_TIM11 */#ifdefBSP_USING_TIM13#ifndefTIM13_CONFIG#defineTIM13_CONFIG\{\.tim_handle.InstanceTIM13,\.tim_irqnTIM8_UP_TIM13_IRQn,\.nametimer13,\}#endif/* TIM13_CONFIG */#endif/* BSP_USING_TIM13 */#ifdefBSP_USING_TIM14#ifndefTIM14_CONFIG#defineTIM14_CONFIG\{\.tim_handle.InstanceTIM14,\.tim_irqnTIM8_TRG_COM_TIM14_IRQn,\.nametimer14,\}#endif/* TIM14_CONFIG */#endif/* BSP_USING_TIM14 */#ifdef__cplusplus}#endif#endif/* __TIM_CONFIG_H__ */修改drv_hwtimer.h文件注释掉drv_hwtimer.c中的#include drv_config.h。向drv_hwtimer.c添加#include rtdevice.h。向drv_hwtimer.c添加#include tim_config.h。修改drv_hwtimer.c中HAL_TIM_PeriodElapsedCallback为使用的定时器添加回调函数voidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef*htim){#ifdefBSP_USING_TIM1if(htim-InstanceTIM1){rt_device_hwtimer_isr(stm32_hwtimer_obj[TIM1_INDEX].time_device);}#endif......#ifdefBSP_USING_TIM10if(htim-InstanceTIM10){rt_device_hwtimer_isr(stm32_hwtimer_obj[TIM10_INDEX].time_device);}#endif......}添加中断函数入口#ifdefined(BSP_USING_TIM1)||defined(BSP_USING_TIM10)voidTIM1_UP_TIM10_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();#ifdefBSP_USING_TIM1if(__HAL_TIM_GET_FLAG(stm32_hwtimer_obj[TIM1_INDEX].tim_handle,TIM_IT_UPDATE)!RESET)HAL_TIM_IRQHandler(stm32_hwtimer_obj[TIM1_INDEX].tim_handle);#endif#ifdefBSP_USING_TIM10if(__HAL_TIM_GET_FLAG(stm32_hwtimer_obj[TIM10_INDEX].tim_handle,TIM_IT_UPDATE)!RESET)HAL_TIM_IRQHandler(stm32_hwtimer_obj[TIM10_INDEX].tim_handle);#endif/* leave interrupt */rt_interrupt_leave();}#endif测试main.c测试代码如下/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2021-01-16 RT-Thread first version */#includertthread.h#includestdlib.h#includertdevice.h#includedrv_common.h#defineDBG_TAGmain#defineDBG_LVLDBG_LOG#includertdbg.h#defineLED_PINGET_PIN(F,9)#defineLED0_PINGET_PIN(F,10)staticintrt_hw_pin_init(){rt_pin_mode(LED_PIN,PIN_MODE_OUTPUT);rt_pin_mode(LED0_PIN,PIN_MODE_OUTPUT);return0;}INIT_BOARD_EXPORT(rt_hw_pin_init);/* 定时器超时回调函数 */staticrt_err_ttimeout_cb1(rt_device_tdev,rt_size_tsize){staticinti0;i;rt_pin_write(LED_PIN,i%2);return0;}staticinthw1timer_sample(intargc,char*argv[]){rt_err_tretRT_EOK;rt_hwtimerval_ttimeout_s;/* 定时器超时值 */rt_device_thw_devRT_NULL;/* 定时器设备句柄 */rt_hwtimer_mode_tmode;/* 定时器模式 *//* 查找定时器设备 */hw_devrt_device_find(timer1);/* 以读写方式打开设备 */retrt_device_open(hw_dev,RT_DEVICE_OFLAG_RDWR);/* 设置超时回调函数 */rt_device_set_rx_indicate(hw_dev,timeout_cb1);/* 设置模式为周期性定时器 */modeHWTIMER_MODE_PERIOD;retrt_device_control(hw_dev,HWTIMER_CTRL_MODE_SET,mode);/* 设置定时器超时值为2s并启动定时器 */timeout_s.sec2;/* 秒 */timeout_s.usec0;/* 微秒 */if(rt_device_write(hw_dev,0,timeout_s,sizeof(timeout_s))!sizeof(timeout_s)){rt_kprintf(set timeout value failed\n);returnRT_ERROR;}returnret;}MSH_CMD_EXPORT(hw1timer_sample,hw1timer_sample);intmain(void){intcount1;while(count){/* set LED0 pin level to high or low */rt_pin_write(LED0_PIN,count%2);// LOG_D(Hello RT-Thread!);rt_thread_mdelay(1000);}returnRT_EOK;}通过msh运行hw1timer_sample即可看到效果。