我們大家平常在單片機開發中經常會使用到延時函數,一般的,我們會使用變量自加循環判斷的方法來實現軟件延時。但是,
這種方法有個弊端——延時時間不精確。
主要體現在:
1, 在C語言編寫的延時函數中,每條函數語句的執行時間可能不同,這樣,在實現延時的過程中,想通過增加或減少函數語
句來實現延時的增加或減小控制起來不太方便,時間的精確性當然很難控制;
2, 由於各種不同的控制器運行的主頻可能不同,執行相同的延時函數所需要的的時間值可能就不同。這樣,使得這種延時函
數在不同的平臺上移植起來時間的精確性就更不可靠。
所以,我們就不使用這樣的延時方法。
從ARM Cortex-M0內核開始,一直到現在的ARM Cortex-M4,這些內核中都搭載了systick滴答定時器,它放在了NVIC中,主要
目的是爲了給操作系統提供一個滴答中斷。當然,畢竟它也是一個定時器,我們就可以利用它來做到精確的軟件延時。
systick定時器是一個遞減的計數器,如果設定初值並使能它以後,它會在每個系統時鐘週期裏計數器減1,直到減到0爲止。然
後,systick計數器自動重裝初值並繼續遞減計數,如果軟件上又使能了systick計數器的中斷,那麼,在systick計數器減到0的時
候,中斷被觸發,當然,中斷標誌位也被置位。那麼,每次計數器遞減到0,所經過的時間值爲:系統時鐘週期*計數器初值。
如:我們這裏以飛思卡爾Cortex-M4內核的Kinetis爲例,系統內核時鐘頻率初始化爲100MHz,則系統內核時鐘週期爲1/100M,
如果計數器的初值爲100000,那麼,延時的時間則爲:(1/100M)*100000=0.001s=1ms。
systick定時器內部幾個常用的寄存器:
1, systick控制及狀態寄存器CTRL:
其中,CTRL[16]位是COUNTFLAG標誌位,當systick計數到0的時候,該位置1,如果讀取該位,則硬件自動清0,所以我們
可以用軟件判斷是否計數到0。
CTRL[2]位是CLKSOURE標誌位,用來指示當前systick定時器的時鐘源,CLKSOURCE=1表示時鐘源是內核時鐘(一般我們
會選擇這種情況,如此處我們使用飛思卡爾Kinetis的內核時鐘100MHz);CLKSOURCE=0表示時鐘源是外部時鐘源。
CTRL[1]位是TICKINT標誌位,用來指示systick計數到0的時候是否產生systick異常請求。CTRL[0]位是ENABLE位,該位是
systick定時器的使能位。
2, systick重裝載計數器LOAD:
該寄存器是一個24位的寄存器,保存着systick定時器的初值,使得當systick計數到0的時候,將該寄存器中的數據重裝載到
當前計數器中繼續遞減計數。
3, systick當前數值計數器VAL:
該寄存器是一個24位的寄存器,用來指示當前的計數值。