1、前言
CM4內核的處理和CM3一樣,內部都包含了一個SysTick定時器,SysTick 是一個24 位的倒計數定時器,當計到0 時,將從RELOAD 寄存器中自動重裝載定時初值。只要不把它在SysTick 控制及狀態寄存器中的使能位清除,就永不停息。這樣可以用systick來實現延時定時功能,不用再占用系統定時器。systick也多用做系統的時鐘節拍,如freeRTOS等OS,再啟動調度器的時候,就會將systick配置成其系統時鐘,給系統提供心跳。systick中有4個寄存器CTRL、LOAD、VAL、CALIB

2、systick配置注意事項
使用CubeMX配置生成的代碼中,會自動生成一個 SystemClock_Config() 的函數,用于配置單片機時鐘,其中就會配置systick
void SystemClock_Config()
{
...........
LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
LL_SetSystemCoreClock(32000000);
#ifndef SYSTICK_IRQ
LL_Init1msTick(32000000); //使能systick但是不開啟systick中斷
#else
SysTick_Config(SystemCoreClock / 1000);//使能systick同時開啟systick中斷
#endif
}
但是這里 需要注意的是,是不是需要開啟 systick 中斷!!!!
1、如果只是想用systick來作為延時用,程序不想被中斷打斷,就只需要使能systick而不用開啟systick中斷,調用 LL_Init1msTick 即可
void LL_Init1msTick(uint32_t HCLKFrequency)
---> LL_InitTick(HCLKFrequency, 1000U);
---> __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)
{
/* Configure the SysTick to have interrupt in 1ms time base */
SysTick->LOAD = (uint32_t)((HCLKFrequency / Ticks) - 1UL); /* set reload register */
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
}
但是需要自己編寫延時函數,不能使用HAL庫提供的HAL_Delay()。原因如下:HAL_Delay的實現是依靠一個uwTickFreq變量,uwTickFreq是在HAL_IncTick中累加的,需要在 SysTick_Handler中斷函數中周期調用,這樣HAL_Delay才會有一個基準
__weak void HAL_IncTick(void)
{
uwTick += uwTickFreq;
}
__weak uint32_t HAL_GetTick(void)
{
return uwTick;
}
__weak void HAL_Delay(uint32_t Delay)
{
uint32_t tickstart = HAL_GetTick();
uint32_t wait = Delay;
/* Add a period to guaranty minimum wait */
if (wait < HAL_MAX_DELAY)
{
wait += (uint32_t)(uwTickFreq);
}
while((HAL_GetTick() - tickstart) < wait)
{
}
}
自定義的us延時
void my_delay_us(uint32_t nus)
{
uint32_t temp;
uint32_t fac_us = SystemCoreClock/1000000; //為系統時鐘的1/1000000
SysTick->LOAD = nus*fac_us; //時間加載
SysTick->VAL = 0x00; //清空計數器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ; //開始倒數
do
{
temp = SysTick->CTRL;
}
while((temp & 0x01) &&! (temp&(1 << 16))); //等待時間到達
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk; //關閉計數器
SysTick->VAL = 0X00; //清空計數器
}
2、如果想用systick座系統的時鐘節拍,需要開啟systick中斷,可以直接調用 SysTick_Config 來配置,也可以使用 HAL_Init 來配置,HAL_Init 配置最終也會調用 SysTick_Config 函數
HAL_Init(void)
---> HAL_InitTick(uint32_t TickPriority)
---> SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
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; /* 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的中斷中調用 osSystickHandler 和 HAL_IncTick
void SysTick_Handler(void)
{
osSystickHandler();//為OS提供系統時鐘節拍
HAL_IncTick();//為HAL庫提供時鐘基準
}
編輯:hfy
-
單片機
+關注
關注
6076文章
45495瀏覽量
670383 -
寄存器
+關注
關注
31文章
5608瀏覽量
129998 -
定時器
+關注
關注
23文章
3368瀏覽量
123631 -
STM32單片機
+關注
關注
59文章
553瀏覽量
60623 -
Systick
+關注
關注
0文章
67瀏覽量
13969
發布評論請先 登錄
小白也能聽懂的單片機知識路徑
CW32系統滴答SysTick定時器詳解
編寫簡單高效單片機匯編程序
使用系統定時器SysTick來實現精確延時微秒和毫秒函數
SysTick系統滴答定時器簡介
單片機怎么驅動電機?
新概念51單片機C語言教程入門、提高、開發、拓展全攻略
0STM32中的SysTick是個啥?咋用?(可下載)
瑞薩MCU RA8系列教程:RA8單片機SysTick使用描述
STM32單片機最小系統電路設計
如何使用STM32單片機systick來實現延時定時功能
評論