stm32-7SysTicks

stm32-7SysTicks


1.系統定時器的相關配置

首先跟蹤一部分代碼,下面爲初始化滴答定時器的函數

    /* 配置SysTick爲10ms中斷一次*/
    SysTick_Init();

跟蹤到bsp_SysTicks.c文件中對他的定義

/**
  * @brief  配置滴答定時器
  * @param  
  * @retval 
  * @attention:配置中斷的時間間隔,配置成功後關閉定時器
  */
void SysTick_Init(void)
{
    /* 配置中斷時間間隔
     * SystemFrequency / 1000    1ms中斷一次
     * SystemFrequency / 100000  10us中斷一次
     * SystemFrequency / 1000000 1us中斷一次
     */
//  if (SysTick_Config(SystemFrequency / 100000))   // ST3.0.0庫版本
    if (SysTick_Config(SystemCoreClock / 100000))   // ST3.5.0庫版本
    { 
        /* Capture error */ 
        while (1);
    }
        // 關閉嘀嗒定時器  
    SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

其中,函數SysTick_Config(SystemCoreClock / 100000) 配置中斷時間間隔,配置失敗返回1,跟蹤到 core_cm3.h中:

/* #####################    SysTick function  ######################## */

#if (!defined (__Vendor_SysTickConfig)) || (__Vendor_SysTickConfig == 0)

/**
 * @brief  Initialize and start the SysTick counter and its interrupt.
 *
 * @param   ticks   number of ticks between two interrupts
 * @return  1 = failed, 0 = successful
 *
 * Initialise the system tick timer and its interrupt and start the
 * system tick timer / counter in free running mode to generate 
 * periodical interrupts.
 * ticks個時鐘週期中斷一次,中斷時間=ticks*時鐘週期
 */
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{   //檢查輸入的參數是否正確,ticks的值<=fffffff
    if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
    //將ticks-1的值裝入RELOAD,從ticks-1減到0是ticks
    SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
    //配置系統滴答定時器中斷SysTick中斷的優先級
    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
    //配置相關寄存器STK_CTRL:時鐘源、異常請求、使能
    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 */
}

#endif
/* ###################    Reset function  ############################# */

這個內核中的函數中使用了位指示宏位屏蔽宏,先上代碼,這是 core_cm3.h 中關於 SysTick 寄存器的一些定義

/* 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 */
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)        /*!< SysTick LOAD: RELOAD Mask */

/* SysTick Current Register Definitions */
#define SysTick_VAL_CURRENT_Pos             0                                             /*!< SysTick VAL: CURRENT Position */
#define SysTick_VAL_CURRENT_Msk            (0xFFFFFFul << SysTick_VAL_CURRENT_Pos)        /*!< SysTick VAL: CURRENT Mask */

其中的寄存器位指示宏:SysTick_xxx_Pos ,宏展開後即爲xxx 在相應寄存器中的位置,如控制 SysTick 時鐘源的 SysTick_CTRL_CLKSOURCE_Pos ,宏展開爲 2,這個寄存器位正是在寄存器 STK_CTRL 中的 Bit2。

而寄存器位屏蔽宏:SysTick_xxx_Msk,宏展開是xxx 的位全部置 1 後,左移 SysTick_xxx_Pos 位。如控制 SysTick 時鐘源的SysTick_CTRL_CLKSOURCE_Msk,宏展開爲 (1ul << SysTick_CTRL_CLKSOURCE_Pos) ,把無符號長整型數值(ul) 1 左移 2 位,得到了一個只有 Bit2:CLKSOURCE 位被置 1,其它位爲 0 的數值,這樣的數值配合位操作&(按位與)、| (按位或)可以很方便地修改寄存器的某些位。假如控制 CLKSOURCE 需要四個寄存器位,這個宏就應該被改爲(0xf ul << SysTick_CTRL_CLKSOURCE_Pos) ,這樣就會得到一個關於 CLKSOURCE 的四位被置 1 的值,這些宏的參數就是這樣被確定的。

2.利用滴答定時器實現精確延時

關於使用滴答定時器時間精確延時函數:

/**
  * @brief      us延時程序,10us爲一個單位»
  * @param  
  * @arg nTime: Delay_us( counts ) 延時爲 counts * 10us
  * @retval     TimingDelay是全局變量
  */
void Delay_us(__IO u32 nTime)
{ 
    TimingDelay = nTime;    
    //使用滴答定時器
    SysTick->CTRL |=  SysTick_CTRL_ENABLE_Msk;
    //直到TimingDelay減到0,延時結束
    while(TimingDelay != 0);
}

中斷需要調用的TimingDelay自減函數

/**
  * @brief  獲取節拍程序 
  * @param  
  * @retval 
  * @attention  在 SysTick 中斷函數 SysTick_Handler()調用
  */
void TimingDelay_Decrement(void)
{
    if (TimingDelay != 0x00)
    { 
        TimingDelay--;
    }
}

中斷函數SysTick_Handler(),在stm32f10x_it.h中由用戶填寫,每中斷一次調用一次TimingDelay_Decrement();使TimingDelay自減一次,直到TimingDelay == 0

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
void SysTick_Handler(void)
{
    TimingDelay_Decrement();    
}

注意

在一個文件裏調用另外一個文件裏的函數需要在該文件中用extern聲明,不然會報錯


End

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章