STM32 (F469I) 延遲時間 如何精準的計算
如何利用系統內的時間 SysTick 來延遲 STM32 下面是一個示範的例子。
時脈的設定在函式內,這裡示範的時脈是 180Mhz,你可以從官方的範例代碼,隨便一個應該都有,可以看到註解會明顯地寫著 180Hhz 等字樣。
時脈的設定在函式內,這裡示範的時脈是 180Mhz,你可以從官方的範例代碼,隨便一個應該都有,可以看到註解會明顯地寫著 180Hhz 等字樣。
這篇介紹的是比較簡單的delay方式,但這會導致計時中板子CPU停機不工作,如果需要多個LED不同頻率閃爍藥用中斷計時比較好,參考站內連結stm32f4 使用計時器計時 1ms
初始化系統時間函式
SystemClock_Config();
調用系統函式
HAL_Delay(1000);
自訂函式
如果需要1us就把乘以1000給拿掉就可以了。
/*****************************************************************
Name : 毫秒延遲
Date : 2017/07/31
By : CharlotteHonG
Final: 2017/07/31
*****************************************************************/
void delay_ms_core(uint32_t n) {
uint32_t clk = 180; // CPU 180MHz
uint32_t ticks = time_ms * clk * 1000; // time is ms
uint32_t told = SysTick->VAL;
uint32_t tnow = told;
uint32_t tcnt = 0;
for(; tcnt<ticks; tnow=SysTick->VAL)
{
if(tnow != told) {
if(tnow < told) {
tcnt += told - tnow;
} else {
tcnt += SysTick->LOAD-tnow + told;
} told = tnow;
}
}
}
搞得這麼麻煩是為了避開益位的問題
SysTick 是一個倒數的計時器,歸零之後會從SysTick->LOAD 重新開始倒數,一般來說這個數值會是 SystemCoreClock 我的板子是 16M。
這些數值在執行 HAL_Init(); 的時候會幫你設置好,你也可以從這個函式按F12慢慢追上去就可以追到這些數據了。
這些數值在執行 HAL_Init(); 的時候會幫你設置好,你也可以從這個函式按F12慢慢追上去就可以追到這些數據了。
if(tnow != told) 是為了確保你的累加量總是小於 16M,不然如果益位超過2次你就沒辦法計算到底是多少了。每次變動後 told = tnow; 重新計算變量。
if(tnow != told) 是一般正常情況就是相減就可以得到時間變量了
else 是益位後的處理,大概是這麼算的已知總長是16M,當時間為 10(told) 被記錄到,經過一段時間變成15M(tnow),要計算其變量就是 16M - 15M(tnow) +10(told)。
就是10歸零之後又減少1M的意思了。
時間常數超出範圍
使用的時候要注意不能設太大,否則ticks可能會相乘出來會超過參數上的 uint32_t 的最大值,處理方式簡單再加一層 for 迴圈處理,依此類推自己加大時間單位。
void delay_ms(uint32_t t) {
const uint32_t sec = 1000;
for(; t>=sec; t-=sec) {
delay_ms_core(sec);
} delay_ms_core(t);
}
沒有留言:
張貼留言