SysTick是什么
SysTick定时器常用来做延时,或者实时系统的心跳时钟。这样可以节省MCU资源,不用浪费一个定时器。SysTick定时器是系统滴答定时器,一个24位的倒计数定时器,计到0时,将从RELOAD寄存器中自动重装载定时器初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作。SysTick定时器也可以做中断,也可以设置其中断的优先级,但是在这里只介绍它的延时功能。
SysTick寄存器
CTRL SysTick控制和状态寄存器
LOAD SysTick自动重装载寄存器
VAL SysTick当前值寄存器
CTRL控制和状态寄存器
对于STM32,外部时钟源HCLK(AHB总线时钟的1/8),内核时钟是HCLK时钟.(HCLK为72MHz)
配置函数:SysTick_CLKSourceConfig();
LOAD自动重装载寄存器
VAL当前值寄存器
代码配置
void delay_init()//SysTick配置
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8 系数为9
fac_ms=(u16)fac_us*1000; //fac_us和fac_ms表达的不是时间是系数!!!系数为9000
}
void delay_us(u32 nus)//微妙级
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL; //读取寄存器ctrl的使能位和countflag标志位
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 当使能位没有被置自0并且countflag为0(没数完),知 然后一直执行DO里的语句,用来延时道
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
void delay_ms(u16 nms)//毫秒级
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;//读取寄存器ctrl的使能位和countflag标志位
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达 当使能位没有被置自0并且countflag为0(没数完),知 然后一直执行DO里的语句,用来延
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
注意:1.使用延时函数时记得在主函数里声明SysTick的寄存器配置delay_init();
2.fac_us不是1微妙
SysTick时钟是sysclk 8分频,即SysTick时钟频率=sysclk/8, systick 计1次数所需时间为8/sysclk(s)=810^6/sysclk(us),由此,
SysTick 1微秒计数个数为fac_us=sysclk/810^6.
举个例子:当sysclk=8M时,systick 计1次数所需时间为1us,由此,fac_us=1,寄存器加载个数SysTick->LOAD=nus1;
当sysclk=72M时,systick 计1次数所需时间为1/9us,由此,fac_us=9,寄存器加载个数SysTick->LOAD=nus9;