STM32延時函數(shù)
{
SysTick->CTRL&=0xfffffffb;
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
Systick 主要的作用就是拿來計時,其原理和應(yīng)用簡述一下就是這樣的:通過配置寄存器 SysTick->CTRL來設(shè)定Systick的計時頻率并Enable使Systick開始計數(shù),這里的 SysTick->CTRL&=0xfffffffb應(yīng)該很好理解,把第2位設(shè)定為0,查找應(yīng)用手冊可以知道這是把Systick的計時頻率設(shè)定為CPU主頻(SYSCLK)的1/8。
假定我們板子默認(rèn)的晶振頻率是8Mhz,默認(rèn)CPU工作頻率(SYSCLK)是9倍頻,即72M,那Systick的頻率就是72/8=9Mhz。
知道了Systick的頻率,下一步就是確定倒時計數(shù)器的數(shù)值,即SysTick-> LOAD這個寄存器的配置。上面已經(jīng)知道了,Systick的工作頻率F=9Mhz=SYSCLK/8,即每秒鐘計數(shù)器自減900萬次,也就是說,SYSCLK/8次的自減耗時1秒,那么(8/SYSCLK)/1000,000次自減就耗時1微秒了,這也就是fac_us的值了。那么上面函數(shù)中的fac_us為什么是SYSCLK/8呢?這里先搞清楚一點,函數(shù)中SYSCLK的單位是Mhz,所以SYSCLK的值是72(這個以Mhz為單位應(yīng)該是STM32基礎(chǔ)庫里面做過宏定義的),否則也不可能用一個8位整形去表示一個7200萬的數(shù)值;而我們這里計算的SYSCLK是以Hz為單位的,即 72Mhz/1000,000=72,所以這個SYSCLK/8是對的。
你可能還沒搞清楚 fac_us到底是干嘛的。很簡單,fac_us就是要寫入SysTick-> LOAD寄存器的值,Systick的工作原理是這個寄存器的值在Systick被Enable之后就開始以設(shè)定的工作頻率自減,減到0的時候就發(fā)出中斷,實現(xiàn)定時。所以,寫入fac_us到SysTick-> LOAD寄存器,就是要Systick在自減了fac_us次以后發(fā)出中斷,自減fac_us所耗的時間已經(jīng)說了,1微秒。
下面的fac_ms應(yīng)該很好理解了,就是1毫秒的計數(shù)次數(shù),剛好是1微妙的1000倍,注意9×1000超出了8位整形的表示范圍,所以要用(u16)先把fac_us轉(zhuǎn)成16位變量,以保證計算的正確。
具體的應(yīng)用函數(shù)是用來做延時,如下:
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //時間加載
SysTick->VAL=0x00; //清空計數(shù)器
SysTick->CTRL=0x01 ; //Enable Systick,開始倒數(shù)
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)
SysTick->CTRL=0x00; //Disable Systick
SysTick->VAL =0X00; //清空計數(shù)器
}
具體的寄存器配置只要看手冊就知道了,這里只需要理解一句:
do
{
temp=SysTick->CTRL;
}
while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)
核心就是while(temp&0x01&&!(temp&(1<<16)));//等待時間到達(dá)
temp 已經(jīng)是Systick控制寄存器的值了,temp&0x01就是把該寄存器的值讀出并且把除第一位之外位都清零(當(dāng)然要通過temp變量來傳遞值而不是直接修改寄存器),第一位就是Systick的Enable配置信息,寫入1就是Enable,寫入0就是Disable,讀這一位是判斷 Systick是否仍然處于Enable狀態(tài)(可能被其他中斷禁用掉),temp&(1<<16)就是讀取第16位的值,這一位如果為0就表示計數(shù)器的值不是0(即還在計數(shù)),如果是1就表示計數(shù)器已經(jīng)自減到0了。
那么這段就很好理解了,即判斷,如果Systick還在Enable的狀態(tài),并且計數(shù)器還沒數(shù)到0,就不停的循環(huán)把當(dāng)前的 SysTick->CTRL寄存器值寫入變量temp,繼續(xù)下一次判斷。當(dāng)Systick被Disable或者計數(shù)器數(shù)到0了,就停止循環(huán)。因為只是做延時,也不需要跳到任何中斷服務(wù)那邊去處理什么,只要這個循環(huán)的耗時過程完成就可以了。
評論