打印

菜鸟问题:一个keil调试错误

[复制链接]
3270|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
沙发
yeshaozhu|  楼主 | 2009-12-3 21:08 | 只看该作者
file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/8WF(]R]{EBUP_Q$1]0BONAN.jpg

使用特权

评论回复
板凳
emailli| | 2009-12-3 22:44 | 只看该作者
keydo 函数没有声明

使用特权

评论回复
地板
yeshaozhu|  楼主 | 2009-12-4 20:33 | 只看该作者
谢谢楼上的,但是好像定义了也还是有这样的错误。。。。:(
我把程序发上来,是一个简单的密码锁的程序,程序中有详尽的注释

#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int

//I/O口定义
sfr p0=0x80;
sfr p1=0x90;
sfr p2=0xa0;
sfr p3=0xb0;

//状态口定义
sbit red=p3^3;
sbit green=p3^2;
sbit speaker=p3^6;

//所用的数组定义
uchar b[10] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//数字
uchar error[5] = {0x11,0x03,0x11,0x11,0x61};       //密码输入错误时的提示
uchar good[4] = {0x85,0x03,0x03,0x09};             //密码输入正确时的提示
uchar lock[8] = {0xfd,0xfd,0x93,0x63,0x03,0xe3,0xfd,0xfd};             //锁定
uchar mima[8] = {4,4,4,4,4,4,4,4};
uchar pw[8] = {10,10,10,10,10,10,10,10};
uchar c[8];

//全局变量
uchar n=0,error_time=0;
bit mima_right;

void keydo(uchar); //按楼上说的进行声明

void delay(uint pp)   //误差 0us
{
        uchar a,b,c;
        while(pp--)
        {
   
    for(c=1;c>0;c--)
        for(b=142;b>0;b--)
            for(a=2;a>0;a--);//1ms
        }
}

void display()
{
        uchar i;
        for(i=0;i<n;i++)          //为了让8个数码管轮流亮一遍过去
        {
                P0=c[i];
                P2=i;
                delay(2);
        }

}


/*----键盘扫描-------------------------*/
uchar KeyScan()
{
                        uchar num=100,temp;
                        p1=0xfe;
                        temp=p1;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=p1;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=p1;
                                        switch(temp)
                                                {
                                                        case 0xee:num=0;
                                                                break;
                                                        case 0xde:num=1;
                                                                break;
                                                        case 0xbe:num=2;
                                                                break;
                                                        case 0x7e:num=3;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=p1;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }

                        p1=0xfd;
                        temp=p1;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=p1;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=p1;
                                        switch(temp)
                                                {
                                                        case 0xed:num=4;
                                                                break;
                                                        case 0xdd:num=5;
                                                                break;
                                                        case 0xbd:num=6;
                                                                break;
                                                        case 0x7d:num=7;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=p1;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }


                        p1=0xfb;
                        temp=p1;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=p1;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=p1;
                                        switch(temp)
                                                {
                                                        case 0xeb:num=8;
                                                                break;
                                                        case 0xdb:num=9;
                                                                break;
                                                        case 0xbb:num=10;
                                                                break;
                                                        case 0x7b:num=11;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=p1;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }


                        p1=0xf7;
                        temp=p1;
                        temp=temp&0xf0;
                        while(temp!=0xf0)
                                {
                                        delay(5);
                                        temp=p1;
                                        temp=temp&0xf0;
                                        while(temp!=0xf0)
                                        {
                                                temp=p1;
                                        switch(temp)
                                                {
                                                        case 0xe7:num=12;
                                                                break;
                                                        case 0xd7:num=13;
                                                                break;
                                                        case 0xb7:num=14;
                                                                break;
                                                        case 0x77:num=15;
                                                                break;
                                                }
                                        while(temp!=0xf0)
                                                {
                                                        temp=p1;
                                                        temp=temp&0xf0;
                                                }
                                        }
                                }
return num;

}
uint check() //比对密码,判断密码数否正确
{
        uint flag;
        uint i;
       
        if(n==8)   //密码位数为八位
        {
                for(i=0; i<8; i++)
                {
                        if(mima[i] != pw[i])
                        {
                                flag = 0;
                                break;
                        }
                        else
                        {
                                flag = 1;
                        }
                }
        }
        else
                flag = 0;

        return flag;
}

//对按键的响应

void keydo(uchar key)
{
        uint i;
        if(key < 10)    //对编码小于10 的按键的响应
        {
                if(n<8)
                {
                        pw[n] = key;      //保存输入的密码

                        for(i=7; i>0; i--) //赋值给c用于显示
                                c[i]=c[i-1];
                        c[0] = b[key];
                       
                        n++;      //位选加1
                }
        }
        else if(key == 11)// 按键编码为11,功能为确定键
        {
                if( check() )
                {
                        for(i=0; i<1; i++)
                        {
                                speaker = 0;
                                green = 0;
                                delay(200);
                                speaker = 1;
                                delay(200);
                        }
                }
                else
                {
                        for(i=0; i<3; i++)
                        {
                                speaker = 0;
                                red = 0;
                                delay(200);
                                speaker = 1;
                                red = 1;
                                delay(200);
                        }
                }
                for(i=0; i<8; i++)//置输入为乱码,为下一次输入做准备
                        pw[i] = 10;
        }
}


void main()
{
        uchar key;

        green = 1;         //初始化绿灯端口,不亮
        red = 1;         //初始化红灯端口,不亮
        speaker = 1;         //初始化蜂鸣器端口,不响

        while(1)
        {
                key = KeyScan();

                if(key != 100)          //当有按键按下时,关闭所有指示灯和蜂鸣器
                {                     //该功能暂定,根据要求可以删除
                        green = 1;
                        red = 1;
                        speaker = 1;
                }

                keydo(key);
                display();
        }
}

使用特权

评论回复
5
yeshaozhu|  楼主 | 2009-12-6 10:50 | 只看该作者
为什么没人理我。。。。。:'(

使用特权

评论回复
6
yazhi68| | 2009-12-6 16:35 | 只看该作者
for(i=0; i<8; i++)//置输入为乱码,为下一次输入做准备
                        pw[i] = 10;
:(
我也不知道这句出了什么问题。
先弄三分

使用特权

评论回复
7
chen3bing| | 2009-12-6 19:23 | 只看该作者
uint i;
keydo函数里的变量i改成
uchar i;就可以了。
我也搞不懂。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
yeshaozhu + 1
8
yeshaozhu|  楼主 | 2009-12-6 20:36 | 只看该作者
本帖最后由 yeshaozhu 于 2009-12-6 20:48 编辑

还是不知道为什么,不过按照楼上说的正确了!
谢谢!
不过还是期望高手能继续为我们分析分析是为什么?

使用特权

评论回复
9
yazhi68| | 2009-12-8 18:49 | 只看该作者
:curse:
看来高人们没空来上课了,水货再来提个问题,顺便弄3分。

ERROR:      CANNOT OPTIMIZE FUNCTION
已经提示了优化出了问题。

试验1
uint i 改成 uchar i
.lst
...
256   2                     for(i=0;i<8;i++)  pw[i] = 10;
...
                                           ; SOURCE LINE # 256
0072         ?C0085:
0072 7908              MOV     R1,#08H
0074 7800        R     MOV     R0,#LOW pw
0076 740A              MOV     A,#0AH
0078         ?C0095:
0078 F6                MOV     @R0,A
0079 08                INC     R0
007A D9FC              DJNZ    R1,?C0095

试验2
还用uint i;
优化级别选6,编译能通过
.lst
...
256   2                     for(i=0;i<8;i++)  pw[i] = 10;
...
                                           ; SOURCE LINE # 256
00A7 E4                CLR     A
00A8 F500        R     MOV     i,A
00AA F500        R     MOV     i+01H,A
00AC         ?C0085:
00AC 7400        R     MOV     A,#LOW pw
00AE 2500        R     ADD     A,i+01H
00B0 F8                MOV     R0,A
00B1 760A              MOV     @R0,#0AH
00B3 0500        R     INC     i+01H
00B5 E500        R     MOV     A,i+01H
00B7 7002              JNZ     ?C0098
00B9 0500        R     INC     i
00BB         ?C0098:
00BB 6408              XRL     A,#08H
00BD 4500        R     ORL     A,i
00BF 70EB              JNZ     ?C0085

优化级别选高于6就通过不了。

试验3
还用uint i;
优化级别还选8。

把搂住的
for(i=0; i<8; i++)//置输入为乱码,为下一次输入做准备
                        pw[i] = 10;
改成
for(i=0; i<8; )  { i++; pw[i] = 10;}
编译通过。
.lst
...
256   2                     //for(i=0;i<8;i++)  pw[i] = 10;
257   2                     for(i=0;i<8;)  { i++;  pw[i] = 10;}
...
                                     ; SOURCE LINE # 257
0096 E4                CLR     A
0097 F583              MOV     DPH,A
0099 F582              MOV     DPL,A
009B         ?C0085:
009B C3                CLR     C
009C E582              MOV     A,DPL
009E 9408              SUBB    A,#08H
00A0 E583              MOV     A,DPH
00A2 9400              SUBB    A,#00H
00A4 500A              JNC     ?C0087
00A6 A3                INC     DPTR
00A7 7400        R     MOV     A,#LOW pw
00A9 2582              ADD     A,DPL
00AB F8                MOV     R0,A
00AC 760A              MOV     @R0,#0AH
00AE 80EB              SJMP    ?C0085

看了一下keil的优化。
Level Description
...
6 Loop Rotation: Program loops are rotated if the resulting program code is faster and more efficient. The loop expression of for and while loops is evaluated once at the top of the loop and then at the bottom of the loop. This optimization generates more code but speeds up execution.  
7 Extended Index Access Optimizing: DPTR is used for register variables where appropriate. Pointer and array access are optimized for both execution speed and code size.  

到此可以认定,问题出在优化级别高于6时,编译器把DPTR分配给uint i 了。
水货的问题是,还用uint i,还用搂住的原来的写法,编译器会试图怎么优化(可能会产生什么样的汇编代码),以至于搞不下去了,报个错,排排屁股走人。

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
yeshaozhu + 1
10
yazhi68| | 2009-12-8 19:04 | 只看该作者
补充一下,
搂住的void keydo(uchar key)里,前面还3次用了i循环

for(i=7; i>0; i--) //赋值给c用于显示
                                c[i]=c[i-1];
for(i=0; i<1; i++)
{。。。
}
for(i=0; i<3; i++)
{。。。
}
尤其是第一次,和出问题的那句差不多,都没出问题,怎么到了出问题的那句编译器就不干了呢?

使用特权

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

本版积分规则

5

主题

32

帖子

0

粉丝