SysTick不能准确延时

2019-10-15 17:42发布

我要使用DS18b20进行温度检测,需要us级别的延时,上网查了相关资料,看了相应的代码,然后把那些ucosII的去掉了,然后进行测试,发现延时很不准,温度也检测不了。。。
[mw_shl_code=c,true]#include "delay.h" void delay_init() { SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8 } void delay_us(u32 nus) { u32 temp; SysTick->LOAD=nus*9; //时间加载 SysTick->VAL=0x00; //清空计数器 SysTick->CTRL|=SysTick_Counter_Enable ; //开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16))); //等待时间到达 SysTick->CTRL&=~(SysTick_Counter_Enable); //关闭计数器 SysTick->VAL =0X00; //清空计数器 } void delay_ms(u16 nms) { u32 temp; SysTick->LOAD=nms*9000;//时间加载(SysTick->LOAD为24bit) SysTick->VAL =0x00; //清空计数器 SysTick->CTRL|=SysTick_Counter_Enable ; //开始倒数 do { temp=SysTick->CTRL; } while(temp&0x01&&!(temp&(1<<16)));//等待时间到达 SysTick->CTRL&=~(SysTick_Counter_Enable); //关闭计数器 SysTick->VAL =0X00; //清空计数器 } [/mw_shl_code] [mw_shl_code=c,true]#ifndef __DELAY_H #define __DELAY_H #include"stm32f10x_lib.h" void delay_init(void); void delay_ms(u16 nms); void delay_us(u32 nus); #endif[/mw_shl_code]
下面是测试的情况:

此时时间:

运行:


此时时间:

整整相差0.0775568,也就是78ms , 也是 77557us ,并不是750us 。。。。。

我是放在main函数里测试的。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
远方
2019-10-15 21:11
“当STK_VAL的值被减至0时,由硬件自动把重载寄存器STK_LOAD(SysTick reload value register)中保存的数据加载到STK_VAL,重新向下计数”,这是文档中对systic工作过程的说明。那么,当计数为0,
准备执行"while(temp&0x01&&!(temp&(1<<16))); //等待时间到达"(你这一句的意思应当是systic打开 && 定时未到则一直循环)时如果突然被一个中断打断,等中断执行完成回过头来继续执行时val的值又等于load了,将继续执行循环,导致延时被延长,所以楼主应先将所有的中断关闭以后再进行测试才行。
但如果真是这种情况,那楼主的这个程序的实用性将大打折扣了。其实原子哥在他的例程中的us延时就已经很好了,完全可以参考。

一周热门 更多>