STM32学习笔记9(SysTick滴答时钟)
我不得不說意法半導(dǎo)體確實(shí)有點(diǎn)風(fēng)騷!甚至有點(diǎn)變態(tài)。我對(duì)ST文檔?STM32F10XXX參考手冊(cè)的編輯水平真是不敢恭維。手冊(cè)中好多說明都是含糊不清,甚至將好多對(duì)初學(xué)者來說很重要的地方都一筆帶過,讓人著實(shí)摸不著頭腦。比如前面我說過的關(guān)于NVIC嵌套向量中斷控制器的介紹,這部分我認(rèn)為是非常重要的,但當(dāng)你看完他這部分介紹,你根本不會(huì)設(shè)置中斷服務(wù)程序,他有哪些寄存器都不知道,更別說去設(shè)置了,NVIC的詳細(xì)介紹是在Cotex-M3中有詳細(xì)的介紹,不多說。今天我們說的是systick定時(shí)器。
systick定時(shí)器和我上面說的情況一樣,在手冊(cè)中根本沒有介紹。我費(fèi)了九牛二虎之力才在一個(gè)犄角格拉里找到systick定時(shí)器的英文版的說明。在Cotex-M3有介紹,為什么要找STM32的介紹,是因?yàn)楣δ茉O(shè)置上還有點(diǎn)區(qū)別。首先看一下systick定時(shí)器的作用,下面是Cotex-M3里的一段話:
SysTick定時(shí)器被捆綁在NVIC中,用于產(chǎn)生SYSTICK異常(異常號(hào):15)。在以前,大多操作系統(tǒng)需要一個(gè)硬件定時(shí)器來產(chǎn)生操作系統(tǒng)需要的滴答中斷,作為整個(gè)系統(tǒng)的時(shí)基。例如,為多個(gè)任務(wù)許以不同數(shù)目的時(shí)間片,確保沒有一個(gè)任務(wù)能霸占系統(tǒng);或者把每個(gè)定時(shí)器周期的某個(gè)時(shí)間范圍賜予特定的任務(wù)等,還有操作系統(tǒng)提供的各種定時(shí)功能,都與這個(gè)滴答定時(shí)器有關(guān)。因此,需要一個(gè)定時(shí)器來產(chǎn)生周期性的中斷,而且最好還讓用戶程序不能隨意訪問它的寄存器,以維持操作系統(tǒng)“心跳”的節(jié)律。
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í)鐘(?CM3處理器上的STCLK信號(hào))。不過,STCLK的具體來源則由芯片設(shè)計(jì)者決定,因此不同產(chǎn)品之間的時(shí)鐘頻率可能會(huì)大不相同,你需要檢視芯片的器件手冊(cè)來決定選擇什么作為時(shí)鐘源。(知道我為什么找ST關(guān)于systick的說明了吧)。
下面介紹STM32中的systick,Systick?部分內(nèi)容屬于NVIC控制部分,一共有4個(gè)寄存器,名稱和地址分別是:
STK_CSR,? ?? ???0xE000E010??--??控制寄存器
STK_LOAD,? ???0xE000E014??--??重載寄存器
STK_VAL,? ?? ???0xE000E018??--??當(dāng)前值寄存器
STK_CALRB,? ?0xE000E01C??--? ?校準(zhǔn)值寄存器
首先看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)清零
STK_LOAD ?重載寄存器:
?
Systick是一個(gè)遞減的定時(shí)器,當(dāng)定時(shí)器遞減至0時(shí),重載寄存器中的值就會(huì)被重裝載,繼續(xù)開始遞減。STK_LOAD ?重載寄存器是個(gè)24位的寄存器最大計(jì)數(shù)0xFFFFFF。
?
STK_VAL當(dāng)前值寄存器:
?
也是個(gè)24位的寄存器,讀取時(shí)返回當(dāng)前倒計(jì)數(shù)的值,寫它則使之清零,同時(shí)還會(huì)清除在SysTick?控制及狀態(tài)寄存器中的COUNTFLAG?標(biāo)志。
STK_CALRB ?校準(zhǔn)值寄存器:
?
這個(gè)寄存器好像目前的水平我還用不到,大體意思明白點(diǎ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.
SysTick定時(shí)器除了能服務(wù)于操作系統(tǒng)之外,還能用于其它目的:如作為一個(gè)鬧鈴,用于測(cè)量時(shí)間等。要注意的是,當(dāng)處理器在調(diào)試期間被喊停(halt)時(shí),則SysTick定時(shí)器亦將暫停運(yùn)作。
下面我們就應(yīng)用SysTick定時(shí)器來裸奔,把它作為一個(gè)定時(shí)器來用,還是老一套,在寄存器頭文件中添加定義寄存器:
//*****************************************************************
//*???????????????????????????????SystemTick-Register?????????????????????????????????
//*******************************************************************
#define SYSTICK_TENMS????(*((volatile unsigned long *)0xE000E01C))
#define SYSTICK_CURRENT??(*((volatile unsigned long *)0xE000E018))
#define SYSTICK_RELOAD???(*((volatile unsigned long *)0xE000E014))
#define SYSTICK_CSR???????(*((volatile unsigned long *)0xE000E010))
?
配置systick寄存器:
void SysTick_Configuration(void)
{
???SYSTICK_CURRENT=0; //當(dāng)前值寄存器
???SYSTICK_RELOAD=20000; //重裝載寄存器,系統(tǒng)時(shí)鐘20M中斷一次1mS
???SYSTICK_CSR|=0x06;//?HCLK作為Systick時(shí)鐘,Systick中斷使能位
?}
中斷處理:
void SysTick_Handler(void) //中斷函數(shù)
{
extern unsigned long TimingDelay;?// 延時(shí)時(shí)間,注意定義為全局變量
?
SYSTICK_CURRENT=0;
if (TimingDelay != 0x00)
TimingDelay--;
}
利用systick的延時(shí)函數(shù):
?
unsigned long TimingDelay;??// 延時(shí)時(shí)間,注意定義為全局變量
void Delay(unsigned long nTime)??//延時(shí)函數(shù)
{
SYSTICK_CSR|=0x07;???//?使能SysTick計(jì)數(shù)器
TimingDelay = nTime; //?讀取延時(shí)時(shí)間
while(TimingDelay != 0); //?判斷延時(shí)是否結(jié)束
SYSTICK_CSR|=0x06;//?關(guān)閉SysTick計(jì)數(shù)器
}
?
int main()
?{
??SystemInit0();????//系統(tǒng)(時(shí)鐘)初始化
?stm32_GpioSetup (); //GPIO初始化
?
??SysTick_Configuration(); //配置systick定時(shí)器
?while(1)
?{
??GPIO_PORTB_ODR|=(1<<5);
Delay(1000); //1S
?GPIO_PORTB_ODR&=~(1<<5);
?Delay(1000); //1S?????????????????????????????????????????????????????????????????????????????
??}
}
完成!Delay(1000);實(shí)現(xiàn)了1S的精確延時(shí),利用Delay(unsigned long nTime);配合systick定時(shí)器可以實(shí)現(xiàn)任意時(shí)間的精確延時(shí),當(dāng)然通過定時(shí)器TIMx也是可以這樣做的,我只是用它來說明systick定時(shí)器的用法。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/dustinzhu/p/4149906.html
總結(jié)
以上是生活随笔為你收集整理的STM32学习笔记9(SysTick滴答时钟)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 青松是谁写的啊?
- 下一篇: C语言对mysql数据库的操作