原创
重新学习延时程序
2011-9-28 14:34
1946
11
16
分类:
软件与OS
在TI提供的CC2510参考代码中有一段延时程序写得挺不错,说它不错是困想不出作者是怎么想到这个方法的,如果也是经过对所有指令的执行时间合计才选择这样的,那许可以做得更精确,如果没有的话那是怎么想到的呢?这就是这段代码被反复玩味的原因。相信除我之还有许多CCXXX0的用户也有同样的困惑。
今天试着来分析下这段代码:
void halWait(BYTE wait)
{
UINT32 largeWait;
if(wait == 0)
{return;}
largeWait = ((UINT16) (wait << 7));
largeWait += 59*wait;
largeWait = (largeWait >> CLKSPD); //CLKSPD代表时钟分频数,这里为0
while(largeWait--); //行7
return;
}
假定选择了26M外部晶振,而且主时钟不作分频,那么以上代码以26M的速度执行。行7以外的代码很容易看懂,却不能看出这计算largeWait的方法原理何在。为了弄清楚计算largeWait的方式背后的初衷,就只能查看IAR编译后的代码了。
0X026B:
MOV V4,V0 1
MOV V5,V1 1
MOV V6,V2 1
MOV V7,V3 1
MOV V0,V4 1
?L_ADD_X
MOVX A,@DPTR 3-10
ADD A,@R0 2
MOV @R0,A 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
ADDC A,@R0 2
MOV @R0,A 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
ADDC A,@R0 2
MOV @R0,A 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
ADDC A,@R0 2
MOV @R0,A 3
RET 4
?L_EQ_X
MOVX A,@DPTR 3-10
XRL A,@R0 2
JNZ 0X006E 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
XRL A,@R0 2
JNZ 0X006E 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
XRL A,@R0 2
JNZ 0X006E 3
INC R0 2
INC DPTR 1
MOVX A,@DPTR 3-10
XRL A,@R0 2
0X006E:RET 4
这段代码分成3个部分,我们只关注时间开销,每行的最后一个个数字代表执行所需指令周期,以此来看行7运行一次所需的时间大概在120~176个时钟周期。从理论上计算每毫秒需要26000个时钟周期。下面再看延时时间和代码执行所耗周期、理论周期的对比。
第一列是时间(ms),第二列是最少消耗时钟周期数,第三列是最大消耗时钟周期数,第四列则取二、三列的平均值,第五列是理论上需要的时钟周期数。
所以这段代码确实实现ms级的延时,最大误差为6.45%。好像大家伙看完都不怎么说话,可能是我之前的blog写得太简单了,往后我得发力写出新得。
Tome(emot)
2011年9月28日
用户1660450 2011-10-8 14:29
zigbee_904218839 2011-10-8 09:27
用户1660450 2011-9-30 09:46
zigbee_904218839 2011-9-29 18:34
用户1660450 2011-9-29 14:02