SysTick簡介、功能框圖講解、SysTick定時實驗講解
SysTick:系統滴答定時器,24位,只能遞減,存在於內核中,嵌套在NVIC中,所有的Cortex-M內核的單片機都具有這個定時器。
(內核中的外設)
功能框圖:STK_CLK(72M/9M) -》STK_VAL遞減計數器
^
|
STK_LOAD重裝載寄存器
遞減計數器counter在時鐘的驅動下,從reload初值開始往下遞減計數到0,
產生中斷和置位COUNTFLAG標誌瞭然後又從reload值開始重新遞減,如此循環。
SysTick中的幾個寄存器:
SysTick控制及狀態寄存器CTRL:
位段 名稱 類型 復位值 描述
16 COUNTFLAG R/W 0 如果上次讀取本寄存器後,SysTick已經到了0,則該位位1
2 CLKSOURCE R/W 0 時鐘源選擇位,0=AHB/8,1=處理器時鐘AHB72M
(就是說,SysTick的CTRL寄存器中的第16位,如果爲1,說明上次讀取數值後Systick有到了0了,完成一次tick滴答了)
SysTick重裝載數值寄存器LOAD:
位段 名稱 類型 復位值 描述
23:0 RELOAD R/W 0 當倒數計數至0,將被重新裝載賦值
SysTick當前數值寄存器VAL:
位段 名稱 類型 復位值 描述
23:0 CURRENT R/W 0 讀取時返回當前倒計數的值,寫它則是指清零
Systick定時時間計算:
1-t:一個計數循環時間,跟reload和CLK有關
2-CLK:72M或者9M,由CTRL寄存器配置
3-RELOAD:24位,用戶自己配置
t=reload*(1/clk)
clk=72M 時,t=72 * (1/72M) = 1us 微妙
clk=72M 時,t=7200 * (1/72M) = 1ms 毫秒
1s = 10^3ms = 10^6us = 10^9ns
SysTick屬於內核的外設,它的中斷優先級和片上的外設的中斷優先級相比,哪一個高?
答:根據中斷向量表查看中斷優先級;
中斷優先級的分組隊內核和外設同樣適用。當比較的時候,
只需要把內核外設的中斷優先級的四個位按照外設的中斷優先級來
分組即可,即人爲的分出【搶佔優先級】和【子優先級】
實驗:編寫微秒級的延時函數 LED閃爍
固件庫函數:
/**
* @brief Initialize and start the SysTick counter and its interrupt.
* 簡述:初始化並且開啓系統滴答定時器及其中斷
* @param ticks number of ticks between two interrupts
參數: ticks :兩次中斷的滴答數
* @return 1 = failed, 0 = successful
返回值:1=失敗,0=成功
*
* Initialise the system tick timer and its interrupt and start the
* system tick timer / counter in free running mode to generate
* periodical interrupts.
初始化系統計時器及其中斷,並在自由運行模式下
啓動系統計時計時器/計數器,以生成周期性中斷
*/
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
//判斷tick的值是否大於2^24,如果大於,則不符合規則
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */
//初始化reload寄存器的值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */
//配置中斷優先級,配置爲15,默認爲最底的優先級
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
//初始化counter的值爲0
SysTick->VAL = 0; /* Load the SysTick Counter Value */
//配置systick的時鐘爲72M;使能中斷;使能systick開始計數
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0); /* Function successful */
}
自己編寫函數:
/*
* param:us:微妙數,us=1000,則該函數產生一個1000us的延時
*/
void SysTick_Delay_us(uint32_t us)
{
uint32_t i;
SysTick_Config(72);
for(i = 0 ;i < us;i++)
{
//counter會從reload的值下減到0
//當計數器的值減小到0的時候,CTRL寄存器的16位會置1,
//循環判斷SysTick的CTRL的16位是否爲1 ,如果是,則說明達到1微妙,跳出循環
while( !((SysTick->CTRL) & (1<<16)) );
}
//跳出循環說明時間到,SysTick清零
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}