一、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 __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 - 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
}
上一篇:STM32的系统滴答定时器(Systick)
下一篇:SysTick功能总结
推荐阅读最新更新时间:2024-03-16 16:21