1. 程式人生 > >STM32—SysTick使用方法

STM32—SysTick使用方法

 一、STM32的SysTick簡介

  SysTick是一個24位的系統節拍定時器system tick timer,SysTick,具有自動過載和溢位中斷功能,所有基於Cortex_M3處理器的微控制器都可以由這個定時器獲得一定的時間間隔。

systick的作用:

  在單任務引用程式中,因為其架構就決定了它執行任務的序列性,這就引出一個問題:當某個任務出現問題時,就會牽連到後續的任務,進而導致整個系統崩潰。要解決這個問題,可以使用實時作業系統(RTOS).

  因為RTOS以並行的架構處理任務,單一任務的崩潰並不會牽連到整個系統。這樣使用者出於可靠性的考慮可能就會基於RTOS來設計自己的應用程式。這樣SYSTICK存在的意義就是提供必要的時鐘節拍,為RTOS的任務排程提供一個有節奏的“心跳”。

  微控制器的定時器資源一般比較豐富,比如STM32存在8個定時器,為啥還要再提供一個SYSTICK?原因就是所有基於ARM Cortex_M3核心的控制器都帶有SysTick定時器,這樣就方便了程式在不同的器件之間的移植。而使用RTOS的第一項工作往往就是將其移植到開發人員的硬體平臺上,由於SYSTICK的存在無疑降低了移植的難度。

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

systick的時鐘選擇:

二、SYSTICK的暫存器

三、SYSTICK的配置和函式解析

SysTick定時器的使用主要有HAL_SYSTICK_Config()函式和HAL_SYSTICK_CLKSourceConfig()函式。如下,

    /**Configure the Systick interrupt time 
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);// 設定定時時間

    /**Configure the Systick 
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//選擇SYSTICK時鐘源,
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);//設定優先順序

Systick定時時間的設定:

重灌載值=systick 時鐘頻率(Hz)X想要的定時時間(S)

如:時鐘頻率為:AHB的8分頻;AHB=72MHz那麼systick的時鐘頻率為72/8MHz=9MHz;要定時1秒,則

重灌載值=9000000X1=9000000;

定時10毫秒

重狀態值=9000000X0.01=90000

//兩個時鐘源的定義
#define SYSTICK_CLKSOURCE_HCLK_DIV8    (0x00000000U)
#define SYSTICK_CLKSOURCE_HCLK         (0x00000004U)
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
{
   return SysTick_Config(TicksNumb);
}
  \brief   System Tick Configuration
  \details 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.//返回0,配置成功
  \return          1  Function failed.//返回1,失敗
  \note    When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
           function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
           must contain a vendor-specific implementation of this function.
 */
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)//超過最大定時值,返回1,SysTick_LOAD_RELOAD_Msk值為2的24方-1;即0xFFFFFF

  {
    return (1UL);                                                   /* Reload value impossible */
  }

  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
  NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;    //SysTick Current Value Register,設為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 (0UL);                                                     /* Function successful */
}

SYSTICK內部暫存器的結構體定義,和上面圖中的暫存器一一對應。

typedef struct
{
  __IOM uint32_t CTRL;                   /*!< Offset: 0x000 (R/W)  SysTick Control and Status Register */
  __IOM uint32_t LOAD;                   /*!< Offset: 0x004 (R/W)  SysTick Reload Value Register */
  __IOM uint32_t VAL;                    /*!< Offset: 0x008 (R/W)  SysTick Current Value Register */
  __IM  uint32_t CALIB;                  /*!< Offset: 0x00C (R/ )  SysTick Calibration Register */
} SysTick_Type;

SysTick定時器的時鐘源選擇函式如下:

void HAL_SYSTICK_CLKSourceConfig(uint32_t CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(CLKSource));
  if (CLKSource == SYSTICK_CLKSOURCE_HCLK)
  {
    SysTick->CTRL |= SYSTICK_CLKSOURCE_HCLK;//見上面的巨集定義,(0x00000004U),即把CLKSOURCE控制暫存器位置1;
  }
  else
  {
    SysTick->CTRL &= ~SYSTICK_CLKSOURCE_HCLK;//把CLKSOURCE控制暫存器位置0;

  }
}

