打印
[国产单片机]

Keil中一个重大疑惑,也许是Keil的一个BUG

[复制链接]
2767|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
技美电子|  楼主 | 2011-9-2 16:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天做项目的时候发现Keil中一个重大疑惑,也许是Keil的一个BUG.如下:
(STC89C52)
第一种情况:(正确的)
先进行位定义
sbit    P10   =     P1^0;
sbit    P11   =     P1^1;
sbit    P12   =     P1^2;
sbit    P13   =     P1^3;
然后在函数中使用
for(i=0;i<4;i++){
         P1=~tmp;
         if(P10==0){
          keyTmp = (i*4+1);
          goto out1;
         }else if(P11==0){
          keyTmp = (i*4+2);
          goto out1;
         }else if(P12==0){
          keyTmp = (i*4+3);
          goto out1;
         }else if(P13==0){
          keyTmp = (i*4+4);
          goto out1;
         }
         tmp<<=1;
        }
Keil的汇编结果如下:
    50:         for(i=0;i<4;i++){
C:0x005C    E4       CLR      A
C:0x005D    FD       MOV      R5,A
    51:                 P1=~tmp;
C:0x005E    EF       MOV      A,R7
C:0x005F    F4       CPL      A
C:0x0060    F590     MOV      P1(0x90),A
    52:                if(P10==0){
C:0x0062    209009   JB       P10(0x90.0),C:006E
    53:                         keyTmp = (i*4+1);
C:0x0065    ED       MOV      A,R5
C:0x0066    25E0     ADD      A,ACC(0xE0)
C:0x0068    25E0     ADD      A,ACC(0xE0)
C:0x006A    04       INC      A
C:0x006B    FE       MOV      R6,A
    54:                         goto out1;
C:0x006C    804D     SJMP     C:00BB
    55:                }else if(P11==0){
C:0x006E    20910A   JB       P11(0x90.1),C:007B
    56:                         keyTmp = (i*4+2);
C:0x0071    ED       MOV      A,R5
C:0x0072    25E0     ADD      A,ACC(0xE0)
C:0x0074    25E0     ADD      A,ACC(0xE0)
C:0x0076    2402     ADD      A,#0x02
C:0x0078    FE       MOV      R6,A
    57:                         goto out1;
C:0x0079    8040     SJMP     C:00BB
    58:                 }else if(P12==0){
C:0x007B    20920A   JB       P12(0x90.2),C:0088
    59:                         keyTmp = (i*4+3);
C:0x007E    ED       MOV      A,R5
C:0x007F    25E0     ADD      A,ACC(0xE0)
C:0x0081    25E0     ADD      A,ACC(0xE0)
C:0x0083    2403     ADD      A,#0x03
C:0x0085    FE       MOV      R6,A
    60:                         goto out1;
C:0x0086    8033     SJMP     C:00BB
    61:                 }else if(P13==0){
C:0x0088    20930A   JB       P13(0x90.3),C:0095
    62:                         keyTmp = (i*4+4);
C:0x008B    ED       MOV      A,R5
C:0x008C    25E0     ADD      A,ACC(0xE0)
C:0x008E    25E0     ADD      A,ACC(0xE0)
C:0x0090    2404     ADD      A,#0x04
C:0x0092    FE       MOV      R6,A
    63:                         goto out1;
C:0x0093    8026     SJMP     C:00BB
    64:                 }
这种方法是我想要的结果。

第二种情况:
不进行位宏定义,直接在函数中使用
for(i=0;i<4;i++){
         P1=~tmp;
         if(P1^0==0){
          keyTmp = (i*4+1);
          goto out1;
         }else if(P1^1==0){
          keyTmp = (i*4+2);
          goto out1;
         }else if(P1^2==0){
          keyTmp = (i*4+3);
          goto out1;
         }else if(P1^3==0){
          keyTmp = (i*4+4);
          goto out1;
         }
         tmp<<=1;
        }
此时Keil的汇编结果如下:
    50:         for(i=0;i<4;i++){
C:0x005F    E4       CLR      A
C:0x0060    FD       MOV      R5,A
    51:                 P1=~tmp;
C:0x0061    EF       MOV      A,R7
C:0x0062    F4       CPL      A
C:0x0063    F590     MOV      P1(0x90),A
    52:                 if(P1^0==0){
C:0x0065    E590     MOV      A,P1(0x90)
C:0x0067    6401     XRL      A,#0x01
C:0x0069    6009     JZ       C:0074
    53:                         keyTmp = (i*4+1);
C:0x006B    ED       MOV      A,R5
C:0x006C    25E0     ADD      A,ACC(0xE0)
C:0x006E    25E0     ADD      A,ACC(0xE0)
C:0x0070    04       INC      A
C:0x0071    FE       MOV      R6,A
    54:                         goto out1;
C:0x0072    8050     SJMP     C:00C4
    55:                 }else if(P1^1==0){
C:0x0074    E590     MOV      A,P1(0x90)
C:0x0076    600A     JZ       C:0082
    56:                         keyTmp = (i*4+2);
C:0x0078    ED       MOV      A,R5
C:0x0079    25E0     ADD      A,ACC(0xE0)
C:0x007B    25E0     ADD      A,ACC(0xE0)
C:0x007D    2402     ADD      A,#0x02
C:0x007F    FE       MOV      R6,A
    57:                         goto out1;
C:0x0080    8042     SJMP     C:00C4
    58:                 }else if(P1^2==0){
C:0x0082    E590     MOV      A,P1(0x90)
C:0x0084    600A     JZ       C:0090
    59:                         keyTmp = (i*4+3);
C:0x0086    ED       MOV      A,R5
C:0x0087    25E0     ADD      A,ACC(0xE0)
C:0x0089    25E0     ADD      A,ACC(0xE0)
C:0x008B    2403     ADD      A,#0x03
C:0x008D    FE       MOV      R6,A
    60:                         goto out1;
C:0x008E    8034     SJMP     C:00C4
    61:                 }else if(P1^3==0){
C:0x0090    E590     MOV      A,P1(0x90)
C:0x0092    600A     JZ       C:009E
    62:                         keyTmp = (i*4+4);
C:0x0094    ED       MOV      A,R5
C:0x0095    25E0     ADD      A,ACC(0xE0)
C:0x0097    25E0     ADD      A,ACC(0xE0)
C:0x0099    2404     ADD      A,#0x04
C:0x009B    FE       MOV      R6,A
    63:                         goto out1;
C:0x009C    8026     SJMP     C:00C4
    64:                 }
变成了判断P1是否为0,与我想要的结果大相径庭!
因为这个问题,让我足足调试时间花多一个多小时呀!
哪位高手能解释下是什么原因吗?

相关帖子

沙发
t.jm| | 2011-9-2 17:44 | 只看该作者
sbit    P10   =     P1^0; 中的^是用来定义bit的,
if(P1^2==0)中的^是异或/XRL的意思,在加上优先级的干扰就更乱了。
应该用if( (P1&(1<<2)) != (1<<2) )

使用特权

评论回复
板凳
liuwenbin1984| | 2011-9-4 21:42 | 只看该作者
学习了。。。

使用特权

评论回复
地板
McuPlayer| | 2011-9-6 09:37 | 只看该作者
楼主首先要明确,sbit定义的变量,并不是宏定义
sbit定义的变量是bit变量

另外就是异或运算符的问题

使用特权

评论回复
5
技美电子|  楼主 | 2011-9-6 12:18 | 只看该作者
嗯,明白了!谢谢t.jm和McuPlayer的解说!小弟向你们敬礼了!:loveliness:

使用特权

评论回复
6
mqp108| | 2011-9-6 13:27 | 只看该作者
学习

使用特权

评论回复
7
Sea-Wolf| | 2011-9-6 16:13 | 只看该作者
路过拿分,今天要上100分

使用特权

评论回复
8
375606426| | 2011-9-7 16:45 | 只看该作者
#define..........是宏定义
sbit是位定义你滴明白????

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:技美电子——单片机开发,常用DIY电子元件和工具配套:http://lintar.taobao.com

6

主题

264

帖子

2

粉丝