用 STM32 通用定時器做微秒延時函數(STM32CubeMX版本)


原文地址:

https://blog.csdn.net/qq_33974167/article/details/110413882?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link

 

 

環境:

開發板:STM32F4探索者(正點原子)
1.配置定時器時鍾
選擇時鍾源

 

 

 

這里選擇的是內部時鍾,來自 RCC 的TIMxCLK,在通用定時器框圖中我們可以看到如下:

 

 

 

而我們可以在 STM32F4xx中文參考手冊中找到,TIM2 在外設總線1(APB1上),因此其時鍾為 84MHz,如下圖所示:

 

 

 

2.計數器時鍾頻率及計數模式
除了配置定時器的時鍾,還需要配置計數器時鍾頻率,我們要實現微秒延時,因此計數器時鍾頻率應該是1MHz,

而要實現還需要以下3個參數:

 

 

 

預分頻系數
根據STM32F4xx中文參考手冊中的時鍾頻率計算,如下圖所示:

 

 

 

其中fCK_PSC就是通用定時器框圖中的CK_PSC, 即值為84MHz,而我們所要的計數器時鍾頻率1MHz

因此:

PSC[15:0] = (fCK_PSC/CK_CNT) - 1
= (84/1) - 1
= 83

因此預分頻系數為 83

計數器模式
計數器這里采用向下計數模式,也就是 如設置計數值為 1000,那么每隔一個微秒,就減一,一直減到 0

自動重裝載值
雖然我們並不使用自動重裝載功能,但是,我們還是要對自動重裝載寄存器進行賦值且不賦值為0即可,但是我測試時發送,如果為1,延時會出現偏差,因此這里賦值為 2,依據如下:

 

 

 

3.打開定時器中斷

 

 


4.具體實現代碼

volatile bool elapsed = false; //用於判斷設置的計數值是否耗盡(向下計數模式),耗盡時,在中斷中獎會設置為true

void setState(bool state)
{
    elapsed = state;
}

bool getState()
{
    return elapsed;
}

void usDelay(uint32_t time)
{

    __HAL_TIM_SetCounter(&htim2,time); //設置計數值
    setState(false);
    HAL_TIM_Base_Start_IT(&htim2); //開啟定時器
    while(!getState()); //判斷計數值是否耗盡
    HAL_TIM_Base_Stop_IT(&htim2); //關閉定時器

}

 


計數值耗盡回掉函數

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if (htim->Instance == TIM2) {
    setState(true);
  }

}

 

5.代碼測試
主函數的主循環中:

while (1)
{
/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */
printf("hello usDelay");
for(int i = 0; i < 1000; i++)
{
usDelay(1000);
}

}

 

在串口調試助手中,可以看到如下,一秒打印一條語句

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM