本章參考資料《ARM Cortex™-M4F 技術參考手冊》 -4.5 章節 SysTick Timer(STK), 和4.48 章節 SHPRx,其中 STK 這個章節有 SysTick 的簡介和寄存器的詳細描述。因為SysTick 是屬於 CM4 內核的外設,有關寄存器的定義和部分庫函數都在 core_cm4.h 這個頭文件中實現。所以學習 SysTick 的時候可以參考這兩個資料,一個是文檔,一個是源碼。
SysTick簡介
SysTick—系統定時器是屬於 CM4 內核中的一個外設,內嵌在 NVIC 中。系統定時器是一個 24bit 的向下遞減的計數器,計數器每計數一次的時間為 1/SYSCLK,一般我們設置系統時鍾 SYSCLK 等於 180M。當重裝載數值寄存器的值遞減到 0 的時候,系統定時器就產生一次中斷,以此循環往復。
因為 SysTick 是屬於 CM4 內核的外設,所以所有基於 CM4 內核的單片機都具有這個系統定時器,使得軟件在 CM4 單片機中可以很容易的移植。系統定時器一般用於操作系統,用於產生時基,維持操作系統的心跳。
寄存器
寄存器名稱 | 寄存器描述 |
---|---|
CTRL | SysTick 控制及狀態寄存器 |
LOAD | SysTick 重裝載數值寄存器 |
VAL | SysTick 當前數值寄存器 |
CALIB | SysTick 校准數值寄存器 |
表 18-2 SysTick 控制及狀態寄存器
位段 | 名稱 | 類型 | 復位值 | 描述 |
---|---|---|---|---|
16 | COUNTFLAG | R/W | 0 | 如果在上次讀取本寄存器后, SysTick 已經計到了 0,則該位為 1。 |
2 | CLKSOURCE | R/W | 0 | 時鍾源選擇位, 0=AHB/8, 1=處理器時鍾 AHB |
1 | TICKINT | R/W | 0 | 1=SysTick 倒數計數到 0 時產生 SysTick 異常請求 , 0= 數 到 0 時 無 動 作 。 也 可 以 通 過 讀 取COUNTFLAG 標志位來確定計數器是否遞減到0 |
0 | ENABLE | R/W | 0 | SysTick 定時器的使能位 |
表 18-3 SysTick 重裝載數值寄存器
位段 | 名稱 | 類型 | 復位值 | 描述 |
---|---|---|---|---|
23:0 | RELOAD | R/W | 0 | 當倒數計數至零時,將被重裝載的值 |
表 18-4 SysTick 當前數值寄存器
位段 | 名稱 | 類型 | 復位值 | 描述 |
---|---|---|---|---|
23:0 | CURRENT | R/W | 0 | 讀取時返回當前倒計數的值,寫它則使之清零,同時還會清除在 SysTick 控制及狀態寄存器中的 COUNTFLAG 標 |
表 18-5 SysTick 校准數值寄存器
位段 | 名稱 | 類型 | 復位值 | 描述 |
---|---|---|---|---|
31 | NOREF | R | 0 | NOREF flag. Reads as zero. Indicates that aseparate reference clock is provided.The frequency of this clock is HCLK/8 |
30 | SKEW | R | 1 | SKEW flag: Indicates whether the TENMS valueis exact. Reads as one. Calibrationvalue for the 1 ms inexact timing is not knownbecause TENMS is not known. This can affectthe suitability of SysTick as a software real timeclock |
23:0 | TENMS | R | 0 | Calibration value. Indicates the calibration valuewhen the SysTick counterruns on HCLK max/8as external clock. The value is productdependent, please refer to theProduct ReferenceManual, SysTick Calibration Value section.When HCLK is programmed atthe maximumfrequency, the SysTick period is 1ms.If calibration information is not known, calculatethe calibration value required from thefrequencyof the processor clock or external clock |
SysTick定時實驗
SysTick_Config()庫函數主要配置了 SysTick 中的三個寄存器: LOAD、 VAL 和 CTRL,有關具體的部分看代碼注釋即可。其中還調用了固件庫函數 NVIC_SetPriority()來配置系統定時器的中斷優先級,該庫函數也在 core_m4.h 中定義,原型如下:
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)IRQn < 0)
{
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] =
(uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
else
{
NVIC->IP[((uint32_t)(int32_t)IRQn)] =(uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
因為 SysTick 屬於內核外設,跟普通外設的中斷優先級有些區別,並沒有搶占優先級和子優先級的說法。在 STM32F429 中,內核外設的中斷優先級由內核 SCB 這個外設的寄存器:SHPRx(x=1.2.3)來配置。有關 SHPRx 寄存器的詳細描述可參考《Cortex-M4 內核編程手冊》 4.4.8 章節。下面我們簡單介紹下這個寄存器。
SPRH1-SPRH3 是一個 32 位的寄存器,但是只能通過字節訪問,每 8 個字段控制着一個內核外設的中斷優先級的配置。在 STM32F429 中,只有位 7:3 這高四位有效,低四位沒有用到,所以內核外設的中斷優先級可編程為: 0~15,只有 16 個可編程優先級,數值越小,優先級越高。如果軟件優先級配置相同,那就根據他們在中斷向量表里面的位置編號來決定優先級大小,編號越小,優先級越高。
如果要修改內核外設的優先級,只需要修改下面三個寄存器對應的某個字段即可。
在系統定時器中,配置優先級為(1UL << __NVIC_PRIO_BITS) - 1UL),其中宏__NVIC_PRIO_BITS 為 4,那計算結果就等於 15,可以看出系統定時器此時設置的優先級在內核外設中是最低的。
// 設置系統定時器中斷優先級 NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
參考引用:
- 野火---《零死角玩轉STM32-F429挑戰者》
- 《STM32F4xx中文參考手冊》
- 《Cortex-M4內核編程手冊》