-------------------------------------------------------------------------------------------------------------------------
工程文件:放在百度云盘里,需要的自行下载!!!
链接:http:// https://pan.baidu.com/s/1tLv_dqTEkdYNSnlVzTdYMA?pwd=xyza
提取码: xyza
-------------------------------------------------------------------------------------------------------------------------
在嵌入式开发中,我们经常需要用到delay延时函数,本文用systick来实现delay函数,分us,ms,s延时。当然我们也可以用最简单的for循环来做,但是它的缺点就是不太准确。
例如:j<1000这个值需要根据平时时钟和指令时间,去调整 ,延时一个时间然后用示波器去看一下延时时间的长短,然后通过调整1000这个值的大小,来达到相对准确的一个延时。
/******************************************************************************************************************************************
* 函数名称: hal_delay_ms()
* 功能说明: 延时ms
* 输 入: 无
*
* 输 出: 无
* 注意事项:
******************************************************************************************************************************************/
void hal_delay_ms(u32 ms)
{
u32 i, j;
for (i = 0; i < ms; i++)
{
for (j = 0; j < 1000; j++)
{
}
}
}
这里我们用systick的滴答数来做延时,能做到比较准确!!!
1:首先需要初始化:现在的主时钟是72Mhz(SystemCoreClock = 72 000 000),我们用主时钟的1/8作为systick的时钟源,相当1s有9M个时钟信号,那么1us就是9个时钟信号
所以1us = SystemCoreClock /8000000
1ms = 1000*1us
2:设置好时钟源后,我们再来认识一下systick的寄存器
SysTick->LOAD:重加载寄存器,我们需要delay多长时间,数值是存在这里面的
SysTick->VAL:计数器寄存器,计到多少数了存在这里
SysTick->CTRL:控制寄存器,第16位,countflag:当计算到0后置为1
/******************************************************************************************************************************************
* 函数名称: delay_us()
* 功能说明: 延时us
* 输 入: 无
*
* 输 出: 无
* 注意事项:
******************************************************************************************************************************************/
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/******************************************************************************************************************************************
* 函数名称: delay_ms()
* 功能说明: 延时ms
* 输 入: 无
*
* 输 出: 无
* 注意事项: 对于72M情况,ms<1864
******************************************************************************************************************************************/
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms; //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00; //清空计数器
SysTick->CTRL=0x01 ; //开始倒数
do
{
temp=SysTick->CTRL;
}
while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL=0x00; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
/******************************************************************************************************************************************
* 函数名称: delay_s()
* 功能说明: 延时s
* 输 入: 无
*
* 输 出: 无
* 注意事项: 调用delay_ms函数s*1000次,因为1秒=1000毫秒
******************************************************************************************************************************************/
void delay_s(u16 ns)
{
u16 i;
for (i = 0; i < ns; i++)
{
delay_ms(1000);
}
}
3:我们再来验证下
延时1000us,打印:this is us delay
延时200ms,打印:this is ms delay
延时1s,打印:this is s delay
us用串口打印不是太准哈,可以用示波器量一下
重点注意:
因为SysTick->VAL:是一个16位的寄存器,所以给它的值有一个上值,要少于2^16-1