STM32學習筆記9(SysTick滴答時鍾)


我不得不說意法半導體確實有點風騷!甚至有點變態。我對ST文檔 STM32F10XXX參考手冊的編輯水平真是不敢恭維。手冊中好多說明都是含糊不清,甚至將好多對初學者來說很重要的地方都一筆帶過,讓人着實摸不着頭腦。比如前面我說過的關於NVIC嵌套向量中斷控制器的介紹,這部分我認為是非常重要的,但當你看完他這部分介紹,你根本不會設置中斷服務程序,他有哪些寄存器都不知道,更別說去設置了,NVIC的詳細介紹是在Cotex-M3中有詳細的介紹,不多說。今天我們說的是systick定時器。

systick定時器和我上面說的情況一樣,在手冊中根本沒有介紹。我費了九牛二虎之力才在一個犄角格拉里找到systick定時器的英文版的說明。在Cotex-M3有介紹,為什么要找STM32的介紹,是因為功能設置上還有點區別。首先看一下systick定時器的作用,下面是Cotex-M3里的一段話:

SysTick定時器被捆綁在NVIC中,用於產生SYSTICK異常(異常號:15)。在以前,大多操作系統需要一個硬件定時器來產生操作系統需要的滴答中斷,作為整個系統的時基。例如,為多個任務許以不同數目的時間片,確保沒有一個任務能霸占系統;或者把每個定時器周期的某個時間范圍賜予特定的任務等,還有操作系統提供的各種定時功能,都與這個滴答定時器有關。因此,需要一個定時器來產生周期性的中斷,而且最好還讓用戶程序不能隨意訪問它的寄存器,以維持操作系統“心跳”的節律。

Cortex‐M3處理器內部包含了一個簡單的定時器。因為所有的CM3芯片都帶有這個定時器,軟件在不同 CM3器件間的移植工作得以化簡。該定時器的時鍾源可以是內部時鍾(FCLK,CM3上的自由運行時鍾),或者是外部時鍾( CM3處理器上的STCLK信號)。不過,STCLK的具體來源則由芯片設計者決定,因此不同產品之間的時鍾頻率可能會大不相同,你需要檢視芯片的器件手冊來決定選擇什么作為時鍾源。(知道我為什么找ST關於systick的說明了吧)。

下面介紹STM32中的systick,Systick 部分內容屬於NVIC控制部分,一共有4個寄存器,名稱和地址分別是:

STK_CSR,        0xE000E010  --  控制寄存器
STK_LOAD,     0xE000E014  --  重載寄存器
STK_VAL,        0xE000E018  --  當前值寄存器
STK_CALRB,   0xE000E01C  --   校准值寄存器

首先看STK_CSR控制寄存器:寄存器內有4個位t具有意義

 

第0位:ENABLE,Systick 使能位  (0:關閉Systick功能;1:開啟Systick功能)
第1位:TICKINT,Systick 中斷使能位    (0:關閉Systick中斷;1:開啟Systick中斷)
第2位:CLKSOURCE,Systick時鍾源選擇  (0:使用HCLK/8 作為Systick時鍾;1:使用HCLK作為Systick時鍾)
第3位:COUNTFLAG,Systick計數比較標志,如果在上次讀取本寄存器后,SysTick 已經數到了0,則該位為1。如果讀取該位,該位將自動清零

STK_LOAD  重載寄存器:

 

Systick是一個遞減的定時器,當定時器遞減至0時,重載寄存器中的值就會被重裝載,繼續開始遞減。STK_LOAD  重載寄存器是個24位的寄存器最大計數0xFFFFFF

 

STK_VAL當前值寄存器:

 

也是個24位的寄存器,讀取時返回當前倒計數的值,寫它則使之清零,同時還會清除在SysTick 控制及狀態寄存器中的COUNTFLAG 標志。

STK_CALRB  校准值寄存器:

 

這個寄存器好像目前的水平我還用不到,大體意思明白點,把英文說明放這吧:

位31 NOREF :1=沒有外部參考時鍾(STCLK 不可用)0=外部參考時鍾可用

位30 SKEW:1=校准值不是准確的1ms 0=校准值是准確的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定時器除了能服務於操作系統之外,還能用於其它目的:如作為一個鬧鈴,用於測量時間等。要注意的是,當處理器在調試期間被喊停(halt)時,則SysTick定時器亦將暫停運作。

下面我們就應用SysTick定時器來裸奔,把它作為一個定時器來用,還是老一套,在寄存器頭文件中添加定義寄存器:

//*****************************************************************

//*                               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; //當前值寄存器

   SYSTICK_RELOAD=20000; //重裝載寄存器,系統時鍾20M中斷一次1mS

   SYSTICK_CSR|=0x06;// HCLK作為Systick時鍾,Systick中斷使能位

 }

中斷處理:

void SysTick_Handler(void) //中斷函數

{

extern unsigned long TimingDelay; // 延時時間,注意定義為全局變量

 

SYSTICK_CURRENT=0;

if (TimingDelay != 0x00)

TimingDelay--;

}

利用systick的延時函數:

 

unsigned long TimingDelay;  // 延時時間,注意定義為全局變量

void Delay(unsigned long nTime)  //延時函數

{

SYSTICK_CSR|=0x07;   // 使能SysTick計數器

TimingDelay = nTime; // 讀取延時時間

while(TimingDelay != 0); // 判斷延時是否結束

SYSTICK_CSR|=0x06;// 關閉SysTick計數器

}

 

int main()

 {

  SystemInit0();    //系統(時鍾)初始化

 stm32_GpioSetup (); //GPIO初始化

 

  SysTick_Configuration(); //配置systick定時器

 while(1)

 {

  GPIO_PORTB_ODR|=(1<<5);

Delay(1000); //1S

 GPIO_PORTB_ODR&=~(1<<5);

 Delay(1000); //1S                                                                             

  }

}

完成!Delay(1000);實現了1S的精確延時,利用Delay(unsigned long nTime);配合systick定時器可以實現任意時間的精確延時,當然通過定時器TIMx也是可以這樣做的,我只是用它來說明systick定時器的用法。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM