一、SysTick相关寄存器
首先关于SysTick寄存器的数据在下面这个文件里面可以找到,平时那个数据手册是没有的。其次我这边使用的开发板是F407的开发板,关于这个寄存器的数据都是来自下面这个文件的截图,一般只会用到这3个寄存器。
二、使用标准库对SysTick进行初始化
首先我们知道当你使用标准库的时候,他已经默认帮你将系统时钟那设置成了168MHz,因此SysTick时钟为168MHz,在初始化里面我选择了8分频,这个样延时的时间可以变得长一点。这里的SCLK的值为168,也就是系统时钟。
void systick_init(uint8_t SCLK)
{SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);f_us = (SCLK/8); //定时1微秒所需要的初始值 这个是两个全局变量f_ms = f_us * 1000; //定时1毫秒所需要的初始值
}
三、编写精确延时函数
//定时时间范围最大798915个微秒
void delayus(uint32_t us)
{uint32_t temp = 0;SysTick->LOAD = f_us*us; SysTick->VAL = 0x00; //清除计数器SysTick->CTRL |= 0x01; //打开计数器do {temp = (SysTick->CTRL) & (1 << 16); //判断计数是否到了0}while((!temp));SysTick->VAL = 0x00; //清除计数器SysTick->CTRL &= ~0x01; //关闭计数器
}
//定时时间范围最大798个毫秒秒
void delaynms(uint32_t ms)
{uint32_t temp = 0;SysTick->LOAD = f_ms*ms;SysTick->VAL = 0x00; SysTick->CTRL |= 0x01;do {temp = (SysTick->CTRL) & (1 << 16);}while((!temp));SysTick->VAL = 0x00; SysTick->CTRL &= ~0x01;}void delayms(uint32_t ms)
{uint32_t i = 0;for (i=0; i<=ms; i++){delaynms(1);}
}
四、关于延时不准确的原因
刚开始我使用这个方法进行延时,确实能达到效果,但是我通过示波器来查看时,发现延时并不准确,而且误差有点大。那我就在想是不是系统时钟的问题,一看还真是,因为F407的标准库里面默认你外部HSE接的是25MHz的晶振,但是我发现我的开发板上面接的是8MHz的晶振,应该就是系统里面帮我初始化时钟的时候,没有真正的初始化为168MHz的时钟。通过查看标准库的代码,并作出了下面的修改就可以了。