https://blog.csdn.net/mygod2008ok/article/details/106749721
#define SYSTEM_CLOCK (SystemCoreClock / 1000000)
static TIM_HandleTypeDef TimHandle;
void delay_init(void)
{
/* Set TIMx instance */
TimHandle.Instance = TIM3;
__HAL_RCC_TIM3_CLK_ENABLE();
TimHandle.Init.Period = 100-1; //比较值
TimHandle.Init.Prescaler = (SYSTEM_CLOCK-1);///uwPrescalerValue;//预分频值
TimHandle.Init.ClockDivision = 0;
TimHandle.Init.CounterMode = TIM_COUNTERMODE_DOWN;
TimHandle.Init.RepetitionCounter = 0;
TimHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_StatusTypeDef err_code = HAL_TIM_Base_Init(&TimHandle);
APP_ERROR_CHECK(err_code);
}
上面初时化每个时钟时间为1us,因为时钟频率为48MHz,经过48分频(48000000/1000000-1),则Prescaler值为47,经过分频后的TIM3的时钟频率为1MHz,那么1个时钟时间为1us
void delay_us(volatile uint32_t us_cnt)
{
TIM3->CNT = us_cnt-1;
TIM3->CR1 |= TIM_CR1_CEN; // 启动计数
while((TIM3->SR & TIM_FLAG_UPDATE)!=SET);
TIM3->SR = (uint16_t)~TIM_FLAG_UPDATE;
TIM3->CR1 &= ~TIM_CR1_CEN; // 停止计数
}
void delay_ms(volatile uint32_t nms)
{
volatile uint32_t ms = nms;
while(nms--)
{
delay_us(1000);
}
}
硬延时采用TIM3定时器,给定的计数据后,启动定时器,等待计数据向下计数到0产生中断来达到延时的目的
volatile uint32_t tim14_tick_count;
static TIM_HandleTypeDef Tim14Handle;
void BSP_tim14_init(void)
{
/* Set TIMx instance */
Tim14Handle.Instance = TIM14;
__HAL_RCC_TIM14_CLK_ENABLE();
/* Initialize TIMx peripheral as follows:
+ Period = 10000 - 1
+ Prescaler = (SystemCoreClock/10000) - 1
+ ClockDivision = 0
+ Counter direction = Up
*/
//f = (system clock/prescaler)/Period :(32=48M/15000)/100
Tim14Handle.Init.Period = 65535; //比较值
Tim14Handle.Init.Prescaler = (SYSTEM_CLOCK-1);///uwPrescalerValue;//预分频值
Tim14Handle.Init.ClockDivision = 0;
Tim14Handle.Init.CounterMode = TIM_COUNTERMODE_UP;
Tim14Handle.Init.RepetitionCounter = 0;
Tim14Handle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
HAL_StatusTypeDef err_code = HAL_TIM_Base_Init(&Tim14Handle);
APP_ERROR_CHECK(err_code);
__HAL_TIM_SET_COUNTER(&Tim14Handle,0);
HAL_NVIC_SetPriority(TIM14_IRQn,3,0);
HAL_NVIC_EnableIRQ(TIM14_IRQn);
HAL_TIM_Base_Start_IT(&Tim14Handle);
tim14_tick_count = 0;
}
/**
* @brief tim14返初时化
*/
uint32_t BSP_tim14_deinit(void)
{
uint32_t tim14_cnt;
tim14_cnt = tim14_tick_count * 65536;
tim14_cnt += __HAL_TIM_GET_COUNTER(&Tim14Handle);
HAL_TIM_Base_Stop_IT(&Tim14Handle);
HAL_NVIC_DisableIRQ(TIM14_IRQn);
HAL_TIM_Base_DeInit(&Tim14Handle);
__HAL_RCC_TIM14_CLK_DISABLE();
return tim14_cnt;
}
void TIM14_IRQHandler(void) //TIM3中断
{
if((TIM14->SR & TIM_FLAG_UPDATE)!=RESET)
{
TIM14->SR = (uint16_t)~TIM_FLAG_UPDATE;
tim14_tick_count++;
}
}
测量时间采用TIM14定时器,定时期周期设定为65536微秒产生一次中断,每产生一次中断令 tim14_tick_count计数值增1,
每次启动测量前会将tim14_tick_count清0,测量完后停此定时器并计算时间,公式如下:
测量时间 = tim14_tick_count * 65536 + __HAL_TIM_GET_COUNTER(&Tim14Handle)
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
RTT_INIT();
HAL_Init();
SystemClock_Config();
BSP_wdt_init(5000);
delay_init();
BSP_tim14_init();
delay_ms(1500);
uint32_t time_count = BSP_tim14_deinit();
NRF_LOG_INFO("time_count = %d us",time_count);
delay_ms(1000);
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
BSP_wdt_feed();
tick_25hz_handler();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief 25Hz handler
*
*/
void tick_25hz_handler(void)
{
if((s_wakeup_flag & TICK_FOR_25HZ) == 0)
return;
s_wakeup_flag &= CLEAR_TICK_FOR_25HZ;
//####################################################################################
//---------TODO this to add 25hz event handler-----------
static uint8_t test_flag;
if(test_flag == 0) // 丢弃上电的第一次tick标志测量
{
test_flag = 1;
}
else if(test_flag == 1)
{
test_flag = 2;
BSP_tim14_init();
}
else
{
test_flag = 1;
uint32_t tick = BSP_tim14_deinit();
NRF_LOG_INFO("tick_25hz = %d us",tick);
}
}