散分,让我费解的延时函数

笑哈哈   2009-1-19 00:48 楼主

  1. /****************************
  2. //延时
  3. *****************************/
  4. void Delay(uchar n)
  5. {
  6.   uchar tt;
  7.       for(tt = 0;tt
  8.       for(tt = 0;tt

  9.       return ;
  10. }


采用的是CC2430芯片,32M晶振,大概测了一下,Delay(1);竟然用了1us多一点

书上了资料说:CC2430/CC2431 增强型8051 内核使用标准8051 指令集,具有8 倍的标准8051 内核的性能。每个时钟周期为一个机器周期而标准8051 中是12 个时钟周期为一个机器周期。

但是理论数据与实际运行的时间不符啊,为什么呢?应该怎么精确计算呢?

回复评论 (18)

这个是有跳转的吧。应该换成汇编指令算时间。
点赞  2009-1-19 09:07
在CE下,要实现LZ想要的精确度比较困难。

因为除了晶振的精确时间外,还有系统执行的时间,所以在应用层得到的精确度不太可靠。
点赞  2009-1-19 09:10
要用专门的仪器查一下
点赞  2009-1-19 11:01
如果有异步事件,比如中断,怎么办? 所以要想时间确定,如果可以,至少需要把这段代码座做为临界段处理。
点赞  2009-1-19 12:22
32MHz, 单时钟周期,一个周期31.25nS, 32个时钟周期=1uS。

这个延时程序,编译后(Keil C8.08)本身有16个汇编指令,按照平均 1指令=2时钟周期 来计算,正好32个时钟周期,正好1uS

算上肯定会多出的:入口保存、出口恢复指令,还要略多一点点。

     8: void usDelay(unsigned char n)
     9: {
    10:     unsigned char tt;
    11:       for(tt = 0;tt C:0x0040    E4       CLR      A
C:0x0041    FE       MOV      R6,A
C:0x0042    EE       MOV      A,R6
C:0x0043    C3       CLR      C
C:0x0044    9F       SUBB     A,R7
C:0x0045    5003     JNC      C:004A
C:0x0047    0E       INC      R6
C:0x0048    80F8     SJMP     C:0042
    12:       for(tt = 0;tt     13:  
    14:       return ;
C:0x004A    E4       CLR      A
C:0x004B    FE       MOV      R6,A
C:0x004C    EE       MOV      A,R6
C:0x004D    C3       CLR      C
C:0x004E    9F       SUBB     A,R7
C:0x004F    5003     JNC      C:0054
C:0x0051    0E       INC      R6
C:0x0052    80F8     SJMP     C:004C
    15: }
点赞  2009-1-19 13:12
楼上的方法也很好哦,不过自己还是不太会做这个....谢谢大家的关注
点赞  2009-1-19 14:24
引用: 引用 1 楼 BEYONDMA 的回复:
这个是有跳转的吧。应该换成汇编指令算时间。

具体不知道怎么实现,哎,还要加油学习啊~~
点赞  2009-1-19 14:25
引用: 引用 4 楼 zyzhang365 的回复:
如果有异步事件,比如中断,怎么办? 所以要想时间确定,如果可以,至少需要把这段代码座做为临界段处理。

这个应该考虑
点赞  2009-1-19 14:25
要实现精确定时,就必须做到:

对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。

对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。

调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。
点赞  2009-1-19 22:21
引用: 引用 9 楼 shuiyan 的回复:
要实现精确定时,就必须做到:

对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。

对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。

调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。

引用: 引用 7 楼 wptad 的回复:
引用 1 楼 BEYONDMA 的回复:
这个是有跳转的吧。应该换成汇编指令算时间。

具体不知道怎么实现,哎,还要加油学习啊~~


shuiyan说的太好了,没有补充了

但是我有疑问,如果你在操作系统下使用这种延时函数,比如wince下,在延时期间关闭中断,那么会严重影响wince系统的性能吧
shuiyan前辈进来说说啊。我看有些人在wince下真这么做,我觉得非常不合理,我觉得在操作系统下应该使用定时器来延时比价合适
请指教。
点赞  2009-1-20 08:50
学习
点赞  2009-1-20 09:44
mark学习
点赞  2009-1-20 10:30
引用: 引用 10 楼 gooogleman 的回复:
引用 9 楼 shuiyan 的回复:
要实现精确定时,就必须做到:

对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。

对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。

调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。


引用 7 楼 wptad 的回复:
引用 1 楼 BEYONDMA 的回复:
这个…


如果需要特别精确,那只能专门使用一个芯片,用来计时,哈哈~~

那这样看来,只能用定时器中断简单一些,还现在就改程序,郁闷~~
点赞  2009-1-20 11:27
大家还有好的想法么?
对了,在avr GCC的函数库中包有个非常有用的精确延时函数,
#include

但是我的环境是IAR,不能使用....
点赞  2009-1-20 11:29
等我把DS18B20的程序写好了,就结贴,希望越快越好.....
点赞  2009-1-20 11:29
GCC AVR是开源的,可以找到源码的。不过你得懂avr的相关寄存器才能看的懂。

DS18B20以前一直用汇编写的,因为在C里面对1-Wire的时序不好控制,尤其是任务多的情况下。

还是用定时器吧,定时小点,尽量精确。
点赞  2009-1-20 12:49
引用: 引用 16 楼 shuiyan 的回复:
GCC AVR是开源的,可以找到源码的。不过你得懂avr的相关寄存器才能看的懂。

DS18B20以前一直用汇编写的,因为在C里面对1-Wire的时序不好控制,尤其是任务多的情况下。

还是用定时器吧,定时小点,尽量精确。


自己用定时器做了一个,效果不好,可能是代码有问题,有没有好一点的代码分享一下?
点赞  2009-1-20 17:58
cc2430太难控制了,我改用at89c2051
点赞  2009-1-21 01:15
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复