SysTick叫做系统嘀嗒时钟,系统定时器,属于Cortex-M4内核中的一个(外设)外围设备,并且是24bit向下递减的计数器
lSystick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器。
lSystick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。比如UCOS中,分时复用,需要一个最小的时间戳,一般在STM32+UCOS系统中,都采用Systick做UCOS心跳时钟
《STM32F4xx中文参考手册.pdf》 第108页
RCC 向 Cortex 系统定时器 (SysTick) 馈送 8 分频的 AHB 时钟 (HCLK) (168M/8=21M)。SysTick 可使用此时钟作为时钟源,也可使用 HCLK 作为时钟源,具体可在 SysTick 控制和状态寄存器中配置
1)定时器的位数越多,定时时间更长
2)通过计数值间接计算定时时间,不能像操作系统直接调用函数实现延时或定时功能
计数值,就是要进行多少个计数
168000000 次 = 1S
168000 次 = 1ms
168 次 = 1us
物质在1S内完成周期性变化的次数叫做频率,常用f表示。为了纪念德国物理学家赫兹的贡献,人们把频率的单位命名为赫兹,简称“赫”,符号为Hz
参考文档:《Cortex M3与M4权威指南.pdf》314页
固件库中的Systick相关函数:
SysTick_CLKSourceConfig() //Systick时钟源选择 misc.c文件中
SysTick_Config(uint32_t ticks) //初始化systick,时钟为HCLK,并开启中断
//core_cm3.h/core_cm4.h文件中
uSystick中断服务函数:
void SysTick_Handler(void);
1、系统嘀嗒时钟配置
uint32_t SysTick_Config(uint32_t ticks);
示例:
系统定时器触发1khz的中断,中断周期时间T=1/f = 1000ms/1000 = 1ms
系统定时器连接到PLL输出的168Mhz时钟
只要系统定时器进行168000000次计数,就是1s时间的到达
只要系统定时器进行168000次计数,就是1ms时间的到达
只要系统定时器进行168次计数,就是1us时间的到达
SysTick_Config(SystemCoreClock / 1000);
SysTick_Config(168000); // 168MHz / 1000 = 168000
三、最大定时时间
1、确定最大的计数值224-1,若计算到0,则进行224次方计数
1000ms TMax
----- == -----
168000000 2^24
Tmax = 2^24 * 1000ms / 168000000 = ms
16,777,216 * 1000 / 168000000 = 99.86ms
初始化系统定时器,1s内内核触发1000次中断,说白了,定时1ms,能够成功
SysTick_Config(SystemCoreClock / 1000);
初始化系统定时器,1s内内核触发10次中断,说白了,定时100ms,不能成功
SysTick_Config(SystemCoreClock / 10);
初始化系统定时器,1s内内核触发11次中断,说白了,定时90.90ms,能够成功
SysTick_Config(SystemCoreClock / 11);
总结:填写中断频率值不能小于11,否则定时时间不准确
没有操作系统:只用于延时
有操作系统(Ucos freertos):为操作系统提供精准的定时中断(50ms)
参考文档:《Cortex M3与M4权威指南.pdf》314页
In many cases you might not want to use the SysTick_Config function because you might want to use the reference clock or you might not want to enable the SysTick interrupt. In these cases you need to program the SysTick registers directly,and the following sequence is recommended
在许多情况下,您可能不想使用SysTick_Config函数,因为您可能想使用参考时钟或不想启用SysTick中断。在这些情况下,您需要直接对SysTick寄存器进行编程,建议采用以下顺序
通过将0写入SysTick->CTRL来禁用SysTick定时器。此步骤是可选的。建议使用可重用代码,因为之前可能已启用SysTick。
将新的重新加载值写入SysTick->LOAD。重新加载值应该是间隔值e1。
使用任何值写入SysTick当前值寄存器SysTick->VAL,将当前值清除为0。
写入SysTick控件和状态寄存器SysTick->CTRL以启动SysTick定时器
If you want to use the SysTick timer in polling mode, you can use the count flagin the SysTick Control and Status Register(SysTick->CTRL) to determinewhen thetimer reaches zero. For example, you can create a timed delay by setting the SysTicktimer to a certain value and waiting until it reaches zero
参考文档:《Cortex M3与M4权威指南.pdf》316页
官方给的示例代码更改之后:1ms
SysTick->CTRL = 0; // Disable SysTick
SysTick->LOAD = 168000-1; // 配置计数值(168000-1) ~ 0
SysTick->VAL = 0; // Clear current value as well as count flag
SysTick->CTRL = 5; // Enable SysTick timer with processor clock
while ((SysTick->CTRL & 0x00010000)==0); // Wait until count flag is set
SysTick->CTRL = 0; // Disable SysTick
参考文档:《Cortex M3与M4权威指南.pdf》315页
void delay_ms(uint32_t n)
{
while(n--)
{
SysTick->CTRL = 0; // 关闭系统定时器
SysTick->LOAD = 168000-1; // 配置计数值(168000-1) ~ 0
SysTick->VAL = 0; // 清除当前值和计数标志
SysTick->CTRL = 5; // 使用处理器时钟启用SysTick定时器
while ((SysTick->CTRL & 0x00010000)==0);// 等待直到设置计数标志
}
SysTick->CTRL = 0; // 关闭系统定时器
}
void delay_ms(uint32_t n)
{
while(n--)
{
SysTick->CTRL = 0; // 关闭系统定时器
SysTick->LOAD = 168-1; // 配置计数值(168-1) ~ 0
SysTick->VAL = 0; // 清除当前值和计数标志
SysTick->CTRL = 5; // 使用处理器时钟启用SysTick定时器
while ((SysTick->CTRL & 0x00010000)==0);// 等待直到设置计数标志
}
SysTick->CTRL = 0; // 关闭系统定时器
}
应用场景:
1、微波炉的定时控制
2、洗衣机的定时控制
3、秒表
VAL = 0; // 清除当前值和计数标志
SysTick->CTRL = 5; // 使用处理器时钟启用SysTick定时器
while ((SysTick->CTRL & 0x00010000)==0);// 等待直到设置计数标志
}
SysTick->CTRL = 0; // 关闭系统定时器
}
应用场景:
1、微波炉的定时控制
2、洗衣机的定时控制
3、秒表
4、智能定时夜灯