文章目录
- 一、SysTick
- 二、SysTick功能
-
- [ 1、基本框图](# 1、基本框图)
- [ 2、SysTick寄存器](# 2、SysTick寄存器)
- [ 3、SysTick定时时间计算](# 3、SysTick定时时间计算)
- 三、SysTick定时实验
-
- [ 1、编程要点](# 1、编程要点)
- [ 2、文件配置](# 2、文件配置)
- [ 3、代码](# 3、代码)
- [ 4、一种简洁的代码](# 4、一种简洁的代码)
一、SysTick
SysTick:系统定时器,24位,只能递减,存在于内核,嵌套在NVIC中,所有的Cortex-M内核的单片机都具有这个定时器。
SysTick---系统定时器是属于CM3内核中的一个外设,内嵌在NVIC中。
系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK,一般我们设置系统时钟SYSCLK等于 72M。
当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。
二、SysTick功能
1、基本框图
counter在时钟的驱动下,从reload初值开始往下递减计数到0,产生中断和置位COUNTFLAG标志。
然后又从reload值开始重新递减计数,如此循环。
系统定时器是一个24bit的向下递减的计数器, 计数器每计数一次的时间为1/SYSCLK。
一般我们设置系统时钟SYSCLK等于72M。
当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复。
2、SysTick寄存器
SysTick寄存器汇总

SysTick控制及状态寄存器

SysTick重装载数值寄存器

SysTick当前数值寄存器

SysTick校准数值寄存器

3、SysTick定时时间计算

t = reload * (1/CLK)
CLK= 72M时,t = (72)*(1/72M) = 1us
CLK= 72M时,t = (72000)*(1/72M) = 1ms
时间换算参考:
1s = 1000ms = 1000 000us = 1000 000 000ns
三、SysTick定时实验
1、编程要点
设置重装载寄存器的值。
清除当前数值寄存器的值。
配置控制与状态寄存器。
2、文件配置
SysTick.c、SysTick.h存放驱动程序及相关宏定义,中断服务在stm32f10x_it.c文件中。
3、代码
SysTick配置库函数
c
// 这个 固件库函数 在 core_cm3.h中 仅参考
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// 不可能的重装载值,超出范围
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) {
return (1UL);
}
// 设置重装载寄存器
SysTick->LOAD = (uint32_t)(ticks - 1UL);
// 设置中断优先级
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
// 设置当前数值寄存器
SysTick->VAL = 0UL;
// 设置系统定时器的时钟源为AHBCLK=72M
// 使能系统定时器中断
// 使能定时器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0UL);
}
配置SysTick中断优先级
c
// 设置系统定时器中断优先级
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
if ((int32_t)IRQn < 0) {
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] =
(uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
} else {
NVIC->IP[((uint32_t)(int32_t)IRQn)] =
(uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
}
}
SysTick初始化函数
c
/**
* @brief 启动系统滴答定时器 SysTick
* @param 无
* @retval 无
*/
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/
if (SysTick_Config(SystemCoreClock / 100000)) {
/* Capture error */
while (1);
}
}
SysTick定时函数
c
/**
* @brief us延时程序,10us为一个单位
* @param
* @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
* @retval 无
*/
void Delay_us(__IO u32 nTime)
{
TimingDelay = nTime;
while (TimingDelay != 0);
}
SysTick中断服务函数
c
/**
* @brief 获取节拍程序
* @param 无
* @retval 无
* @attention 在 SysTick 中断函数 SysTick_Handler()调用
*/
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00) {
TimingDelay--;
}
}
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}
主函数
c
int main(void)
{
/* LED 端口初始化 */
LED_GPIO_Config();
/* 配置SysTick 为10us中断一次,时间到后触发定时中断,
*进入stm32fxx_it.c文件的SysTick_Handler处理,通过数中断次数计时
*/
SysTick_Init();
while (1) {
LED_ON;
Delay_us(100000); // 10000 * 10us = 1000ms
LED2_ON;
Delay_us(100000); // 10000 * 10us = 1000ms
LED3_ON;
Delay_us(100000); // 10000 * 10us = 1000ms
}
}
4、一种简洁的代码
直接在函数内部配置SysTick
c
void SysTick_Delay_Ms( __IO uint32_t ms)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000);
for (i=0; i<ms; i++) {
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
// 当置1时,读取该位会清0
while ( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~ SysTick_CTRL_ENABLE_Msk;
}
void SysTick_Delay_Us( __IO uint32_t us)
{
uint32_t i;
SysTick_Config(SystemCoreClock/1000000);
for (i=0; i<us; i++) {
// 当计数器的值减小到0的时候,CRTL寄存器的位16会置1
while ( !((SysTick->CTRL)&(1<<16)) );
}
// 关闭SysTick定时器
SysTick->CTRL &=~SysTick_CTRL_ENABLE_Msk;
}
systick 配置函数参考
c
// 这个 固件库函数 在 core_cm3.h中
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// reload 寄存器为24bit,最大值为2^24
if (ticks > SysTick_LOAD_RELOAD_Msk) return (1);
// 配置 reload 寄存器的初始值
SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;
// 配置中断优先级为 1<<4 -1 = 15,优先级为最低
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);
// 配置 counter 计数器的值
SysTick->VAL = 0;
// 配置systick 的时钟为 72M
// 使能中断
// 使能systick
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0);
}