新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32F103 systick 是做什么用呢

STM32F103 systick 是做什么用呢

作者: 時(shí)間:2016-11-23 來(lái)源:網(wǎng)絡(luò) 收藏
提到systick 不得不抱怨以下STM32 的用戶手冊(cè),既然提供了systick 的功

能,為啥手冊(cè)里卻只提了一下?后來(lái)筆者上網(wǎng)搜的時(shí)候,才發(fā)現(xiàn),抱怨的不僅僅
是我一個(gè)人。整個(gè)DATASHEET上面就只有一句話提到了關(guān)于systick的具體用法,糊里糊涂的我蒙了半天,問老大,結(jié)果被人家鄙視了,我很是不爽就在網(wǎng)上看了看,結(jié)果還是沒有資料,后來(lái)終于看了信達(dá)工作室里整合了一篇關(guān)于systick的文章,覺得不錯(cuò)就和大家分享下,希望對(duì)大家有幫助,由于時(shí)間緊張文章中可能會(huì)有寫的不具體和邏輯不清楚的地方,請(qǐng)大家多包涵。
1. systick介紹
Systick 就是一個(gè)定時(shí)器而已,只是它放在了NVIC 中,主要的目的是為了
給操作系統(tǒng)提供一個(gè)硬件上的中斷(號(hào)稱滴答中斷)。沒有學(xué)過(guò)操作系統(tǒng)的同學(xué),
可能會(huì)很郁悶,啥叫滴答中斷?這里來(lái)簡(jiǎn)單地解釋一下。操作系統(tǒng)進(jìn)行運(yùn)轉(zhuǎn)的時(shí)
候,也會(huì)有“心跳”。它會(huì)根據(jù)“心跳”的節(jié)拍來(lái)工作,把整個(gè)時(shí)間段分成很多
小小的時(shí)間片,每個(gè)任務(wù)每次只能運(yùn)行一個(gè)“時(shí)間片”的時(shí)間長(zhǎng)度就得退出給別
的任務(wù)運(yùn)行,這樣可以確保任何一個(gè)任務(wù)都不會(huì)霸占整個(gè)系統(tǒng)不放。這個(gè)心跳,
可以通過(guò)定時(shí)器來(lái)周期性觸發(fā),而這個(gè)定時(shí)器就是systick。很明顯,這個(gè)“心跳”
是不允許任何人來(lái)隨意地訪問和修改的。只要不把它在SysTick 控制及狀態(tài)寄
存器中的使能位清除,就永不停息。它有四個(gè)寄存器,筆者把它列出來(lái):
STK_CSR, 0xE000E010 -- 控制寄存器
STK_LOAD, 0xE000E014 -- 重載寄存器
STK_VAL, 0xE000E018 -- 當(dāng)前值寄存器
STK_CALRB, 0xE000E01C -- 校準(zhǔn)值寄存器

本文引用地址:http://m.butianyuan.cn/article/201611/320338.htm


以下部分參考互聯(lián)網(wǎng)的一篇文章,網(wǎng)址為:
http://home.eeworld.com.cn/my/space.php?uid=116357&do=blog&id=31714
感謝作者“416561760 的博客”提供如此詳細(xì)的寄存器說(shuō)明的文章。


1、STK_CSR控制寄存器:寄存器內(nèi)有4 個(gè)位t 具有意義


第0 位:ENABLE,Systick 使能位(0:關(guān)閉Systick 功能;1:開啟Systick
功能)
第1 位:TICKINT,Systick 中斷使能位(0:關(guān)閉Systick 中斷;1:開啟
Systick 中斷)
第2 位:CLKSOURCE,Systick 時(shí)鐘源選擇(0:使用HCLK/8 作為Systick
時(shí)鐘;1:使用HCLK 作為Systick 時(shí)鐘)
第3 位:COUNTFLAG,Systick 計(jì)數(shù)比較標(biāo)志,如果在上次讀取本寄存器后,
SysTick 已經(jīng)數(shù)到了0,則該位為1。如果讀取該位,該位將自動(dòng)清零。
2、STK_LOAD 重載寄存器:


Systick 是一個(gè)遞減的定時(shí)器,當(dāng)定時(shí)器遞減至0 時(shí),重載寄存器中的值就
會(huì)被重裝載,繼續(xù)開始遞減。STK_LOAD 重載寄存器是個(gè)24 位的寄存器最大
計(jì)數(shù)0xFFFFFF。
3、STK_VAL當(dāng)前值寄存器:


也是個(gè)24 位的寄存器,讀取時(shí)返回當(dāng)前倒計(jì)數(shù)的值,寫它則使之清零,同
時(shí)還會(huì)清除在SysTick 控制及狀態(tài)寄存器中的COUNTFLAG 標(biāo)志。
4、STK_CALRB 校準(zhǔn)值寄存器:


