打印

KEIL C 编译器的问题

[复制链接]
3901|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
niuniu1983|  楼主 | 2008-4-30 14:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
KEIL C 编译器的问题

定时器中断中调用一个扫描数码管的子函数,数码管由74HC595驱动。

//--------------------------------------------------------------
void main(void)
{
    init_mcu();
    while(1)
    {

    }
}
//--------------------------------------------------------------
void time0_over_int(void)interrupt 1 using 3    
{
 uint i = TIMER0_TIME;                //            
 
 TR0 = 0;
 TL0 = i;
 TH0 = i>>8;    
 TR0 = 1;

 led_dly_one_byte(test_reg_1,1);
}
//--------------------------------------------------------------
void    led_dly_one_byte(uchar number, bit dp)  //参数1为显示的数字,十六进制
{                        //参数2为小数点控制位,1为显示
    uchar    i,j;    
    i=~led_dly_table[number];        //取出的显示码是共阴,电路是共阳
    if(dp) i&=0x7f;
    for(j=0;j<8;j++)
    {
       if((i&0x80)==0x80) DS=1;        //串行数据输出制595
       else    DS=0;
        
       i<<=1;                //左移
       SHCP = 1;
           _nop_();
          SHCP = 0;                //串行时钟
    }
    STCP = 1;                //锁存
        _nop_();
       STCP = 0;
}
//--------------------------------------------------------------
现象:数码管不显示小数点。
原因:见反汇编
问题:函数led_dly_one_byte的临时变量一会用R7,一会用0X07?
      怎样避免类似的错误?

相关帖子

沙发
niuniu1983|  楼主 | 2008-4-30 14:09 | 只看该作者

11

使用特权

评论回复
板凳
xhtxzxw| | 2008-4-30 14:45 | 只看该作者

嘿嘿

很细心的,有点意思,那说明KEILC51有Bug了?
只能在函数里面指定一下RS0,RS1了?
PSW |= ....;//?

使用特权

评论回复
地板
niuniu1983|  楼主 | 2008-4-30 14:52 | 只看该作者

函数里指明?

那这个函数的通用性怎么保证?调用这个函数的函数若正在使用你指明的工作寄存器呢?


另外,怎么知道一个函数的临时变量要用到那些资源,用C语言还考虑这些吗??



刚试着转C,感觉那里都不对.........还是汇编好用

使用特权

评论回复
5
zgl7903| | 2008-4-30 15:04 | 只看该作者

不同的寄存器组

void time0_over_int(void)interrupt 1 using 3 
void led_dly_one_byte(uchar number, bit dp) using 3

试试看

使用特权

评论回复
6
niuniu1983|  楼主 | 2008-4-30 15:19 | 只看该作者

这样肯定没有问题了,

但是,写每一个函数都必须要知道编译器内部要用到哪些资源?并且,还要清楚你这个函数要被哪些函数调用,那些个函数中要用的资源是否与本函数的冲突.......

以前也写过两个来着,没有考虑这些个东西呢,连反汇编这回事都不知道.

现在感觉C语言没法用了。。。。

使用特权

评论回复
7
niuniu1983|  楼主 | 2008-4-30 16:40 | 只看该作者

这种问题是常见的呢,还是偶的编译器有问题?

感觉大家都没有遇到过这种情况

使用特权

评论回复
8
wxj1952| | 2008-4-30 20:04 | 只看该作者

中断函数里被调用的函数应设为可重入的reentrant

void led_dly_one_byte(uchar number, bit dp)  reentrant


使用特权

评论回复
9
niuniu1983|  楼主 | 2008-4-30 20:13 | 只看该作者

可重入?偶现查查什么叫可重入。

谢谢大家

使用特权

评论回复
10
niuniu1983|  楼主 | 2008-4-30 20:49 | 只看该作者

昨天试了试,改为重入函数也不行。

编译器只是把重入函数用到的临时变量重新开辟一个存储区。而这里的问题是,在调用函数的时候编译器还是用工作寄存器来传递参数。

后来,修改了一下KEIL的设置,好像解决问题了,如图

使用特权

评论回复
11
niuniu1983|  楼主 | 2008-5-1 09:05 | 只看该作者

//设置

使用特权

评论回复
12
niuniu1983|  楼主 | 2008-5-1 09:06 | 只看该作者

//汇编代码

使用特权

评论回复
13
niuniu1983|  楼主 | 2008-5-1 09:08 | 只看该作者

KEIL C就是为了节省一条指令?

看来,好像是这个样子。

呵呵//

使用特权

评论回复
14
niuniu1983|  楼主 | 2008-5-4 11:20 | 只看该作者

顶一下

使用特权

评论回复
15
wxj1952| | 2008-5-4 11:43 | 只看该作者

好精彩的问题帖子。

不是那么简单的。关系到C51编译器的设置,例如像#pragma NOAREGS.等等一些问题。

正在总结.....

使用特权

评论回复
16
niuniu1983|  楼主 | 2008-5-4 11:54 | 只看该作者

偶也觉得应该让更多的人看看,就顶上来了。

感觉编译器用好很难,也在看......

WXJ1952大侠总结后一定要发表啊,先谢谢啦

使用特权

评论回复
17
农民讲习所| | 2008-5-4 12:03 | 只看该作者

看看俺的培训教材,里面有

使用特权

评论回复
18
jack.king| | 2008-5-4 12:15 | 只看该作者

地址在那里啊?怎么去看你的培训啊?

使用特权

评论回复
19
icecut| | 2008-5-4 12:47 | 只看该作者

很不错

希望版主给条裤子
keil的问题很多,如果你A函数调用B函数,B函数调用C,然后很可能在C函数里就使用了A函数的变量地址。我没有用寄存器,但是内存也复用。希望大家注意就行了。我调试一个大约63.3×××K大小的程序,这种错误遇到好几次了。我再也不相信keil了!并且各个版本都有同样的bug。

使用特权

评论回复
20
wxj1952| | 2008-5-4 13:06 | 只看该作者

请求所长直接给我们讲讲课。

您2分钟的事。让我们那么多人一个一个地去花时间找您的教材,岂不是最大的时间/生命浪费?

或者有偿发放给我们每人一本教材也好。

使用特权

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

本版积分规则

18

主题

127

帖子

1

粉丝