415462822 发表于 2010-12-5 09:44:43

UCOS-II的OSTimeDlyHMSM(0,0,0,1);延时不准是怎么回事

我将UCOS-II的系统时钟设为1ms,那么OSTimeDlyHMSM(0,0,0,1);的延时时间也应该为1ms,可是我用KEIL进行仿真发现差了很多。执行
OSTimeDlyHMSM(0,0,0,1);只有2ns的延时,OSTimeDlyHMSM(0,0,1,0);和OSTimeDlyHMSM(0,1,0,0);也测试过与理论值差了很多分别只有0.2s和11.98731s。
但是用同样的方法测试OSTimeDly(1)函数的延时确实准确的1ms。我也对照了其它ucos-ii程序的OSTimeDlyHMSM(0,0,0,1);函数发现跟我现用的函数内容是一模一样的。不知道用过这函数的朋友出现过我同样的问题吗?还是我漏掉了某重要的部分?望大家指教。

AVR_DIY 发表于 2010-12-6 11:21:17

回复【楼主位】415462822 头文字C
    我将ucos-ii的系统时钟设为1ms,那么ostimedlyhmsm(0,0,0,1);的延时时间也应该为1ms,可是我用keil进行仿真发现差了很多。执行
ostimedlyhmsm(0,0,0,1);只有2ns的延时,ostimedlyhmsm(0,0,1,0);和ostimedlyhmsm(0,1,0,0);也测试过与理论值差了很多分别只有0.2s和11.98731s。
但是用同样的方法测试ostimedly(1)函数的延时确实准确的1ms。我也对照了其它ucos-ii程序的ostimedlyhmsm(0,0,0,1);函数发现跟我现用的函数内容是一模一样的。不知道用过这函数的朋友出现过我同样的问题吗?还是我漏掉了某重要的部分?望大家指教。
-----------------------------------------------------------------------

你晶振配置的不对?
另外,你一个节拍配置为1MS,这对于单片机来说开销太大了! 速度不够快的话,你延时OSTimeDlyHMSM(0,0,0,1)1MS误差很大的,因为OSTimeDlyHMSM(0,0,0,1)这个函数的延时最终还是换算成OSTimeDly(1)函数来实现延时,加上一些中断响应延时...这个我也测试过,不过不是软仿真,我是用硬件测的!

avrgogo 发表于 2010-12-6 11:59:17

这个本来就不是很准,要准,必须用中断。

health 发表于 2010-12-6 12:05:53

理论上就是这样。
即使没有别的任务运行,最大误差也为一个时钟节拍。
如果有更高优先级任务运行,定时时间到,任务就绪并不一定会立即运行,轮到此任务运行不一定多少时间了。

pbxywyq 发表于 2010-12-6 12:37:43

OSTimeDlyHMSM最小延时为OSTimeDly(1),当设置的值<1Tick时,任务立即就绪,也就是根本不延时;因此,延时不准是因为你函数调用方法的问题,不是晶振或其他因素引起的!你应该看看OSTimeDlyHMSM的源码。

simplorer 发表于 2010-12-7 11:01:11

压堆栈,出堆栈都需要时间消耗!

415462822 发表于 2010-12-7 13:35:39

回复【4楼】pbxywyq

-----------------------------------------------------------------------

如果像你所说“当设置的值<1Tick时,任务立即就绪,也就是根本不延时;”,那为什么我使用ostimedlyhmsm(0,0,1,0);延时1s也不准列?它的设置值不是>1Tick吗?

health 发表于 2010-12-7 15:26:05

原因已经说过了,再重复一遍。
不管延时多长时间,最终都需要转换为以时钟节拍为单位。
例如,如果时钟节拍设为10ms,也就是说每隔10ms产生一个节拍,
延时1个时钟节拍,则任务挂起,等1一个时钟节拍产生后任务就绪。
时钟节拍的发生和任务是异步的,如果延时操作之后恰好立即产生节拍,则任务立即就绪,延时时间接近0。
如果延时操作前刚发生过节拍,则需等待10ms后才会再发生一次节拍,即延时时间为一个节拍。

同理,延时多个时钟节拍,实际时间应该有最大一个节拍的误差。
另外这个只是任务就绪的时间,如果有高优先级任务在执行,还要一直延时下去。

说的不是很清楚,用图来表示的话会清晰一些。

AVR_DIY 发表于 2010-12-7 15:50:25

