- /****************************
- //延时
- *****************************/
- void Delay(uchar n)
- {
- uchar tt;
- for(tt = 0;tt
- for(tt = 0;tt
- return ;
- }
采用的是CC2430芯片,32M晶振,大概测了一下,Delay(1);竟然用了1us多一点
书上了资料说:CC2430/CC2431 增强型8051 内核使用标准8051 指令集,具有8 倍的标准8051 内核的性能。每个时钟周期为一个机器周期而标准8051 中是12 个时钟周期为一个机器周期。
但是理论数据与实际运行的时间不符啊,为什么呢?应该怎么精确计算呢?
在CE下,要实现LZ想要的精确度比较困难。
因为除了晶振的精确时间外,还有系统执行的时间,所以在应用层得到的精确度不太可靠。
如果有异步事件,比如中断,怎么办? 所以要想时间确定,如果可以,至少需要把这段代码座做为临界段处理。
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: }
楼上的方法也很好哦,不过自己还是不太会做这个....谢谢大家的关注
要实现精确定时,就必须做到:
对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。
对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。
调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。
引用: 引用 9 楼 shuiyan 的回复:
要实现精确定时,就必须做到:
对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。
对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。
调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。
引用: 引用 7 楼 wptad 的回复:
引用 1 楼 BEYONDMA 的回复:
这个是有跳转的吧。应该换成汇编指令算时间。
具体不知道怎么实现,哎,还要加油学习啊~~
shuiyan说的太好了,没有补充了
但是我有疑问,如果你在操作系统下使用这种延时函数,比如wince下,在延时期间关闭中断,那么会严重影响wince系统的性能吧
shuiyan前辈进来说说啊。我看有些人在wince下真这么做,我觉得非常不合理,我觉得在操作系统下应该使用定时器来延时比价合适
请指教。
引用: 引用 10 楼 gooogleman 的回复:
引用 9 楼 shuiyan 的回复:
要实现精确定时,就必须做到:
对汇编极其熟悉,这样才能根据编译的结果,去判断延时函数到底需要执行多长时间。
对系统的函数调用机制极其熟悉,才能知道调用前、调用后分别多用几条代码做额外保护现场和恢复现场的处理。
调用延时之前要禁止所有中断,之后再使能需要的中断,确保延时中不会被中断打断,造成失控。
引用 7 楼 wptad 的回复:
引用 1 楼 BEYONDMA 的回复:
这个…
如果需要特别精确,那只能专门使用一个芯片,用来计时,哈哈~~
那这样看来,只能用定时器中断简单一些,还现在就改程序,郁闷~~
大家还有好的想法么?
对了,在avr GCC的函数库中包有个非常有用的精确延时函数,
#include
但是我的环境是IAR,不能使用....
等我把DS18B20的程序写好了,就结贴,希望越快越好.....
GCC AVR是开源的,可以找到源码的。不过你得懂avr的相关寄存器才能看的懂。
DS18B20以前一直用汇编写的,因为在C里面对1-Wire的时序不好控制,尤其是任务多的情况下。
还是用定时器吧,定时小点,尽量精确。
引用: 引用 16 楼 shuiyan 的回复:
GCC AVR是开源的,可以找到源码的。不过你得懂avr的相关寄存器才能看的懂。
DS18B20以前一直用汇编写的,因为在C里面对1-Wire的时序不好控制,尤其是任务多的情况下。
还是用定时器吧,定时小点,尽量精确。
自己用定时器做了一个,效果不好,可能是代码有问题,有没有好一点的代码分享一下?