systick定時器的處理函式為空,並未執行任何動作,如下:

void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */
	
  /* USER CODE END SysTick_IRQn 1 */
}
void HAL_SYSTICK_IRQHandler(void)
{
  HAL_SYSTICK_Callback();
}
__weak void HAL_SYSTICK_Callback(void)
{
  /* NOTE : This function Should not be modified, when the callback is needed,
            the HAL_SYSTICK_Callback could be implemented in the user file
   */
}

注意:當主晶片需使用SLEEP模式時,SYSTICK的異常請求會喚醒SLEEP模式,進入SLEEP模式前需要把TICKINT控制器置為0。

HAL_SuspendTick();//把TICKINT控制暫存器置0;
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
HAL_ResumeTick();//把TICKINT控制暫存器置1;
__weak void HAL_SuspendTick(void)
{
  /* Disable SysTick Interrupt */
  CLEAR_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);//置0
}
__weak void HAL_ResumeTick(void)
{
  /* Enable SysTick Interrupt */
  SET_BIT(SysTick->CTRL,SysTick_CTRL_TICKINT_Msk);//置1
}

相關推薦

STM32SysTick使用方法

 一、STM32的SysTick簡介   SysTick是一個24位的系統節拍定時器system tick timer,SysTick,具有自動過載和溢位中斷功能,所有基於Cortex_M3處理器的微控制器都可以由這個定時器獲得一定的時間間隔。 systick的作用:

STM32學習方法

對比 開始 資源 文檔 版本 .cn bsp 標準 測試 1.網絡學習資源 WWW.openedv.com 開源電子網 WWW.stmcu.org ST中國官方技術網站,ST官方文檔發布網站 微信公眾平臺 正點原子 2.

嵌入式stm32學習方法

方法 學習交流 inter 規律 rup reset 學習 key 串口   stm32方法總結   相信很多人學習單片機都是從51開始的,而相對於51來說,stm32的代碼量明顯增加,並且了解到一定程度就知道stm32的代碼不可能都自己寫(因為代碼量不允許),因此學習方向

STM32-(SysTick定時器,EXTI外部中斷/事件控制器)

Systick系統定時器 介紹:systick定時器上屬於CM3核心中的一個外設,內嵌在NVIC中。系統定時器是一個24位向下計數的計數器,計數器每一次計數的時間是1/SYSTICK,一般我們設定SYSTICK為72M。當過載數值暫存器的值遞減到0時,系統定時器產生一次中斷,以此迴圈。

STM32 systick 定時 時間計算

