系統定時器SysTick

2022-06-19 02:06:11 字數 4148 閱讀 2815

在lpc824內部有乙個特殊的定時器——系統定時器(systick),它位於cortex-m0+核心裡面,是arm核心的一部分,主要用來給作業系統提供時間片輪轉的定時,一般固定為10ms的定時,所以中文也稱它為「嘀嗒」定時器(也稱「心跳」定時器)。在不跑作業系統時,可以把它當作普通定時器來用,一般用來進行程式延時。在前面的第乙個演示示例中就用到過,下面就來討論一下如何運用systick來提供延時。

系統定時器也位於「私有外設匯流排」(private peripheral bus)內,其位址為0xe000e010~0xe000e0ff。下面先來看一下systick的內部結構,如下圖所示。

從上圖中可以看出,systick定時器的位長度是24位,即最長的計數次數為16777216次,且計數為倒數計數形式,遞減到0時產生中斷請求。計數的脈衝可直接取系統時鐘,也可取半系統時鐘。下表給出了和systick相關的暫存器。

上表中,syst_csr是系統定時器的控制暫存器,負責systick的啟動、中斷使能、輸入時鐘選擇、溢位標誌讀取等操作;syst_rvr是系統定時器的初始值過載暫存器,負責systick的24位初值載入;syst_cvr是系統定時器的當前值暫存器,負責獲取systick的24位當前計數值,當對該暫存器進行寫操作時,該暫存器的數值將會被清零;syst_calib是系統定時器的校準值暫存器,負責systick的校準。

下面給出的是上表中控制暫存器syst_csr的全部位結構,其位元組位址為0xe000e010。

(1)第0位(enable)是使能systick位,置1啟動計數,置0關閉計數。

(2)第1位(tickint)是systick的中斷使能位,置1使能中斷,置0禁止中斷。

(3)第2位(clksource)是輸入時鐘的選擇位,置1時選擇系統時鐘做為計數脈衝,置0時選擇半系統時鐘做為計數脈衝的參考時鐘。

(4)第3到15位為保留位,不能對它們寫1。

(5)第16位(countflag)是溢位標誌位,當計數的值遞減到0時,該位被置1,在讀取該值後自動清零。

(6)第17到31位為保留位,不能對它們寫1。

syst_rvr是系統定時器的初始值過載暫存器,負責systick的24位初值載入。下表給出了它的全部位結構,其位元組位址為0xe000e014。

(1)第0到23位(reload)為過載的初值,即當計數器計數到0後過載到計數器中的值,一共24位。

(2)第24到31位為保留位,不能對它們寫1。

syst_cvr是系統定時器的當前值暫存器,負責獲取systick的24位當前計數值,當對該暫存器進行寫操作時,該暫存器的數值將會被清零。下表給出了它的全部位結構,其位元組位址為0xe000e018。

(1)第0到23位(current)為systick的當前值,一共24位。

(2)第24到31位為保留位,不能對它們寫1。

syst_calib是系統定時器的校準值暫存器,負責systick的校準。下表給出了它的全部位結構,其位元組位址為0xe000e01c。

(1)第31位(noref)指示處理器是否有基準時鐘,由晶元廠家出廠時決定。該位讀出值為1,指明無獨立的基準時鐘。

(2)第30位(skew)指示tenms值是否精確。由於tenms不可知,因此10ms不精確計時的校準值不能確定,這會影響systick作為軟體實時時鐘的適用性。該位讀出值為1,指明未提供tenms值。

(3)第24到29位為保留位。

(4)第0到23位(tenms)在發生系統時鐘扭曲錯誤時,在10ms時序下的校正值。該位讀出值為0,指明校準值未知。

下面給出系統時鐘systick的結構體定義。

typedef struct

systick_type;

注意,在上述定義中,結構體成員ctrl對應syst_csr暫存器,load對應syst_rvr暫存器,val對應syst_cvr暫存器,calib對應syst_calib暫存器。結構體中並沒有全部採用systick中的暫存器名稱。

