娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

GD32開發實戰指南(基礎篇) 第5章 跳動的心臟-Systick

發布者:心靈之旅最新更新時間:2024-11-08 來源: elecfans關鍵字:GD32  開發實戰  Systick 手機看文章 掃描二維碼
隨時隨地手機看文章

開發環境:

MDK:Keil 5.30

開發板:GD32F207I-EVAL

MCU:GD32F207IK

Cortex-M的內核中包含Systick定時器了,只要是Cortex-M系列的MCU就會有Systick,因此這是通用的,下面詳細分析。


1 Systick工作原理分析

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

1683642280703y06zbdqjnq

Cortex-M3 在內核部分包含了一個簡單的定時器——SysTick。因為所有的 CM3 芯片都帶有這個定時器,軟件在不同芯片生產廠商的 CM3 器件間的移植工作就得以簡化。該定時器的時鐘源可以是內部時鐘(FCLK,CM3 上的自由運行時鐘),或者是外部時鐘。不過,外部時鐘的具體來源則由芯片設計者決定,因此不同產品之間的時鐘頻率可能大不相同。因此,需要閱讀芯片的使用手冊來確定選擇什么作為時鐘源。在 GD32 中SysTick 以 HCLK(AHB 時鐘)或 HCLK/8 作為運行時鐘,見上圖。

SysTick 定時器能產生中斷,CM3 為它專門開出一個異常類型,并且在向量表中有它的一席之地。它使操作系統和其他系統軟件在 CM3 器件間的移植變得簡單多了,因為在所有 CM3 產品間,SysTick 的處理方式都是相同的。SysTick 定時器除了能服務于操作系統之外,還能用于其他目的,如作為一個鬧鈴、用于測量時間等。 Systick 定時器屬于Cortex 內核部件 ,可以參考《ARM Cortex-M3 權威指南》((英)JosephYiu 著,宋巖譯,北京航空航天大學出版社出版)來了解。

2 Systick寄存器分析

在傳統的嵌入式系統軟件按中通常實現 Delay(N) 函數的方法為:

for(i = 0; i <= x; i ++);

x --- ;

對于GD32系列微處理器來說,執行一條指令只有幾十個 ns,進行 for 循環時,要實現 N 毫秒的 x 值非常大,而且由于系統頻率的寬廣,很難計算出延時 N 毫秒的精確值。針對GD32 微處理器,需要重新設計一個新的方法去實現該功能,以實現在程序中使用 Delay(N)。

Cortex-M3 的內核中包含一個 SysTick 時鐘。SysTick 為一個 24 位遞減計數器,SysTick 設定初值并使能后,每經過 1 個系統時鐘周期,計數值就減 1。計數到 0 時,SysTick 計數器自動重裝初值并繼續計數,同時內部的 COUNTFLAG 標志會置位,觸發中斷 (如果中斷使能情況下)。

在 GD32 的應用中,使用 Cortex-M3 內核的 SysTick 作為定時時鐘,設定每一毫秒產生一次中斷,在中斷處理函數里對 N 減一,在Delay(N) 函數中循環檢測 N 是否為 0,不為 0 則進行循環等待;若為 0 則關閉 SysTick 時鐘,退出函數。

注: 全局變量 TimingDelay , 必須定義為 volatile 類型 , 延遲時間將不隨系統時鐘頻率改變。

Cortex-M3中的Systick部分內容屬于NVIC控制部分,一共有4個寄存器,名稱和地址分別是:

  • STK_CTRL,0xE000E010--控制寄存器

1683642281331ygg5hvor5x

第0位:ENABLE,Systick 使能位

(0:關閉Systick功能;1:開啟Systick功能)

第1位:TICKINT,Systick 中斷使能位

(0:關閉Systick中斷;1:開啟Systick中斷)

第2位:CLKSOURCE,Systick時鐘源選擇

(0:使用HCLK/8 作為Systick時鐘;1:使用HCLK作為Systick時鐘)

第16位:COUNTFLAG,Systick計數比較標志,如果在上次讀取本寄存器后,SysTick 已經數到了0,則該位為1。如果讀取該位,該位將自動清零

  • STK_LOAD, 0xE000E014--重載寄存器

1683642281747f5i5uqwxre

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

  • STK_VAL, 0xE000E018--當前值寄存器

1683642282071e7f33le3xp

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

  • STK_CALRB, 0xE000E01C--校準值寄存器