系統嘀嗒(SysTick)校準值暫存器 1.(SysTick) 系統嘀嗒時鐘是由HCLK 分頻 出來的。HCLK=SYSCLK=72MHz /* Select HCLK/8 as SysTick clock source */   SysTick_CLKSourceConfig(SysTick_CLKSou

[STM32]SysTick, 簡單到只有一句話

多年的開發STM32,遇到一些簡單的需要計時的任務,比如延時等,最方便的是其提供的systick。 systick其實本為移植作業系統提供滴答時鐘的方便。 前兩天再次接觸STM32,使用了V3.5的庫,突然發現繁瑣的Systick用法被簡化成一句話。 即:  void Sy

STM32 SysTick 精準延時 簡單分析

//if (SysTick_Config(SystemCoreClock / 1000000*a))//寫初值---- ST3.0.0庫版本if (SysTick_Config(SystemCoreClock / 1000000*a))  //寫初值----ST3.5.0庫版本{         while

STM32 Systick定時器在實現1us延時時的問題與解決

問題: 使用systick_config()函式來實現計數,這個函式在下面程式碼中的 SysTick_CTRL_TICKINT_Msk 開啟了中斷。不論系統時鐘為72Mhz或36Mhz若設定STM32每10us進入一次中斷,計時是可以的;而每1us進入中斷,由於中斷指令較多

STM32 SysTick定時器做延時函式

在STM32中延時函式用的非常廣泛,具體延時函式怎麼使用,下面我們來進行想詳解,本文主要介紹採用SysTick計時器來實驗系統延時: 原理介紹:                  SysTick計時器是一個24位的倒計數定時器,主要用來做作業系統的定時器,每來一個時鐘週期

stm32 systick使用

控制寄存器 技術分享 tex pre def ace ali ppi cal 一開始在stm32參考手冊裏找關於systick的內容,沒找到任何有用的信息,後來百度了下,發現是在cortex m3參考手冊裏有 幾個寄存器的描述在第8.2節,寄存器的定義在core_cm3.h

基於stm32 Systick 的簡單定時器(裸機)-- 陣列實現

前言   在嵌入式的開發中,經常需要執行定時的操作。 聰明的同學肯定會想到, 我可以配置硬體定時器, 然後利用定時器中斷來執行需要定時執行的程式碼。然而硬體定時器的數量總是有限,不一定可以滿足我們定時的需求。因此我們常常需要用到軟體定時的方法。   事實上,

STM32中使用systick時鐘進行延時的中斷與非中斷兩種方法

一、第一種方法是進入核心中斷的方式 //以下程式是根據官方程式修改的 #include "systick.h" /* Private variables ---------------------------------------------------------*/ u32 Timin

STM32 UART串口通訊編程方法

STM32 串口編程 uart 在對通訊時間要求比較高的時候,就需要自己對UART的通訊底層直接進行操作。我以STM32單片機為例,講一下比較快速的UART編程方法。——其實不止是STM32這麽處理,我以前使用過51的單片機,TI的MSP單片機,三菱的16位單片機,都可以采用這種方法。

stm32開發生成庫的方法

option 選擇 函數 情況 如果 接口 關心 nbsp 協同工作 在一個項目裏面可能有對單片機很熟悉的工程師,懂硬件和軟件,也有只寫軟件的工程師,那麽怎麽才能進行協同工作呢,我想了一個辦法就是懂底層的工程師開發驅動,然後留出接口給其他的工程師來調用,這樣其

關於STM32的可編程電壓檢測器的使用方法

als hcl oot nbsp 分享圖片 too cmd init splay 關於STM32的可編程電壓檢測器的使用方法 思維導圖總覽: 代碼: 1 #include "sys.h" 2 #include "delay.h" 3 #include "us

一種基於STM32的APP和BootLoader設計的方法

IAP(In Application Programming)即在應用程式設計, IAP 是使用者自己的程式在執行過程中對User Flash 的部分割槽域進行燒寫,目的是為了在產品釋出後可以方便地通過預留的通訊口對產品中的韌體程式進行更新升級。 通常實現 IAP 功能時,即使用者程式執

關於STM32程式模擬時卡死在default_handler的解決方法

問題描述:在debugger模式下,執行後,串列埠通訊正常,過一會串列埠通訊異常,暫停模擬發現程式死在default_Handler 原因:沒有中斷入口函式,當然了,有些人可能會這麼寫 void USART1_IRQHandler(void) { } 以為這樣就算是

STM32外設資源查詢方法,對比C8T6和ZET6

對應不同型號的微控制器的外設資源需要找相應的微控制器的資料手冊,比如STM32F103ZET6資料手冊,STM32F103C8T6資料手冊. 根據FLASH大小STM32F103ZET6 - 為HD型,STM32F103C8T6 - 為MD型。 STM32F103ZET6

STM32 不斷進入串列埠中斷問題 解決方法

STM32 有時候會不斷進入中斷,解決方法如下 1.串列埠初始化配置時,需要開啟ORE 溢位中斷,如下紅色程式碼所示 void Usart_Init(void) {     GPIO_InitTypeDef GPIO_InitStructure;

STM32-嵌入式-04-systick系統定時器

systick系統定時器 系統定時器存在核心中,是24位的定時器,只能向下遞減,巢狀在NVIC中   counter 在時鐘的驅動下 在reload的初值開始向下遞減計時到0,產生中斷置位標誌然後又從reload值開始重新遞減計數,迴圈 定時時間計算 t=reload*