systick定時器組的基址為0xe000e000,所以要將基址指標強制轉換為上述結構體,還要加上下面的定義。

#define scs_base            (0xe000e000ul)

#define systick_base        (scs_base +  0x0010ul)

#define systick             ((systick_type   *)     systick_base  )

對於系統定時器systick產生的中斷,也有特定的入口函式,形式如下所示。

void systick_handler(void)

由上述可見,其實系統定時器本身就是乙個普通的定時器,在實際應用時可按以下順序進行操作。

(1)給syst_rvr暫存器寫入定時器的初始值。

(2)寫syst_cvr暫存器對計數值進行清零。

(3)設定syst_csr暫存器選擇相應的時鐘源,啟動定時並使能中斷。

systick定時的時長由系統時鐘頻率、系統時鐘選擇和載入的初始值共同決定。假設系統時鐘為24mhz,預設情況下systick的clksource值為0,即選擇半系統時鐘頻率。這樣,輸入給定時器計數的時鐘就是24÷2=12mhz,計數週期為1/(12mhz)=1/12us,則計12次就是1us的定時,但實際上systick採用的是倒數計數方式,即從最大值依次遞減計數直到0產生溢位訊號。所以12次計數實際上是0~11次,即最大值要減1,即12-1=11。同時要注意,由於計數字寬是24位,所以最大計數值不能超過2的24次方(即16777216),由此,可得出微秒級的初始值計算公式,如下:

load=((12*us)-1),其中us取值範圍1~1398000

同理可得出毫秒級的初始值計算公式:

load=((12000*ms)-1),其中ms取值範圍1~1398

上公升到一般情況,定時初始值可用下面的公式來計算:

上式中,系統時鐘sysclk的單位是mhz,clksource的值是0或1,得到的是微秒級別的定時,要注意load的值不能大於16777216。

下面來看乙個使用sysclk實現的毫秒級延時函式,**如下:

void delay_ms(uint32_t ms)

在程式中,通過「while(!(systick ->ctrl & 0x10000));」這句來等待定時器溢位,其實就是迴圈查詢控制暫存器syst_csr中的countflag位(第16位)是否被置1,若為0則迴圈等待直到1為止。注意,本函式延時的最大時長為1398ms,即傳遞給它的引數不能超過1398,否則不能實現延時功能。

下面再來看乙個流水燈的例子,要求實現乙個8位的流水燈,時間間隔為100ms。電路延用第乙個演示示例中的電路原理圖,參考**如下:

#include

//************************埠初始化***********************************

void port_init(void)

//************************定時器初始化*********************************

void systick_init(void)

//***************************主函式************************************

int main(void)

}//************************定時器中斷***********************************

void systick_handler(void)

}

SysTick 系統定時器

本章參考資料 arm cortex m4f 技術參考手冊 4.5 章節 systick timer stk 和 4.48 章節 shprx,其中 stk 這個章節有 systick 的簡介和暫存器的詳細描述。因為 systick 是屬於 cm4 核心的外設,有關暫存器的定義和部分庫函式都在 core...

SysTick 系統定時器

本章參考資料 arm cortex m4f 技術參考手冊 4.5 章節 systick timer stk 和 4.48 章節 shprx,其中 stk 這個章節有 systick 的簡介和暫存器的詳細描述。因為 systick 是屬於 cm4 核心的外設,有關暫存器的定義和部分庫函式都在 core...

SysTick系統定時器

1.systick定時器介紹 systick定時器也叫systick滴答定時器,它是cortex m3核心的乙個 外設,被嵌入在 nvic 中。它是乙個24 位向下遞減的定時器,每計數一 次所需時間為1 systick,systick是系統定時器時鐘,它可以直接取自 系統時鐘,還可以通過系統時鐘8分...