1683642282361vwfhmxvgzx

校準值寄存器提供了這樣一個解決方案:它使系統即使在不同的CM3產品上運行,也能產生恒定的SysTick中斷頻率。最簡單的作法就是:直接把TENMS的值寫入重裝載寄存器,這樣一來,只要沒突破系統極限,就能做到每10ms來一次 SysTick異常。如果需要其它的SysTick異常周期,則可以根據TENMS的值加以比例計算。只不過,在少數情況下, CM3芯片可能無法準確地提供TENMS的值(如, CM3的校準輸入信號被拉低),所以為保險起見,最好在使用TENMS前檢查器件的參考手冊。


SysTick定時器除了能服務于操作系統之外,還能用于其它目的:如作為一個鬧鈴,用于測量時間等。要注意的是,當處理器在調試期間被喊停( halt)時,則SysTick定時器亦將暫停運作。


3 Systick定時器實現

SysTick屬于Cortex-M內核的部分,因此其相關的定義在core_cm3.h文件中。


3.1 main文件分析

主函數如下:


/*

    brief      main function

    param[in]  none

    param[out] none

    retval     none

*/

int main(void)

{

    //systick init

    sysTick_init();

    /* configure LED1 GPIO port */

    led_init(LED1);


    /* configure LED2 GPIO port */

    led_init(LED2);


    /* configure LED3 GPIO port */

    led_init(LED3);


    /* configure LED4 GPIO port */

    led_init(LED4);


    while(1) 

    {

        /* turn on LED1, turn off LED4 */

        led_on(LED1);

        led_off(LED4);

        /*delay 500ms*/

        delay_ms(500);


        /* turn on LED2, turn off LED1 */

        led_on(LED2);

        led_off(LED1);

        /*delay 500ms*/

        delay_ms(500);


        /* turn on LED3, turn off LED2 */

        led_on(LED3);

        led_off(LED2);

        /*delay 500ms*/

        delay_ms(500);


        /* turn on LED4, turn off LED3 */

        led_on(LED4);

        led_off(LED3);

        /*delay 500ms*/

        delay_ms(500);

    }

}

在 main 函數中,sysTick_init和 delay_us() 這兩個函數比較陌生,它們的功能分別是配置好 SysTick 定時器和進行精確延時。整個 main 函數的流程就是初始化 LED 及SysTick 定時器之后,就進入死循環,點亮LED的時間為精確的 500 ms。


3.2 gd32f207i_systick_eval.c文件分析

配置并啟動 SysTick

我們看一下systick_init()這個函數,其功能是啟動系統滴答定時器 SysTick。


/*

    brief      SysTick init

    param[in]  none

    param[out] none

    retval     none

*/

void sysTick_init(void)

{

/* SystemFrequency / 1000    1ms中斷一次

  * SystemFrequency / 100000  10us中斷一次

  * SystemFrequency / 1000000 1us中斷一次

  */

    /* setup systick timer for 1000Hz interrupts */

    if(SysTick_Config(SystemCoreClock / 100000U)){

        /* capture error */

        while(1){

        }

    }


    // 關閉滴答定時器  

    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;


    /* configure the systick handler priority */

    NVIC_SetPriority(SysTick_IRQn, 0x00U);

}

本函數實際上只是調用了 SysTick_Config() 函數,它是屬于內核層的 Cortex-M3 通用函數,位于 core_cm3.h 文件中。若調用 SysTick_Config() 配置 SysTick 不成功,則進入死循環,初始化 SysTick 成功后,先關閉定時器,在需要的時候再開啟。SysTick_Config() 函數無法在GD32 外設固件庫文件中找到其使用方法。所以我們在 Keil 環境下直接跟蹤這個函數到 core_cm3.h 文件,查看函數的定義。


/** \brief  System Tick Configuration


    The function initializes the System Timer and its interrupt, and starts the System Tick Timer.

    Counter is in free running mode to generate periodic interrupts.


    \param [in]  ticks  Number of ticks between two interrupts.


    \return          0  Function succeeded.

    \return          1  Function failed.


    \note     When the variable __Vendor_SysTickConfig is set to 1, then the

    function SysTick_Config is not included. In this case, the file device.h

    must contain a vendor-specific implementation of this function.


 */

__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)