回复【7楼】health
原因已经说过了,再重复一遍。
不管延时多长时间,最终都需要转换为以时钟节拍为单位。
例如,如果时钟节拍设为10ms,也就是说每隔10ms产生一个节拍,
延时1个时钟节拍,则任务挂起,等1一个时钟节拍产生后任务就绪。
时钟节拍的发生和任务是异步的,如果延时操作之后恰好立即产生节拍,则任务立即就绪,延时时间接近0。
如果延时操作前刚发生过节拍,则需等待10ms后才会再发生一次节拍,即延时时间为一个节拍。
同理,延时多个时钟节拍,实际时间应该有最大一个节拍的误差。
另外这个只是任务就绪的时间,如果有高优先级任务在执行,还要一直延时下去。
说的不是很清楚,用图来表示的话会清晰一些。
-----------------------------------------------------------------------

楼上分析的很透彻!不用图像也很容易理解!
也就说不管你延时多长误差都会在一个时钟接拍内。

415462822 发表于 2010-12-7 23:51:54

回复【7楼】health
原因已经说过了,再重复一遍。
不管延时多长时间,最终都需要转换为以时钟节拍为单位。
例如,如果时钟节拍设为10ms,也就是说每隔10ms产生一个节拍,
延时1个时钟节拍,则任务挂起,等1一个时钟节拍产生后任务就绪。
时钟节拍的发生和任务是异步的,如果延时操作之后恰好立即产生节拍,则任务立即就绪,延时时间接近0。
如果延时操作前刚发生过节拍,则需等待10ms后才会再发生一次节拍,即延时时间为一个节拍。

同理,延时多个时钟节拍,实际时间应该有最大一个节拍的误差。
另外这个只是任务就绪的时间,如果有高优先级任务在执行,还要一直延时下去。

说的不是很清楚,用图来表示的话会清晰一些。
-----------------------------------------------------------------------
我已经明白你的意思了 ostimedly(1);这个函数就等于一个时钟节拍,现定为1ms。
你上面所说的都和这个函数有关。
但我想问的是ostimedlyhmsm(0,0,0,1);这个函数为什么不准确? 它和时钟节拍的关系是什么?
我已经将STM32的系统时钟倍频为72Mhz了,难道还不够快吗?
还是我使用ostimedlyhmsm(0,0,0,1);的方法不正确?
如果不正确的话,如何使用才能得到精确的延时?

june4th 发表于 2010-12-8 00:29:48

OSTimeDlyHMSM(0,0,0,1)这个我虽然用过,但没去注意精确地时间,但OSTimeDly(1)的实际运行时间我是在72M的STM32F103系统里面测试过的,一点都不准,是在0~(1/OS_TICKS_PER_SEC)之间。也就是说OS_TICKS_PER_SEC=1000的话,延迟时间是0~1ms的任意值。在Labrosse的书里面,OSTimeDly()项目下明确说明如果要保证1/OS_TICKS_PER_SEC延迟,参数应该为2。

这种实时性强的东西,不要相信仿真,只能相信示波器。

我用的是官方2.86的STM32 Ports,参考书为《MicroC OS II, The Real-Time Kernel, 2nd Ed. - Labrosse 2002.pdf》,你可以用电驴的ed2k网络搜索并下载到。

415462822 发表于 2010-12-8 09:40:37

回复【10楼】june4th 朴正欢
OSTimeDlyHMSM(0,0,0,1)这个我虽然用过,但没去注意精确地时间,但OSTimeDly(1)的实际运行时间我是在72M的STM32F103系统里面测试过的,一点都不准,是在0~(1/OS_TICKS_PER_SEC)之间。也就是说OS_TICKS_PER_SEC=1000的话,延迟时间是0~1ms的任意值。在Labrosse的书里面,OSTimeDly()项目下明确说明如果要保证1/OS_TICKS_PER_SEC延迟,参数应该为2。

这种实时性强的东西,不要相信仿真,只能相信示波器。

-----------------------------------------------------------------------

我已经确定OSTimeDly(1)的准确性了,我将OSTimeDly(1)和滴答时钟(时钟节拍)中断程序同时进行仿真,发现它们的时间是一样的。
我也用硬件验证过OSTimeDlyHMSM(0,0,0,1)这个函数不准。
我在任务里对LED进行取反,使用OSTimeDlyHMSM(0,0,3,0)每隔3s执行一次。但感觉上它1s内就执行完了。如果误差只有几ms的话我就不追究了。但是这个误差实在是太大了。已经影响到使用了。

