Stm32入门——Systick定时器
Systick定时器是什么?
从原理上来说,Systick定时器和开发板上的通用定时器没有区别。从功能上来说,Systick定时器主要是用来用来进行延时的(就是让CPU一直重复计数这件事),而通用或者高级定时器往往用来进行PWM输出、输入捕获等功能。至于为什么不用通用定时器或者高级定时器来完成延时功能,则是考虑到节省MCU的资源来做更重要的事。
Systick定时器相关寄存器
CTRL Systick控制和状态寄存器(存放使能位、中断位、时钟源选择位等)
LOAD Systick自动重装载值寄存器
VAL Systick当前值寄存器
(这里插一句,建议大家在学习的时候直接对寄存器进行操作,不要用库函数,这样前期虽然会有困难,但操作寄存器其实更高效、更能理解开发原理)
Systick定时器在工作时,先将LOAD中存放的值放入VAL中,然后VAL中的值会在每个时钟周期中减1直到变成0触发中断(如果开启了中断)。需要说明的是,LOAD的有效位是24位,因此理论上它可以存放的数值范围是[0,224 -1]。至于VAL每次减1用了多长时间,这要看你Systick定时器的时钟频率是多少了,比如你设置的时钟频率是1000Hz,那么每次减1就用了1毫秒(因为1000Hz代表1秒钟会产生1000个时钟周期,而一个时钟周期val会减1)。
延时方式
Systick实现延时的方式有两种:中断和非中断。
先说说中断吧,看看下面这段代码
Static _IO uint32_t TimingDelay;
Void Delay(_IO uint32_t nTime)
{
TimingDelay = nTime;
While(TimingDelay !=0);
}
Void SysTick_Handler(void)
{
If(TimingDelay !=0x00)
{
TimingDelay --;
}
}
Int main(void)
{
If(SysTick_Config(SystemCoreClock/1000))//Systick时钟为72MHz,中断时间间隔为1ms
{
While(1)
}
While(1)
{
Delay(200);//2ms
}
}
此处假设定时器时钟设置的是72MHz(关于时钟部分的知识见时钟篇讲解),SysTick_Config()这个函数是用来开启中断和设置每次中断产生的时间间隔的。SysTick_Config()的入口参数意义为:每产生一次中断,定时器会经过多少个周期。其实这个参数就是用来配置上文所说的LOAD寄存器的,因为每经过一个周期LOAD值就会减1。这样,在定时器时钟频率f和每次中断经过的周期数n确定的情况下,就能算出每次中断产生的时间间隔t,因为频率就是指每秒钟会经过的时钟周期个数。那么问题就很简单了,1秒钟产生了72MHz个时钟周期,那么产生72KHz个时钟周期(即产生一次中断)用了多久?答案是1ms。每次中断产生的时间间隔确定后,调用delay()设置中断次数就能设置多次中断了,比如delay(200)就是延时了200ms。
再说说非中断的情况。
非中断就比较简单了,主要思想就是算出每经过1m会经过多少个时钟周期(即val寄存器减多少次),如果每经过1ms会经过9个周期,那你给LOAD寄存器设置为9000就能延时1000ms了,但要注意的是LOAD寄存器有效位为24位,因此不能赋值超过224 -1的值,但你可以通过多次调用或者在函数内部用循环+取模的方法来让板子在不产生中断的情况下延时更久。
初学stm32,如有不当,欢迎指正!
参考资料:某宝stm32开发板视屏、《stm32中文参考手册》。