搜索
bottom↓
回复: 0

请51汇编或者编译器使用的高手解决问题,keil @ C8051系列MCU

[复制链接]

出0入475汤圆

发表于 2013-6-22 23:25:55 | 显示全部楼层 |阅读模式
问题描述如下:
由于需要精确的时序,在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)


太长太多,求高手

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 16:24

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表