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