位31 NOREF :1=沒有外部參考時(shí)鐘(STCLK 不可用)0=外部參考時(shí)鐘可用
位30 SKEW:1=校準(zhǔn)值不是準(zhǔn)確的1ms 0=校準(zhǔn)值是準(zhǔn)確的1ms
位[23:0] :Calibration value
Indicates the calibration value when the SysTick counter runs on HCLK
max/8 as external clock. The value is product dependent, please refer to
the Product Reference Manual, SysTick Calibration Value section. When
HCLK is programmed at the maximum frequency, the SysTick period is 1ms.
If calibration information is not known, calculate the calibration value
required from the frequency of the processor clock or external clock.
2. systick編程
現(xiàn)在我們想通過(guò)Systick 定時(shí)器做一個(gè)精確的延遲函數(shù),比如讓LED 精確延
遲1 秒鐘閃亮一次。
思路:利用systick 定時(shí)器為遞減計(jì)數(shù)器,設(shè)定初值并使能它后,它會(huì)每個(gè)
系統(tǒng)時(shí)鐘周期計(jì)數(shù)器減1,計(jì)數(shù)到0 時(shí),SysTick 計(jì)數(shù)器自動(dòng)重裝初值并繼續(xù)
計(jì)數(shù),同時(shí)觸發(fā)中斷。
那么每次計(jì)數(shù)器減到0,時(shí)間經(jīng)過(guò)了:系統(tǒng)時(shí)鐘周期* 計(jì)數(shù)器初值。我們
使用72M 作為系統(tǒng)時(shí)鐘,那么每次計(jì)數(shù)器減1 所用的時(shí)間是1/72M,計(jì)數(shù)器
的初值如果是72000,那么每次計(jì)數(shù)器減到0,時(shí)間經(jīng)過(guò)(1/72M) * 72000 =
0.001,即1ms。但是我們一般使用的時(shí)候都不是直接用72M作為systick時(shí)鐘的,而是間接地把AHB分頻(8分頻),此時(shí)systick時(shí)鐘就為9M。1/9000000*9000=1ms,這次是STM32規(guī)格書上所說(shuō)的配置systick定時(shí)器的具體方法。
現(xiàn)在我們做出來(lái)的Delay(1),就是1 毫秒延遲。Delay(1000)就是1 秒。
有了以上的思路后,systick 的編程非常簡(jiǎn)單。


接著開始配置systick,實(shí)際上配置systick 的嚴(yán)格過(guò)程如下:
使用ST 的函數(shù)庫(kù)使用systick 的方法:
1、調(diào)用SysTick_CounterCmd() – 使能SysTick 計(jì)數(shù)器
2、調(diào)用SysTick_ITConfig () -- 使能SysTick 中斷
3、調(diào)用SysTick_CLKSourceConfig() -- 設(shè)置SysTick 時(shí)鐘源。
4、調(diào)用SysTick_SetReload() -- 設(shè)置SysTick 重裝載值。
5、調(diào)用SysTick_ITConfig () -- 使能SysTick 中斷
6、調(diào)用SysTick_CounterCmd() -- 開啟SysTick 計(jì)數(shù)器
這里大家一定要注意,必須使得當(dāng)前寄存器的值VAL 等于0!
SysTick->VAL = (0x00);
只有當(dāng)VAL 值為0 時(shí),計(jì)數(shù)器自動(dòng)重載RELOAD。
接下來(lái)就可以直接調(diào)用Delay();函數(shù)進(jìn)行延遲了。延遲函數(shù)的實(shí)現(xiàn)中,要注
意的是,全局變量TimingDelay 必須使用volatile,否則可能會(huì)被編譯器優(yōu)化。

