问题描述如下:
由于需要精确的时序,在C工程中嵌入了汇编代码,当然这样的事情也经常做,但是这次发现了问题,而且一时半会没办法解决。
具体的情况是我需要操作一个IO口输出特定的时序,使用汇编语句精确计算了执行的时钟数,最终输出也‘基本符合’要求的时序,不过出现了及其细微的误差,这个误差不是显性的能看出来(比如通过代码),而且用示波器看的时候才出现。
时序是,将输入的字节内容(累加器A)按位进行曼切斯特编码输出到IO口,问题现象是,例如ACC.0是50us正确,ACC.1就是52us,ACC.2又是50us,ACC.3又是52us如此比较有规律的出现(偶尔也会出现51us的时候),代码如下:
MOVX A,@DPTR; 3 //得到需要传输的内容
EA=0; //关闭全局中断,防止打乱时序
rlc a; 1
jc B0; 2/4
nop; 1
nop; 1
lcall BIT_0; 5
ajmp $+8; 4
B0: lcall BIT_1; 5
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B1;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B1: lcall BIT_1;
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B2;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B2: lcall BIT_1;
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B3;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B3: lcall BIT_1;
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B4;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B4: lcall BIT_1;
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B5;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B5: lcall BIT_1;
NOP;
NOP;
NOP;
; NOP;
rlc a;
jc B6;
nop;
nop;
lcall BIT_0;
ajmp $+8;
B6: lcall BIT_1;
。。。
以下的位都是一样的了。。。略去。
////////////////////////////////////////
这里是BIT_1和BIT_0
//------//
BIT_1:
setb ASK; //IO 口
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
clr ASK;
ret; //total:30 clk
BIT_0:
clr ASK; //IO口
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
nop;
NOP;
nop;
;nop;
setb ASK;
ret; //total:30 clk
//------//
上面的BIT_1和BIT_0函数部分其具体的执行细节可以不管具体是多少个周期,问题关键是例如将累加器的值固定为全1(0xff)或者全0(0x00)后,后续的B3:,以及B4:就会出现前面描述的执行时钟会偏差1、2个时钟周期的现象。而且随着BIT_1和BIT_0函数的摆放位置不同(比如现在是放在调用主体后面的,当放在调用主体前面就是不同)后,执行结果居然就有差异。
特别说明一下,上述代码在执行过程中绝对没有被中断等干扰 现象,因为使用前关闭了全局中断EA=0
汇编后的代码如下,可见完全有规律,根本没有哪里多一条指令或者少一条指令的现象,连跳转的间隔都是一样的。
C:0x19F0 12193E LCALL BIT_1(C:193E)
C:0x19F3 00 NOP
C:0x19F4 00 NOP
C:0x19F5 00 NOP
C:0x19F6 33 RLC A
C:0x19F7 4007 JC B1(C:1A00)
C:0x19F9 00 NOP
C:0x19FA 00 NOP
C:0x19FB 12195A LCALL BIT_0(C:195A)
C:0x19FE 4106 AJMP C:1A06
B1:
C:0x1A00 12193E LCALL BIT_1(C:193E)
C:0x1A03 00 NOP
C:0x1A04 00 NOP
C:0x1A05 00 NOP
C:0x1A06 33 RLC A
C:0x1A07 4007 JC B2(C:1A10)
C:0x1A09 00 NOP
C:0x1A0A 00 NOP
C:0x1A0B 12195A LCALL BIT_0(C:195A)
C:0x1A0E 4116 AJMP C:1A16
B2:
C:0x1A10 12193E LCALL BIT_1(C:193E)
C:0x1A13 00 NOP
C:0x1A14 00 NOP
C:0x1A15 00 NOP
C:0x1A16 33 RLC A
C:0x1A17 4007 JC B3(C:1A20)
C:0x1A19 00 NOP
C:0x1A1A 00 NOP
C:0x1A1B 12195A LCALL BIT_0(C:195A)
C:0x1A1E 4126 AJMP C:1A26
B3:
C:0x1A20 12193E LCALL BIT_1(C:193E)
C:0x1A23 00 NOP
C:0x1A24 00 NOP
C:0x1A25 00 NOP
C:0x1A26 33 RLC A
C:0x1A27 4007 JC B4(C:1A30)
C:0x1A29 00 NOP
C:0x1A2A 00 NOP
C:0x1A2B 12195A LCALL BIT_0(C:195A)
C:0x1A2E 4136 AJMP C:1A36
B4:
C:0x1A30 12193E LCALL BIT_1(C:193E)
C:0x1A33 00 NOP
C:0x1A34 00 NOP
C:0x1A35 00 NOP
C:0x1A36 33 RLC A
C:0x1A37 4007 JC B5(C:1A40)
C:0x1A39 00 NOP
C:0x1A3A 00 NOP
C:0x1A3B 12195A LCALL BIT_0(C:195A)
C:0x1A3E 4146 AJMP C:1A46
B5:
C:0x1A40 12193E LCALL BIT_1(C:193E)
C:0x1A43 00 NOP
C:0x1A44 00 NOP
C:0x1A45 00 NOP
C:0x1A46 33 RLC A
C:0x1A47 4007 JC B6(C:1A50)
C:0x1A49 00 NOP
C:0x1A4A 00 NOP
C:0x1A4B 12195A LCALL BIT_0(C:195A)
C:0x1A4E 4156 AJMP C:1A56
B6:
C:0x1A50 12193E LCALL BIT_1(C:193E)
太长太多,求高手
一周热门 更多>