OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5373|回复: 11

SysTick不能准确延时

[复制链接]

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
发表于 2015-12-11 22:03:42 | 显示全部楼层 |阅读模式
5金钱
我要使用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函数里测试的。

最佳答案

查看完整内容[请看2#楼]

“当STK_VAL的值被减至0时,由硬件自动把重载寄存器STK_LOAD(SysTick reload value register)中保存的数据加载到STK_VAL,重新向下计数”,这是文档中对systic工作过程的说明。那么,当计数为0, 准备执行"while(temp&0x01&&!(temp&(1<<16))); //等待时间到达"(你这一句的意思应当是systic打开 && 定时未到则一直循环)时如果突然被一个中断打断,等中断执行完成回过头来继续执行时val的 ...
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2013-5-3
在线时间
40 小时
发表于 2015-12-11 22:03:43 | 显示全部楼层
“当STK_VAL的值被减至0时,由硬件自动把重载寄存器STK_LOAD(SysTick reload value register)中保存的数据加载到STK_VAL,重新向下计数”,这是文档中对systic工作过程的说明。那么,当计数为0,
准备执行"while(temp&0x01&&!(temp&(1<<16))); //等待时间到达"(你这一句的意思应当是systic打开 && 定时未到则一直循环)时如果突然被一个中断打断,等中断执行完成回过头来继续执行时val的值又等于load了,将继续执行循环,导致延时被延长,所以楼主应先将所有的中断关闭以后再进行测试才行。
但如果真是这种情况,那楼主的这个程序的实用性将大打折扣了。其实原子哥在他的例程中的us延时就已经很好了,完全可以参考。
恰如猛虎卧山丘,潜伏爪牙忍受!
回复

使用道具 举报

3

主题

2178

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3323
金钱
3323
注册时间
2013-7-19
在线时间
195 小时
发表于 2015-12-11 22:35:04 | 显示全部楼层
这个时间是不是51行和52行一块消耗的时间?断点是不是应该放在52行上?
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-11 23:28:18 | 显示全部楼层





相差5ms  ??
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-11 23:29:07 | 显示全部楼层
回复【3楼】kai20151211:
---------------------------------
时间时间是减少了,但还是不对啊!
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-12 11:01:04 | 显示全部楼层
回复【2楼】ricefat:
---------------------------------
回复【2楼】ricefat:
---------------------------------
怎么调都不行啊!烦
回复

使用道具 举报

1

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
188
金钱
188
注册时间
2013-5-3
在线时间
40 小时
发表于 2015-12-12 16:07:45 | 显示全部楼层
楼主查看一下系统时钟是不是72MHz, 
 RCC_ClocksTypeDef  rcc_clocks;  
 
 RCC_GetClocksFreq(&rcc_clocks);                       //获取SYSCLK,HCLK,PCLK1,PCLK2,单位Hz 

 sysclk = rcc_clocks.SYSCLK_Frequency;
 hclk    = rcc_clocks.HCLK_Frequency;
 pclk1  = rcc_clocks.PCLK1_Frequency;
 pclk2  = rcc_clocks.PCLK2_Frequency;

如果hclk是72M,那说明时钟没问题,但按照你仿真的结果,貌似hclk是12M左右。
恰如猛虎卧山丘,潜伏爪牙忍受!
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-12 19:54:31 | 显示全部楼层
回复【6楼】远方:
---------------------------------
我看看
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-12 21:05:46 | 显示全部楼层


是72M.......
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-13 09:16:24 | 显示全部楼层





这是SysTick时钟源的配置函数,SysTick_CLKSourse_HCLK_Div8 是0xFFFFFFFB, 也就是对CTRL寄存器的第3位置0,选择的是AHB时钟源除以8,而AHB时钟是0x44AA200,也就是72M,那算起来SysTick时钟应该是 72/8=9M 啊  。。。。
回复

使用道具 举报

3

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
53
金钱
53
注册时间
2015-12-11
在线时间
2 小时
 楼主| 发表于 2015-12-14 20:28:47 | 显示全部楼层
回复【10楼】远方:
---------------------------------
回复很给力,谢谢!
回复

使用道具 举报

0

主题

9

帖子

0

精华

新手上路

积分
35
金钱
35
注册时间
2016-11-29
在线时间
4 小时
发表于 2017-1-12 10:27:59 | 显示全部楼层
我的F103板子HCLK是8M ,  后来在主函数加SystemInit();  就变好了,非常感谢本帖!!!!!!!!!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-30 11:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表