xyc2690 发表于 2015-1-15 22:46:50

关于SysTick 1us延时的实验

本帖最后由 xyc2690 于 2015-1-24 20:21 编辑

常常在论坛看到有关SysTick 不能实现1us延时的问题,晚上决定亲手用示波器测一下。
首先,我的板子是NucleoSTM32F072 ,没有外接晶振,设置使用内部晶振48M(HSI48)。

时钟频率:1/48M=0.0208333us
没有使用STM32的固件库,1us延时比较短,


while (1)
{
                GPIOA->ODR ^=GPIO_PIN_5;
                Delay_us(1);
}每1us   GPIO状态翻转。void Delay_us(uint32_t nTime)
{
    SysTick->VAL=0X00;                              //初值
    SysTick->LOAD=48*nTime;                   //重装值;48个时钟周期=1us
    SysTick->CTRL=0x00000005;               //第0位:使能时钟   第3位:使用内部时钟
    while(!(SysTick->CTRL&0x00010000));//计时
    SysTick->CTRL|=0x00000004;             // 第1位:产生异常请求
}



不能实现1us延时。

******************************************************************
我尝试将
SysTick->VAL=0X00;   注释掉
void Delay_us(uint32_t nTime)
{
//SysTick->VAL=0X00;            //初值
SysTick->LOAD=48*nTime;    //重装值;48个时钟周期=1us
SysTick->CTRL=0x00000005;//第0位:使能时钟   第3位:使用内部时钟
while(!(SysTick->CTRL&0x00010000));//计时
SysTick->CTRL|=0x00000004;// 第1位:产生异常请求
}
除了第一次之后的Delay_us(1)有改观,

进一步,如果将

SysTick->LOAD=48*nTime; // 重装值;48个时钟周期=1us
SysTick->CTRL=0x00000005;// 第0位:使能时钟 第3位:使用内部时钟
这两句在前面初始化,而不放进延时:





延时就比较精确了。


我的问题就是“SysTick->VAL=0X00; ” 为什么会有1us?

天天晓宇 发表于 2015-1-16 08:31:15

这个没什么意义

数码小叶 发表于 2015-1-16 07:55:00

论坛有好几个这样的帖子了,我也发过,都回答的很详细:lol:lol:lol

holts1 发表于 2015-1-16 08:18:35

本身中断切换要时间的,这个1U就是修正值

xyc2690 发表于 2015-1-16 08:32:27

holts1 发表于 2015-1-16 08:18
本身中断切换要时间的,这个1U就是修正值

中断响应考虑进去了,没有1us这么长的,当然这里延时1us gpio翻转一次,示波器显示的是1个周期其实是延时2us了。我的疑问是清空SysTick->VAL相对与其他寄存器操作很费时间。。。

我是酱油哥 发表于 2015-1-16 08:33:57

不错    好东西

holts1 发表于 2015-1-16 12:01:11

xyc2690 发表于 2015-1-16 08:32
中断响应考虑进去了,没有1us这么长的,当然这里延时1us gpio翻转一次,示波器显示的是1个周期其实是延时 ...

即然费时间,哪它有没有预加载的机制?

大秦正声 发表于 2015-1-16 14:26:51

学习,内部晶振有误差的

xyc2690 发表于 2015-1-16 14:39:29

holts1 发表于 2015-1-16 12:01
即然费时间,哪它有没有预加载的机制?

就是不清楚为什么费时间呀~

hanmcustm 发表于 2015-1-16 15:04:48

楼主用外部时钟试一下
页: [1] 2 3
查看完整版本: 关于SysTick 1us延时的实验