Q:什么是SYSTick定時(shí)器?
SysTick 是一個(gè)24 位的倒計(jì)數(shù)定時(shí)器,當(dāng)計(jì)到0 時(shí),將從RELOAD 寄存器中
自動(dòng)重裝載定時(shí)初值。只要不把它在SysTick 控制及狀態(tài)寄存器中的使能位清
除,就永不停息。
Q:為什么要設(shè)置SysTick定時(shí)器?
(1)產(chǎn)生操作系統(tǒng)的時(shí)鐘節(jié)拍
SysTick定時(shí)器被捆綁在NVIC中,用于產(chǎn)生SYSTICK異常(異常號(hào):15)。
在以前,大多操作系統(tǒng)需要一個(gè)硬件定時(shí)器來(lái)產(chǎn)生操作系統(tǒng)需要的滴答中斷,作
為整個(gè)系統(tǒng)的時(shí)基。因此,需要一個(gè)定時(shí)器來(lái)產(chǎn)生周期性的中斷,而且最好還讓
用戶程序不能隨意訪問它的寄存器,以維持操作系統(tǒng)“心跳”的節(jié)律。
(2)便于不同處理器之間程序移植。
Cortex‐M3 處理器內(nèi)部包含了一個(gè)簡(jiǎn)單的定時(shí)器。因?yàn)樗械腃M3 芯片都帶
有這個(gè)定時(shí)器,軟件在不同CM3 器件間的移植工作得以化簡(jiǎn)。該定時(shí)器的時(shí)鐘
源可以是內(nèi)部時(shí)鐘(FCLK,CM3 上的自由運(yùn)行時(shí)鐘),或者是外部時(shí)鐘( C
M3 處理器上的STCLK 信號(hào))。
不過(guò),STCLK 的具體來(lái)源則由芯片設(shè)計(jì)者決定,因此不同產(chǎn)品之間的時(shí)鐘頻率
可能會(huì)大不相同,你需要檢視芯片的器件手冊(cè)來(lái)決定選擇什么作為時(shí)鐘源。Sys
Tick 定時(shí)器能產(chǎn)生中斷,CM3 為它專門開出一個(gè)異常類型,并且在向量表中有
它的一席之地。它使操作系統(tǒng)和其它系統(tǒng)軟件在CM3 器件間的移植變得簡(jiǎn)單多
了,因?yàn)樵谒蠧M3 產(chǎn)品間對(duì)其處理都是相同的。
(3)作為一個(gè)鬧鈴測(cè)量時(shí)間。
SysTick 定時(shí)器除了能服務(wù)于操作系統(tǒng)之外,還能用于其它目的:如作為一個(gè)鬧
鈴,用于測(cè)量時(shí)間等。要注意的是,當(dāng)處理器在調(diào)試期間被喊停(halt)時(shí),則
SysTick 定時(shí)器亦將暫停運(yùn)作。
Q:Systick如何運(yùn)行?
首先設(shè)置計(jì)數(shù)器時(shí)鐘源,CTRL->CLKSOURCE(控制寄存器)。設(shè)置重載值(R
ELOAD 寄存器),清空計(jì)數(shù)寄存器VAL(就是下圖的CURRENT)。置CTRL
->ENABLE 位開始計(jì)時(shí)。
如果是中斷則允許Systick 中斷,在中斷例程中處理。如采用查詢模式則不斷讀
取控制寄存器的COUNTFLAG 標(biāo)志位,判斷是否計(jì)時(shí)至零?;蛘卟扇∠铝幸环N
方法
當(dāng)SysTick 定時(shí)器從1 計(jì)到0 時(shí),它將把COUNTFLAG 位置位;而下述方法
可以清零之:
1. 讀取SysTick 控制及狀態(tài)寄存器(STCSR)
2. 往SysTick 當(dāng)前值寄存器(STCVR)中寫任何數(shù)據(jù)
只有當(dāng)VAL 值為0 時(shí),計(jì)數(shù)器自動(dòng)重載RELOAD。
SysTick 的最大使命,就是定期地產(chǎn)生異常請(qǐng)求,作為系統(tǒng)的時(shí)基。OS 都需要
這種“滴答”來(lái)推動(dòng)任務(wù)和時(shí)間的管理。如欲使能SysTick 異常,則把STCSR.TI
CKINT 置位。另外,如果向量表被重定位到SRAM 中,還需要為SysTick 異
常建立向量,提供其服務(wù)例程的入口地址。

中斷方式參考:

void RCC_Configuration(void)

{

RCC_DeInit();

RCC_HSEConfig(RCC_HSE_ON);

HSEStartUpStatus = RCC_WaitForHSEStartUp();

if(HSEStartUpStatus == SUCCESS)

{

FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1);

RCC_PCLK2Config(RCC_HCLK_Div1);

RCC_PCLK1Config(RCC_HCLK_Div2);

RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

RCC_PLLCmd(ENABLE);

while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

{

}

RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

while(RCC_GetSYSCLKSource() != 0x08)

{

}

}

}

配置具體的systick()

void InitSysTick(void)

{

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);//系統(tǒng)時(shí)鐘72MH,除以8后systick時(shí)鐘為9MH。

SysTick_SetReload(9000); //t = 9000/9000000 = 1ms

SysTick_CounterCmd(SysTick_Counter_Enable);

SysTick_ITConfig(ENABLE);

}

中斷的入口就在:SysTickHandler()

void SysTickHandler(void)

{

Fuction();/./所需功能函數(shù)

}



關(guān)鍵詞: STM32F103systic

評(píng)論


技術(shù)專區(qū)

關(guān)閉