{

  if ((ticks - 1) > SysTick_LOAD_RELOAD_Msk)  return (1);      /* Reload value impossible */


  SysTick->LOAD  = ticks - 1;                                  /* set reload register */

  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Systick Interrupt */

  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */

  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |

                   SysTick_CTRL_TICKINT_Msk   |

                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */

  return (0);                                                  /* Function successful */

}

在這個函數定義的前面有關于它的注釋,如果我們不想去研究它的具體實現,可以根據這段注釋了解函數的功能 :這個函數啟動了 SysTick ;并把它配置為計數至 0 時引起中斷 ;輸入的參數 ticks 為兩個中斷之間的脈沖數,即相隔 ticks 個時鐘周期會引起一次中斷 ;配置 SysTick 成功時返回 0,出錯時返回 1。但是,這段注釋并沒有告訴我們它把 SysTick 的時鐘設置為 AHB 時鐘還是 AHB/8,這是一個十分關鍵的問題,于是,我們將對這個函數的具體實現進行分析,與大家再分享一下如何分析底層庫函數。分析底層庫函數,要有 SysTick 定時器工作分析的知識準備。


檢查輸入參數

SysTick_Config() 第 3 行代碼是檢查輸入參數 ticks,因為 ticks 是脈沖計數值,要被保存到重載寄存器 STK_LOAD 寄存器中,再由硬件把 STK_LOAD 值加載到當前計數值寄存器 STK_VAL 中使用,STK_LOAD 和 STK_VAL 都是 24 位的,所以當輸入參數 ticks 大于其可存儲的最大值時,將由這行代碼檢查出錯誤并返回。


位指示宏及位屏蔽宏

檢查 ticks 參數沒有錯誤后,就稍稍處理一下把 ticks-1 賦值給 STK_LOAD 寄存器,要注意的是減 1,若 STK_VAL 從 ticks?1 向下計數至 0,實際上就經過了 ticks 個脈沖。這句賦值代碼使用了宏 SysTick_LOAD_RELOAD_Msk,與其他庫函數類似,這個宏是用來指示寄存器的特定位置或進行位屏蔽的。


/* SysTick Control / Status Register Definitions */

#define SysTick_CTRL_COUNTFLAG_Pos         16                                             /*!< SysTick CTRL: COUNTFLAG Position */

#define SysTick_CTRL_COUNTFLAG_Msk         (1ul << SysTick_CTRL_COUNTFLAG_Pos)            /*!< SysTick CTRL: COUNTFLAG Mask */


#define SysTick_CTRL_CLKSOURCE_Pos          2                                             /*!< SysTick CTRL: CLKSOURCE Position */

#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)            /*!< SysTick CTRL: CLKSOURCE Mask */


#define SysTick_CTRL_TICKINT_Pos            1                                             /*!< SysTick CTRL: TICKINT Position */

#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)              /*!< SysTick CTRL: TICKINT Mask */


#define SysTick_CTRL_ENABLE_Pos             0                                             /*!< SysTick CTRL: ENABLE Position */

#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos)               /*!< SysTick CTRL: ENABLE Mask */


/* SysTick Reload Register Definitions */

#define SysTick_LOAD_RELOAD_Pos             0                                             /*!< SysTick LOAD: RELOAD Position */

[1] [2]
關鍵字:GD32  開發實戰  Systick 引用地址:GD32開發實戰指南(基礎篇) 第5章 跳動的心臟-Systick

上一篇:【技術分享】星空派GD32開發板LVGL移植經驗分享
下一篇:keil中GD32 MCU IAP中APP的存儲地址如何設置?

推薦閱讀最新更新時間:2025-04-16 16:03

