微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > Keil C51的一些有趣特性

Keil C51的一些有趣特性

时间:05-14 来源:互联网 点击:

实在无法避免,则把有效数据存入固定的RAM中。

对于中断函数问题,当你看到下面的程序相差55 Byte时,不知你会怎么想的。

例2:

void OSTimeDly(void); //using 1

static void Timer0OVInt(void) interrupt 1 //using 1

{

TR0 = 0;

TH0 = 100;

TL0 = 100;

TR0 = 1;

OSTimeDly();

}

void OSTimeDly(void) //using 1

{

}

void OSTimeDly(void) //using 1

{

}

static void Timer0OVInt(void) interrupt 1 //using 1

{

TR0 = 0;

TH0 = 100;

TL0 = 100;

TR0 = 1;

OSTimeDly();

}

它们的汇编代码分别是,

; static void Timer0OVInt(void) interrupt 1 //using 1

RSEG ?PR?Timer0OVInt?TEST

USING 0

Timer0OVInt:

PUSH ACC

PUSH B

PUSH DPH

PUSH DPL

PUSH PSW

MOV PSW,#00H

PUSH AR0

PUSH AR1

PUSH AR2

PUSH AR3

PUSH AR4

PUSH AR5

PUSH AR6

PUSH AR7

USING 0

; SOURCE LINE # 24

; {

; TR0 = 0;

; SOURCE LINE # 26

CLR TR0

; TH0 = 100;

; SOURCE LINE # 27

MOV TH0,#064H

; TL0 = 100;

; SOURCE LINE # 28

MOV TL0,#064H

; TR0 = 1;

; SOURCE LINE # 29

SETB TR0

;

; OSTimeDly();

; SOURCE LINE # 31

LCALL OSTimeDly

; }

; SOURCE LINE # 32

POP AR7

POP AR6

POP AR5

POP AR4

POP AR3

POP AR2

POP AR1

POP AR0

POP PSW

POP DPL

POP DPH

POP B

POP ACC

RETI

; END OF Timer0OVInt

;

;

; void OSTimeDly(void) //using 1

RSEG ?PR?OSTimeDly?TEST

OSTimeDly:

; SOURCE LINE # 35

; {

; SOURCE LINE # 36

;

; }

; SOURCE LINE # 38

RET

; END OF OSTimeDly

; void OSTimeDly(void) //using 1

RSEG ?PR?OSTimeDly?TEST

OSTimeDly:

; SOURCE LINE # 22

; {

; SOURCE LINE # 23

;

; }

; SOURCE LINE # 25

RET

; END OF OSTimeDly

CSEG AT 0000BH

LJMP Timer0OVInt

;

; static void Timer0OVInt(void) interrupt 1 //using 1

RSEG ?PR?Timer0OVInt?TEST

USING 0

Timer0OVInt:

; SOURCE LINE # 27

; {

; TR0 = 0;

; SOURCE LINE # 29

CLR TR0

; TH0 = 100;

; SOURCE LINE # 30

MOV TH0,#064H

; TL0 = 100;

; SOURCE LINE # 31

MOV TL0,#064H

; TR0 = 1;

; SOURCE LINE # 32

SETB TR0

;

; OSTimeDly();

; SOURCE LINE # 34

LCALL OSTimeDly

; }

; SOURCE LINE # 35

RETI

; END OF Timer0OVInt

这个例子的汇编代码很好的解释了上面的特性1及3。

至于第四个特性,值得特别说明一下。看下例:

例3:

void OSTimeDly(void);

static void Timer0OVInt(void) interrupt 1 using 0

{

TR0 = 0;

TH0 = 100;

TL0 = 100;

TR0 = 1;

OSTimeDly();

}

void OSTimeDly(void) // using 0

{

}

它的汇编代码是

; static void Timer0OVInt(void) interrupt 1 using 0

RSEG ?PR?Timer0OVInt?TEST

USING 0

Timer0OVInt:

PUSH ACC

PUSH B

PUSH DPH

PUSH DPL

PUSH PSW

USING 0

MOV PSW,#00H

; SOURCE LINE # 24

; {

; TR0 = 0;

; SOURCE LINE # 26

CLR TR0

; TH0 = 100;

; SOURCE LINE # 27

MOV TH0,#064H

; TL0 = 100;

; SOURCE LINE # 28

MOV TL0,#064H

; TR0 = 1;

; SOURCE LINE # 29

SETB TR0

;

; OSTimeDly();

; SOURCE LINE # 31

LCALL OSTimeDly

; }

; SOURCE LINE # 32

POP PSW

POP DPL

POP DPH

POP B

POP ACC

RETI

; END OF Timer0OVInt

;

; void OSTimeDly(void) // using 0

RSEG ?PR?OSTimeDly?TEST

OSTimeDly:

; SOURCE LINE # 34

; {

; SOURCE LINE # 35

;

; }

; SOURCE LINE # 37

RET

; END OF OSTimeDly

此例中除了中断函数使用了using 0之外,与上例中的程序并无区别,但是汇编的代码相差却很大。此例中的汇编代码不再保存R0 ---- R7的值。(默认keil c51中的函数使用的是0寄存器组,当中断函数使用using n时,n = 1,2,3或许是对的,但n=0时,程序就已经存在了bug(只有中断函数及其所调用的函数并没有改变R0 ---- R7的值时,这个bug不会表现出来))

一个结论是,在中断函数中如果使用了using n,则中断不再保存R0----R7的值。

由此可以推论出,一个高优先级的中断函数及一个低优先级的中断函数同时使用了using n,(n = 0,1,2,3)当n相同时,这个存在的bug 是多么的隐蔽。(这恰是使人想象不到的)

最后再来看一例

例4:

void OSTimeDly(unsigned char i);

static void Timer0OVInt(void) interrupt 1 using 1

{

TR0 = 0;

TH0 = 100;

TL0 = 100;

TR0 = 1;

OSTimeDly(5);

}

void OSTimeDly(unsigned char i) // using 0

{

while(i--);

}

汇编的结果

; static void Timer0OVInt(void) interrupt 1 using 1

RSEG ?PR?Timer0OVInt?TEST

USING 1

Timer0OVInt:

PU

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top