/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 24-8-4 shchl first version
*/#ifndefTHREADX_F407ZGT6_HWTIMER_H#defineTHREADX_F407ZGT6_HWTIMER_Hstructrt_hwtimer_device;/* Timer Control Command */typedefenum{
HWTIMER_CTRL_FREQ_SET,/* set the count frequency */
HWTIMER_CTRL_STOP,/* stop timer */
HWTIMER_CTRL_INFO_GET,/* get a timer feature information */
HWTIMER_CTRL_MODE_SET /* Setting the timing mode(oneshot/period) */}rt_hwtimer_ctrl_t;/* Timing Mode */typedefenum{
HWTIMER_MODE_ONESHOT =0x01,
HWTIMER_MODE_PERIOD
}rt_hwtimer_mode_t;/* Time Value */typedefstructrt_hwtimerval{int32_t sec;/* second */int32_t usec;/* microsecond */}rt_hwtimerval_t;#defineHWTIMER_CNTMODE_UP0x01/* increment count mode */#defineHWTIMER_CNTMODE_DW0x02/* decreasing count mode *//* Timer Feature Information */structrt_hwtimer_info{int32_t maxfreq;/* the maximum count frequency timer support */int32_t minfreq;/* the minimum count frequency timer support */uint32_t maxcnt;/* counter maximum value */uint8_t cntmode;/* count mode (inc/dec) */};structrt_hwtimer_ops{void(*init)(structrt_hwtimer_device*timer,uint32_t state);int8_t(*start)(structrt_hwtimer_device*timer,uint32_t cnt,rt_hwtimer_mode_t mode);void(*stop)(structrt_hwtimer_device*timer);uint32_t(*count_get)(structrt_hwtimer_device*timer);int8_t(*control)(structrt_hwtimer_device*timer,uint32_t cmd,void*args);};typedefstructrt_hwtimer_device{conststructrt_hwtimer_ops*ops;conststructrt_hwtimer_info*info;int32_t freq;/* counting frequency set by the user */int32_t overflow;/* timer overflows */float period_sec;int32_t cycles;/* how many times will generate a timeout event after overflow */int32_t reload;/* reload cycles(using in period mode) */rt_hwtimer_mode_t mode;/* timing mode(oneshot/period) */int8_t(*rx_indicate)(structrt_hwtimer_device*dev);void*user_data;}rt_hwtimer_t;int8_trt_hwtimer_init(rt_hwtimer_t*timer);int8_trt_hwtimer_open(rt_hwtimer_t*timer);int8_trt_hwtimer_close(rt_hwtimer_t*timer);size_trt_hwtimer_read(rt_hwtimer_t*timer,rt_hwtimerval_t*buffer);size_trt_hwtimer_write(rt_hwtimer_t*timer,rt_hwtimerval_t*buffer);int8_trt_hwtimer_control(rt_hwtimer_t*timer,int cmd,void*args);voidrt_device_hwtimer_isr(rt_hwtimer_t*timer);int8_trt_device_hwtimer_init(rt_hwtimer_t*timer,constchar*name,void*user_data);rt_hwtimer_t*rt_hwtimer_get_device(constchar*name);#endif//THREADX_F407ZGT6_HWTIMER_H
源文件
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 24-8-4 shchl first version
*/#include"bsp.h"#include"hwtimer.h"staticuint32_ttimeout_calc(rt_hwtimer_t*timer,rt_hwtimerval_t*tv){float overflow;float timeout;uint32_t counter;int i, index =0;float tv_sec;float devi_min =1;float devi;/* changed to second */
overflow = timer->info->maxcnt /(float) timer->freq;
tv_sec = tv->sec + tv->usec /(float)1000000;if(tv_sec <(1/(float) timer->freq)){/* little timeout */
i =0;
timeout =1/(float) timer->freq;}else{for(i =1; i >0; i++){
timeout = tv_sec / i;if(timeout <= overflow){
counter =(uint32_t)(timeout * timer->freq);
devi = tv_sec -(counter /(float) timer->freq)* i;/* Minimum calculation error */if(devi > devi_min){
i = index;
timeout = tv_sec / i;break;}elseif(devi ==0){break;}elseif(devi < devi_min){
devi_min = devi;
index = i;}}}}
timer->cycles = i;
timer->reload = i;
timer->period_sec = timeout;
counter =(uint32_t)(timeout * timer->freq);return counter;}int8_trt_hwtimer_init(rt_hwtimer_t*timer){int8_t result =0;/* try to change to 1MHz */if((1000000<= timer->info->maxfreq)&&(1000000>= timer->info->minfreq)){
timer->freq =1000000;}else{
timer->freq = timer->info->minfreq;}
timer->mode = HWTIMER_MODE_ONESHOT;
timer->cycles =0;
timer->overflow =0;if(timer->ops->init){
timer->ops->init(timer,1);}else{
result =-1;}return result;}int8_trt_hwtimer_open(rt_hwtimer_t*timer){int8_t result =0;if(timer->ops->control !=NULL){
timer->ops->control(timer, HWTIMER_CTRL_FREQ_SET,&timer->freq);}else{
result =-1;}return result;}int8_trt_hwtimer_close(rt_hwtimer_t*timer){int8_t result =0;if(timer->ops->init !=NULL){
timer->ops->init(timer,0);}else{
result =-1;}
timer->rx_indicate =NULL;return result;}size_trt_hwtimer_read(rt_hwtimer_t*timer,rt_hwtimerval_t*buffer){rt_hwtimerval_t tv;uint32_t cnt;
BSP_DEF_CRITICAL_SECTION;int32_t overflow;float t;if(timer->ops->count_get ==NULL)return0;
BSP_ENTER_CRITICAL;
cnt = timer->ops->count_get(timer);
overflow = timer->overflow;
BSP_EXIT_CRITICAL;if(timer->info->cntmode == HWTIMER_CNTMODE_DW){
cnt =(uint32_t)(timer->freq * timer->period_sec)- cnt;}if(timer->mode == HWTIMER_MODE_ONESHOT){
overflow =0;}
t = overflow * timer->period_sec + cnt /(float) timer->freq;
tv.sec =(int32_t) t;
tv.usec =(int32_t)((t - tv.sec)*1000000);memcpy(buffer,&tv,sizeof(tv));returnsizeof(tv);}size_trt_hwtimer_write(rt_hwtimer_t*timer,rt_hwtimerval_t*buffer){
BSP_DEF_CRITICAL_SECTION;uint32_t t;rt_hwtimer_mode_t opm = HWTIMER_MODE_PERIOD;if((timer->ops->start ==NULL)||(timer->ops->stop ==NULL))return0;
timer->ops->stop(timer);
BSP_ENTER_CRITICAL;
timer->overflow =0;
BSP_EXIT_CRITICAL;
t =timeout_calc(timer, buffer);if((timer->cycles <=1)&&(timer->mode == HWTIMER_MODE_ONESHOT)){
opm = HWTIMER_MODE_ONESHOT;}if(timer->ops->start(timer, t, opm)!=0)return0;returnsizeof(rt_hwtimerval_t);}int8_trt_hwtimer_control(rt_hwtimer_t*timer,int cmd,void*args){
BSP_DEF_CRITICAL_SECTION
int8_t result =0;switch(cmd){case HWTIMER_CTRL_STOP:{if(timer->ops->stop !=NULL){
timer->ops->stop(timer);}else{
result =-1;}}break;case HWTIMER_CTRL_FREQ_SET:{int32_t*f;if(args ==NULL){
result =-2;break;}
f =(int32_t*) args;if((*f > timer->info->maxfreq)||(*f < timer->info->minfreq)){// bsp_d_log("frequency setting out of range! It will maintain at %d Hz", timer->freq);
result =-3;break;}if(timer->ops->control !=NULL){
result = timer->ops->control(timer, cmd, args);if(result ==0){
BSP_ENTER_CRITICAL;
timer->freq =*f;
BSP_EXIT_CRITICAL;}}else{
result =-1;}}break;case HWTIMER_CTRL_INFO_GET:{if(args ==NULL){
result =-2;break;}*((structrt_hwtimer_info*) args)=*timer->info;}break;case HWTIMER_CTRL_MODE_SET:{rt_hwtimer_mode_t*m;if(args ==NULL){
result =-2;break;}
m =(rt_hwtimer_mode_t*) args;if((*m != HWTIMER_MODE_ONESHOT)&&(*m != HWTIMER_MODE_PERIOD)){
result =-2;break;}
BSP_ENTER_CRITICAL
timer->mode =*m;
BSP_EXIT_CRITICAL
}break;default:{
result =-3;}break;}return result;}voidrt_device_hwtimer_isr(rt_hwtimer_t*timer){
BSP_DEF_CRITICAL_SECTION;assert_param(timer != RT_NULL);
BSP_ENTER_CRITICAL;
timer->overflow++;if(timer->cycles !=0){
timer->cycles--;}if(timer->cycles ==0){
timer->cycles = timer->reload;
BSP_ENTER_CRITICAL;if(timer->mode == HWTIMER_MODE_ONESHOT){if(timer->ops->stop !=NULL){
timer->ops->stop(timer);}}if(timer->rx_indicate !=NULL){
timer->rx_indicate(timer);}}else{
BSP_EXIT_CRITICAL;}}int8_trt_device_hwtimer_init(rt_hwtimer_t*timer,constchar*name,void*user_data){
timer->user_data = user_data;return0;}
bsp_hwtimer驱动部分
头文件
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 24-8-4 shchl first version
*/#ifndefTHREADX_F407ZGT6_BSP_HWTIMER_H#defineTHREADX_F407ZGT6_BSP_HWTIMER_H#include"hwtimer/hwtimer.h"#defineTIM_DEV_INFO_CONFIG\{\.maxfreq =1000000,\.minfreq =3000,\.maxcnt =0xFFFF,\.cntmode = HWTIMER_CNTMODE_UP,\}#defineTIM13_CONFIG\{\.tim_handle.Instance = TIM13,\.tim_irqn = TIM8_UP_TIM13_IRQn,\.name ="timer13",\}#defineBSP_USING_TIM13intbsp_hwtimer_init(void);#endif//THREADX_F407ZGT6_BSP_HWTIMER_H
源文件
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-12-10 zylx first version
* 2020-06-16 thread-liu Porting for stm32mp1
* 2020-08-25 linyongkang Fix the timer clock frequency doubling problem
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
*/#include"bsp.h"#include"bsp_hwtimer.h"enum{#ifdefBSP_USING_TIM1
TIM1_INDEX,#endif#ifdefBSP_USING_TIM2
TIM2_INDEX,#endif#ifdefBSP_USING_TIM3
TIM3_INDEX,#endif#ifdefBSP_USING_TIM4
TIM4_INDEX,#endif#ifdefBSP_USING_TIM5
TIM5_INDEX,#endif#ifdefBSP_USING_TIM6
TIM6_INDEX,#endif#ifdefBSP_USING_TIM7
TIM7_INDEX,#endif#ifdefBSP_USING_TIM8
TIM8_INDEX,#endif#ifdefBSP_USING_TIM9
TIM9_INDEX,#endif#ifdefBSP_USING_TIM10
TIM10_INDEX,#endif#ifdefBSP_USING_TIM11
TIM11_INDEX,#endif#ifdefBSP_USING_TIM12
TIM12_INDEX,#endif#ifdefBSP_USING_TIM13
TIM13_INDEX,#endif#ifdefBSP_USING_TIM14
TIM14_INDEX,#endif};structstm32_hwtimer{rt_hwtimer_t time_device;
TIM_HandleTypeDef tim_handle;
IRQn_Type tim_irqn;char*name;};staticstructstm32_hwtimer stm32_hwtimer_obj[]={#ifdefBSP_USING_TIM1
TIM1_CONFIG,#endif#ifdefBSP_USING_TIM2
TIM2_CONFIG,#endif#ifdefBSP_USING_TIM3
TIM3_CONFIG,#endif#ifdefBSP_USING_TIM4
TIM4_CONFIG,#endif#ifdefBSP_USING_TIM5
TIM5_CONFIG,#endif#ifdefBSP_USING_TIM6
TIM6_CONFIG,#endif#ifdefBSP_USING_TIM7
TIM7_CONFIG,#endif#ifdefBSP_USING_TIM8
TIM8_CONFIG,#endif#ifdefBSP_USING_TIM9
TIM9_CONFIG,#endif#ifdefBSP_USING_TIM10
TIM10_CONFIG,#endif#ifdefBSP_USING_TIM11
TIM11_CONFIG,#endif#ifdefBSP_USING_TIM12
TIM12_CONFIG,#endif#ifdefBSP_USING_TIM13
TIM13_CONFIG,#endif#ifdefBSP_USING_TIM14
TIM14_CONFIG,#endif#ifdefBSP_USING_TIM15
TIM15_CONFIG,#endif#ifdefBSP_USING_TIM16
TIM16_CONFIG,#endif#ifdefBSP_USING_TIM17
TIM17_CONFIG,#endif};/* APBx timer clocks frequency doubler state related to APB1CLKDivider value */staticvoidpclkx_doubler_get(uint32_t*pclk1_doubler,uint32_t*pclk2_doubler){uint32_t flatency =0;
RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};assert_param(pclk1_doubler != ULL);assert_param(pclk1_doubler !=NULL);HAL_RCC_GetClockConfig(&RCC_ClkInitStruct,(uint32_t*)&flatency);*pclk1_doubler =1;*pclk2_doubler =1;#ifdefined(SOC_SERIES_STM32MP1)if(RCC_ClkInitStruct.APB1_Div != RCC_APB1_DIV1){*pclk1_doubler =2;}if(RCC_ClkInitStruct.APB2_Div != RCC_APB2_DIV1){*pclk2_doubler =2;}#elseif(RCC_ClkInitStruct.APB1CLKDivider != RCC_HCLK_DIV1){*pclk1_doubler =2;}#if!defined(SOC_SERIES_STM32F0)&&!defined(SOC_SERIES_STM32G0)if(RCC_ClkInitStruct.APB2CLKDivider != RCC_HCLK_DIV1){*pclk2_doubler =2;}#endif#endif}staticvoidtimer_init(structrt_hwtimer_device*timer,uint32_t state){uint32_t prescaler_value =0;uint32_t pclk1_doubler, pclk2_doubler;
TIM_HandleTypeDef *tim =NULL;structstm32_hwtimer*tim_device =NULL;assert_param(timer !=NULL);if(state){
tim =(TIM_HandleTypeDef *) timer->user_data;
tim_device =(structstm32_hwtimer*) timer;pclkx_doubler_get((uint32_t*)&pclk1_doubler,(uint32_t*)&pclk2_doubler);/* time init */if(tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11){
prescaler_value =(uint32_t)(HAL_RCC_GetPCLK2Freq()* pclk2_doubler /10000)-1;}else{
prescaler_value =(uint32_t)(HAL_RCC_GetPCLK1Freq()* pclk1_doubler /10000)-1;}
tim->Init.Period =10000-1;
tim->Init.Prescaler = prescaler_value;
tim->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;if(timer->info->cntmode == HWTIMER_CNTMODE_UP){
tim->Init.CounterMode = TIM_COUNTERMODE_UP;}else{
tim->Init.CounterMode = TIM_COUNTERMODE_DOWN;}
tim->Init.RepetitionCounter =0;if(HAL_TIM_Base_Init(tim)!= HAL_OK){printf("%s init failed", tim_device->name);return;}else{/* set the TIMx priority */HAL_NVIC_SetPriority(tim_device->tim_irqn,3,0);/* enable the TIMx global Interrupt */HAL_NVIC_EnableIRQ(tim_device->tim_irqn);/* clear update flag */__HAL_TIM_CLEAR_FLAG(tim, TIM_FLAG_UPDATE);/* enable update request source */__HAL_TIM_URS_ENABLE(tim);printf("%s init success", tim_device->name);}}}staticint8_ttimer_start(rt_hwtimer_t*timer,uint32_t t,rt_hwtimer_mode_t opmode){int8_t result =0;
TIM_HandleTypeDef *tim =NULL;assert_param(timer !=NULL);
tim =(TIM_HandleTypeDef *) timer->user_data;/* set tim cnt */__HAL_TIM_SET_COUNTER(tim,0);/* set tim arr */__HAL_TIM_SET_AUTORELOAD(tim, t -1);if(opmode == HWTIMER_MODE_ONESHOT){/* set timer to single mode */
tim->Instance->CR1 |= TIM_OPMODE_SINGLE;}else{
tim->Instance->CR1 &=(~TIM_OPMODE_SINGLE);}/* start timer */if(HAL_TIM_Base_Start_IT(tim)!= HAL_OK){printf("TIM start failed");
result =-1;}return result;}staticvoidtimer_stop(rt_hwtimer_t*timer){
TIM_HandleTypeDef *tim =NULL;assert_param(timer !=NULL);
tim =(TIM_HandleTypeDef *) timer->user_data;/* stop timer */HAL_TIM_Base_Stop_IT(tim);/* set tim cnt */__HAL_TIM_SET_COUNTER(tim,0);}staticint8_ttimer_ctrl(rt_hwtimer_t*timer,uint32_t cmd,void*arg){
TIM_HandleTypeDef *tim =NULL;int8_t result =0;uint32_t pclk1_doubler, pclk2_doubler;assert_param(timer !=NULL);assert_param(arg !=NULL);
tim =(TIM_HandleTypeDef *) timer->user_data;switch(cmd){case HWTIMER_CTRL_FREQ_SET:{uint32_t freq;uint16_t val;/* set timer frequence */
freq =*((uint32_t*) arg);pclkx_doubler_get((uint32_t*)&pclk1_doubler,(uint32_t*)&pclk2_doubler);if(tim->Instance == TIM9 || tim->Instance == TIM10 || tim->Instance == TIM11){
val =HAL_RCC_GetPCLK2Freq()* pclk2_doubler / freq;}else{
val =HAL_RCC_GetPCLK1Freq()* pclk1_doubler / freq;}__HAL_TIM_SET_PRESCALER(tim, val -1);/* Update frequency value */
tim->Instance->EGR |= TIM_EVENTSOURCE_UPDATE;}break;default:{
result =-1;}break;}return result;}staticuint32_ttimer_counter_get(rt_hwtimer_t*timer){
TIM_HandleTypeDef *tim =NULL;assert_param(timer !=NULL);
tim =(TIM_HandleTypeDef *) timer->user_data;return tim->Instance->CNT;}staticconststructrt_hwtimer_info _info = TIM_DEV_INFO_CONFIG;staticconststructrt_hwtimer_ops _ops ={.init = timer_init,.start = timer_start,.stop = timer_stop,.count_get = timer_counter_get,.control = timer_ctrl,};#ifdefBSP_USING_TIM2voidTIM2_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM2_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM3voidTIM3_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM3_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM4voidTIM4_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM4_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM5voidTIM5_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM5_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM11voidTIM1_TRG_COM_TIM11_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM11_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM13voidTIM8_UP_TIM13_IRQHandler(void){/* enter interrupt */
BSP_DEF_CRITICAL_SECTION;
BSP_ENTER_CRITICAL;HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM13_INDEX].tim_handle);/* leave interrupt */
BSP_EXIT_CRITICAL;}#endif#ifdefBSP_USING_TIM14voidTIM8_TRG_COM_TIM14_IRQHandler(void){/* enter interrupt */
BSP_DEF_CRITICAL_SECTION;
BSP_ENTER_CRITICAL;HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM14_INDEX].tim_handle);/* leave interrupt */
BSP_EXIT_CRITICAL;}#endif#ifdefBSP_USING_TIM15voidTIM1_BRK_TIM15_IRQHandler(void){/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM15_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM16#ifdefined(SOC_SERIES_STM32L4)||defined(SOC_SERIES_STM32WB)voidTIM1_UP_TIM16_IRQHandler(void)#elifdefined(SOC_SERIES_STM32F0)||defined(SOC_SERIES_STM32MP1)voidTIM16_IRQHandler(void)#endif{/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM16_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endif#ifdefBSP_USING_TIM17#ifdefined(SOC_SERIES_STM32L4)||defined(SOC_SERIES_STM32WB)voidTIM1_TRG_COM_TIM17_IRQHandler(void)#elifdefined(SOC_SERIES_STM32F0)||defined(SOC_SERIES_STM32MP1)voidTIM17_IRQHandler(void)#endif{/* enter interrupt */rt_interrupt_enter();HAL_TIM_IRQHandler(&stm32_hwtimer_obj[TIM17_INDEX].tim_handle);/* leave interrupt */rt_interrupt_leave();}#endifvoidHAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){#ifdefBSP_USING_TIM2if(htim->Instance == TIM2){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM2_INDEX].time_device);}#endif#ifdefBSP_USING_TIM3if(htim->Instance == TIM3){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM3_INDEX].time_device);}#endif#ifdefBSP_USING_TIM4if(htim->Instance == TIM4){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM4_INDEX].time_device);}#endif#ifdefBSP_USING_TIM5if(htim->Instance == TIM5){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM5_INDEX].time_device);}#endif#ifdefBSP_USING_TIM11if(htim->Instance == TIM11){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM11_INDEX].time_device);}#endif#ifdefBSP_USING_TIM13if(htim->Instance == TIM13){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM13_INDEX].time_device);}#endif#ifdefBSP_USING_TIM14if(htim->Instance == TIM14){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM14_INDEX].time_device);}#endif#ifdefBSP_USING_TIM15if(htim->Instance == TIM15){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM15_INDEX].time_device);}#endif#ifdefBSP_USING_TIM16if(htim->Instance == TIM16){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM16_INDEX].time_device);}#endif#ifdefBSP_USING_TIM17if(htim->Instance == TIM17){rt_device_hwtimer_isr(&stm32_hwtimer_obj[TIM17_INDEX].time_device);}#endif}intbsp_hwtimer_init(void){int i =0;int result =0;for(i =0; i <sizeof(stm32_hwtimer_obj)/sizeof(stm32_hwtimer_obj[0]); i++){
stm32_hwtimer_obj[i].time_device.info =&_info;
stm32_hwtimer_obj[i].time_device.ops =&_ops;if(rt_device_hwtimer_init(&stm32_hwtimer_obj[i].time_device, stm32_hwtimer_obj[i].name,&stm32_hwtimer_obj[i].tim_handle)==0){printf("%s register success", stm32_hwtimer_obj[i].name);}else{printf("%s register failed", stm32_hwtimer_obj[i].name);
result =-1;}}return result;}rt_hwtimer_t*rt_hwtimer_get_device(constchar*name){int i =0;for(i =0; i <sizeof(stm32_hwtimer_obj)/sizeof(stm32_hwtimer_obj[0]); i++){if(strncmp(stm32_hwtimer_obj[i].name, name,strlen(name))==0){return&stm32_hwtimer_obj[i].time_device;}}returnNULL;}
测试代码
/*
* Copyright (c) 2024-2024,shchl
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 24-8-4 shchl first version
*/#include"bsp.h"#include"bsp_hwtimer.h"#defineHWTIMER_DEV_NAME"timer13"/* 定时器名称 */rt_hwtimer_t*hw_dev =NULL;/* 定时器设备句柄 *//* 定时器超时回调函数 */staticint8_ttimeout_cb(structrt_hwtimer_device*dev){printf("set timeout value failed\n");return0;}inthwtimer_sample(){int8_t ret =0;rt_hwtimerval_t timeout_s;/* 定时器超时值 */rt_hwtimer_mode_t mode;/* 定时器模式 */uint32_t freq =10000;/* 计数频率 *//* 查找定时器设备 */
hw_dev =rt_hwtimer_get_device(HWTIMER_DEV_NAME);if(hw_dev ==NULL){printf("hwtimer sample run failed! can't find %s device!\n", HWTIMER_DEV_NAME);return-1;}/* 以读写方式打开设备 */rt_hwtimer_init(hw_dev);
ret =rt_hwtimer_open(hw_dev);if(ret !=0){printf("open %s device failed!\n", HWTIMER_DEV_NAME);return ret;}/* 设置超时回调函数 */
hw_dev->rx_indicate = timeout_cb;/* 设置计数频率(若未设置该项,默认为1Mhz 或 支持的最小计数频率) */rt_hwtimer_control(hw_dev, HWTIMER_CTRL_FREQ_SET,&freq);/* 设置模式为周期性定时器(若未设置,默认是HWTIMER_MODE_ONESHOT)*/
mode = HWTIMER_MODE_PERIOD;
ret =rt_hwtimer_control(hw_dev, HWTIMER_CTRL_MODE_SET,&mode);if(ret !=0){printf("set mode failed! ret is :%d\n", ret);return ret;}/* 设置定时器超时值为5s并启动定时器 */
timeout_s.sec =5;/* 秒 */
timeout_s.usec =0;/* 微秒 */if(rt_hwtimer_write(hw_dev,&timeout_s)!=sizeof(timeout_s)){printf("set timeout value failed\n");return-1;}/* 延时3500ms */HAL_Delay(3500);return ret;}