GD32開發實戰指南(基礎篇) 第5章 跳動心臟-Systick
開發環境: MDK:Keil 5.30 開發板:GD32F207I-EVAL MCU:GD32F207IK Cortex-M的內核中包含Systick定時器了,只要是Cortex-M系列的MCU就會有Systick,因此這是通用的,下面詳細分析。 1 Systick工作原理分析 SysTick 定時器被捆綁在 NVIC 中,用于產生 SysTick 異常(異常號 :15)。在以前,操作系統和所有使用了時基的系統都必須有一個硬件定時器來產生需要的“滴答”中斷,作為整個系統的時基。滴答中斷對操作系統尤其重要。例如,操作系統可以為多個任務分配不同數目的時間片,確保沒有一個任務能霸占系統 ;或者將每個定時器周期的某個時間范圍賜予特定的
[單片機]
GD32 MCU 入門教程】GD32 MCU 常見外設介紹(4)EXTI 中斷介紹
EXTI(中斷/事件控制器)包含多個相互獨立的邊沿檢測電路并且能夠向處理器內核產生中斷請求或喚醒事件。 EXTI 有三種觸發類型:上升沿觸發、下降沿觸發和任意沿觸發。 EXTI中的每一個邊沿檢測電路都可以獨立配置和屏蔽。 4.1.GD32 EXTI 外設原理簡介 GD32 EXTI 主要特性(以 GD32F30x 為例) ? 高效的中斷處理; ? 支持異常搶占和咬尾中斷; ? 將系統從省電模式喚醒; ? 3 種觸發類型:上升沿觸發,下降沿觸發和任意沿觸發; ? 軟件中斷或事件觸發; ? 可配置的觸發源; ? Cortex-M4系統異常; ? 多達68種可屏蔽的外設中斷; ? 4位中斷優先級配置位,可配置16個中斷優先級; ? EX
[單片機]
【<font color='red'>GD32</font> MCU 入門教程】<font color='red'>GD32</font> MCU 常見外設介紹(4)EXTI 中斷介紹
stm32f4使用Systick實現延時
使用Systick定時器實現延時 一、SysTick定時器特性 SysTick定時器是一個24位的遞減計數器,即vlue自減等于0時觸發中斷,并重新加載load值,如此循環。 在stm32f4庫文件中,默認將優先級設置為最低優先級,可進入函數SysTick_Config查看優先級設置。 SysTick是Cortex-M內核的一部分,因此只要是Cortex-M內核都有該定時器。 SysTick的時鐘源可由HCLK產生,或則HCLK/8產生。 二、如何使用SysTick定時器 既然是定時器,那么至少應該設置2方面內容: 1. 定時時間 2. 定時時間到后做什么。 三、程序解析 1. SysTick定時器初始化
[單片機]
STM32之用SysTick做準確定時
SysTick,ST的數據手冊上稍微提了一下但是沒有詳細介紹,這里我們仔細研究下。如有錯誤之處敬請更正。 SysTick位于NVIC中,它主要應用在操作系統中,所以平常我們用的很少,但是我們可以用它來做簡單的延時,還是比較準確的。 那我們先看一下跟他相關的寄存器吧: 主要有四個寄存器:CTRL,RELOAD,VAL,CALIB CALIB我們一般不用,所以就不做介紹了。 對CTRL的操作實際就是設置SysTick的時鐘,以及使能等。 對LOAD的操作就是填充新的計數值 對VAL的操作時設置計數滿后的操作 學習最快最感性的莫過于實例了,那我們就通過一個例子來學習SysTick 那我們先說下思路,延
[單片機]
STM32之用<font color='red'>SysTick</font>做準確定時
兆易創新推出GD32H737/757/759系列Cortex?-M7內核超高性能MCU
中國北京(2023年5月11日) — 業界領先的半導體器件供應商兆易創新GigaDevice(股票代碼 603986)今日宣布,正式推出中國首款基于Arm? Cortex?-M7內核的GD32H737/757/759系列超高性能微控制器 。 GD32H7系列MCU具備卓越的處理能效、豐富連接特性及多重安全機制,以先進工藝制程和優化的成本控制,全面釋放高級應用的創新潛力。 全新產品組合包括3個系列共27個型號,提供176腳和100腳BGA封裝,176腳、144腳和100腳LQFP封裝等五種選擇,將于5月底陸續開放樣片和開發板卡申請,10月起正式量產供貨。 GD32H7可廣泛用于數字信號處理、電機變頻、電源、儲能系統、無人機、
[嵌入式]
兆易創新推出GD32H737/757/759系列Cortex?-M7內核超高性能MCU
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 沁水县| 元氏县| 泰州市| 米泉市| 勃利县| 磴口县| 天镇县| 锦屏县| 江口县| 临武县| 抚松县| 乐东| 苍梧县| 蒙城县| 客服| 达州市| 安徽省| 汶上县| 顺义区| 锦州市| 崇信县| 铁岭市| 紫金县| 车致| 绥宁县| 中宁县| 大石桥市| 汕尾市| 金平| 松溪县| 徐闻县| 贺州市| 大渡口区| 深泽县| 靖州| 葫芦岛市| 广饶县| 东莞市| 通山县| 甘肃省| 万全县|