-
工程準備,在以下鏈接的例程上實現TIM延時及時間測量,參考鏈接如下:
https://blog.csdn.net/mygod2008ok/article/details/106749721
-
在工程中增加stm32f0xx_hal_tim.c和stm32f0xx_hal_tim_ex.c
-
在stm32f0xx_hal_conf.h文件中打開HAL_TIM_MODULE_ENABLED宏
-
新建BSP文件夾並新建BSP_delay.c和BSP_delay.h文件並加入到工程中
-
添加路徑
BSP_delay延時初時化函數實現,這裏採用TIM3定時器
#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產生中斷來達到延時的目的
-
定時器TIM14實現測量時間,初時化函數如下
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;
}
-
得到微秒級計數值並反初時化TIM14
/**
* @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;
}
-
TIM14中斷
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)
在main.c中包含BSP_delay.h,添加測試代碼
/**
* @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 */
}
-
在tick_25hz_handler函數中添加測量代碼
/**
* @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);
}
}
-
運行結果如下:
例程下載鏈接:
https://download.csdn.net/download/mygod2008ok/12522665