久久ER99热精品一区二区-久久精品99国产精品日本-久久精品免费一区二区三区-久久综合九色综合欧美狠狠

專欄中心

EEPW首頁 > 專欄 > STM32學習筆記9(SysTick滴答時鐘)

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

發布人:電子禪石 時間:2019-11-02 來源:工程師 發布文章
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定時器的用法。

 

/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2017-07-24     Tanek        the first version
 * 2018-11-12     Ernest Chen  modify copyright
 */
#include <rthw.h>
#include <rtthread.h>
#define _SCB_BASE       (0xE000E010UL)
#define _SYSTICK_CTRL   (*(rt_uint32_t *)(_SCB_BASE + 0x0))
#define _SYSTICK_LOAD   (*(rt_uint32_t *)(_SCB_BASE + 0x4))
#define _SYSTICK_VAL    (*(rt_uint32_t *)(_SCB_BASE + 0x8))
#define _SYSTICK_CALIB  (*(rt_uint32_t *)(_SCB_BASE + 0xC))
#define _SYSTICK_PRI    (*(rt_uint8_t  *)(0xE000ED23UL))
// Updates the variable SystemCoreClock and must be called 
// whenever the core clock is changed during program execution.
extern void SystemCoreClockUpdate(void);
// Holds the system core clock, which is the system clock 
// frequency supplied to the SysTick timer and the processor 
// core clock.
//extern uint32_t SystemCoreClock;
uint32_t SystemCoreClock = 180000000;
static uint32_t _SysTick_Config(rt_uint32_t ticks)
{
    if ((ticks - 1) > 0xFFFFFF)
    {
        return 1;
    }
    
    _SYSTICK_LOAD = ticks - 1; 
    _SYSTICK_PRI = 0xFF;
    _SYSTICK_VAL  = 0;
    _SYSTICK_CTRL = 0x07;  
    
    return 0;
}
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
#define RT_HEAP_SIZE 1536
static uint32_t rt_heap[RT_HEAP_SIZE]; // heap default size: 6K(1536 * 4)
RT_WEAK void *rt_heap_begin_get(void)
{
    return rt_heap;
}
RT_WEAK void *rt_heap_end_get(void)
{
    return rt_heap + RT_HEAP_SIZE;
}
#endif
/**
 * This function will initial your board.
 */
void rt_hw_board_init()
{ 
 /* System Clock Update */
 SystemCoreClockUpdate();
 
 /* System Tick Configuration */
 _SysTick_Config(SystemCoreClock / RT_TICK_PER_SECOND);
    /* Call components board initial (use INIT_BOARD_EXPORT()) */
#ifdef RT_USING_COMPONENTS_INIT
   // rt_components_board_init();
#endif
    
#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
 rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
    
#if defined(RT_USING_USER_MAIN) && defined(RT_USING_HEAP)
    rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif
}
void SysTick_Handler(void)
{
 extern unsigned long TimingDelay; // 延時時間,注意定義為全局變量
 
_SYSTICK_VAL =0;
if (TimingDelay != 0x00)
TimingDelay--;
 /* enter interrupt */
 //rt_interrupt_enter();
 //rt_tick_increase();
 /* leave interrupt */
 //rt_interrupt_leave();
}
unsigned long TimingDelay;  // 延時時間,注意定義為全局變量
void Delay(unsigned long nTime)  //延時函數
{
_SYSTICK_CTRL |=0x07;   // 使能SysTick計數器
TimingDelay = nTime; // 讀取延時時間
while(TimingDelay != 0); // 判斷延時是否結束
_SYSTICK_CTRL|=0x06;// 關閉SysTick計數器
}



*博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。

關鍵詞:

相關推薦

LabVIEW網絡講壇第三季——第九期:子面板技術探究

視頻 2009-06-09

SiC和GaN技術重塑電力電子行業前景

新加坡延長電動車補貼政策,中國車企迎來新機遇

LabVIEW網絡講壇第三季——第八期:生產者/消費者循環(下)

視頻 2009-06-09

LabVIEW網絡講壇第三季——第七期:生產者/消費者循環(中)

視頻 2009-06-09

替代電池解決方案之路:超越鋰,創造可持續的未來

模擬電子:現代傳感器的永恒支柱

使用PWM得到精密的輸出電壓

生成式人工智能提高芯片良率并減少制造缺陷

重新構想人機交互:力傳感作為HMI的新前沿

機器人 2025-09-15

LabVIEW網絡講壇第三季——第六期:生產者/消費者循環(上)

視頻 2009-06-09

實用電源電路集錦

Intuitive 為達芬奇 5 手術機器人增加了實時手術洞察

芯原股份收購芯來科技,AI算力訂單創新高

美光凍結價格,推理 AI 推動 SSD 需求激增及供應短缺

網絡與存儲 2025-09-15

LabVIEW網絡講壇第三季——第五期:LabVIEW狀態圖(下)

視頻 2009-06-09

軟開關雙管正激電源設計方案(英文)

使用電流反饋放大器的有源濾波器

三星泰勒廠面臨簽證難題,恐影響2026年投產計劃

EDA/PCB 2025-09-15
更多 培訓課堂
更多 焦點
更多 視頻

技術專區