AVR_DIY 发表于 2010-12-8 09:42:30

回复【9楼】415462822 头文字C
回复【7楼】health
原因已经说过了,再重复一遍。
不管延时多长时间,最终都需要转换为以时钟节拍为单位。
例如,如果时钟节拍设为10ms,也就是说每隔10ms产生一个节拍,
延时1个时钟节拍,则任务挂起,等1一个时钟节拍产生后任务就绪。
时钟节拍的发生和任务是异步的,如果延时操作之后恰好立即产生节拍,则任务立即就绪,延时时间接近0。
如果延时操作前刚发生过节拍,则需等待10ms后才会再发生一次节拍,即延时时间为一个节拍。
同理,延时多个时钟节拍,实际时间应该有最大一个节拍的误差。
另外这个只是任务就绪的时间,如果有高优先级任务在执行,还要一直延时下去。
说的不是很清楚,用图来表示的话会清晰一些。
-----------------------------------------------------------------------
我已经......
-----------------------------------------------------------------------

看来你还没有明白.....
你去看看源代码就清楚了!

John_Lee 发表于 2010-12-8 15:26:16

从来不用OSTimeDlyHMSM,浪费代码空间。
Tick=1ms,要延时3s,只需OSTimeDly(3000)即可,或者OSTimeDly(OS_TICKS_PER_SEC * 3)。

chenfu 发表于 2010-12-8 17:33:37

回复【12楼】AVR_DIY 苹果的另一半
-----------------------------------------------------------------------

我觉得是你们没看懂楼主的问题。。。按你说最大误差是1个Tick + 高于本任务优先级的任务。但是楼主已经误差的太大了吧。

AVR_DIY 发表于 2010-12-8 20:51:21

回复【14楼】chenfu
回复【12楼】avr_diy 苹果的另一半
-----------------------------------------------------------------------
我觉得是你们没看懂楼主的问题。。。按你说最大误差是1个tick + 高于本任务优先级的任务。但是楼主已经误差的太大了吧。
-----------------------------------------------------------------------

楼上的,KEIL中的仿真能和实际的比吗???

415462822 发表于 2010-12-8 21:33:40

大家说的都是为什么ostimedlyhmsm(0,0,0,1);的延时会>1ms,但我的问题却是为什么ostimedlyhmsm(0,0,0,1);会<1ms。
虽然大家误解了我的意思,但是通过看的家的回帖,我已经发现什么ostimedlyhmsm(0,0,0,1);会<1ms的原因了。
原因很简单在OS_CFG.H文件中定义了
#define OS_TICKS_PER_SEC   200
它对应的UC/OS-II时钟周期为5ms
但我现在设置的UC/OS-II的时钟周期为1ms,所以应该定义OS_TICKS_PER_SEC为1000。
#define OS_TICKS_PER_SEC   1000
这样定义后,再进行仿真ostimedlyhmsm(0,0,0,1);就约等于1ms了。

谢谢大家了,没有大家的回帖我解决不了这个问题。

John_Lee 发表于 2010-12-8 23:21:00

我倒!

ba_wang_mao 发表于 2010-12-10 08:47:39

最终结论:

http://cache.amobbs.com/bbs_upload782111/files_35/ourdev_603673UK1DIN.JPG
(原文件名:12.JPG)

chenfu 发表于 2010-12-10 13:13:58

倒,问问题,竟然也搞乌龙。

415462822 发表于 2010-12-10 16:37:08

回复【19楼】chenfu
-----------------------------------------------------------------------

我没想到会让大家产生误解

hnsw 发表于 2011-6-16 16:10:22

mark~~~~

ShaoKn 发表于 2011-8-11 20:53:30

mark

xrwgy 发表于 2011-8-15 17:11:03

ticks抖动引起,或晶振不准。

maxiang1985 发表于 2012-7-17 09:22:32

mark。。。。。。。。。。

chenchengtao 发表于 2012-10-25 15:48:59

学习了            

中国力量 发表于 2013-2-8 04:02:19

呃 这个还是看配置吧

i55x 发表于 2013-2-8 15:07:43

居然是这么RZ的错误。

lxl_lw 发表于 2013-2-20 07:39:50

要是想要实现1us的延时,怎么实现啊?
页: [1]
查看完整版本: UCOS-II的OSTimeDlyHMSM(0,0,0,1);延时不准是怎么回事