微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机keil 常见问题

单片机keil 常见问题

时间:08-02 来源:互联网 点击:

一、混合编程

1、模块内接口:

使用如下标志符:

#pragma asm

汇编语句

#pragma endasm

注意:如果在c51程序中使用了汇编语言,注意在keil编译器中需要激活Properties中的“Generate Assembler SRC File” 和“Assembler SRC File ”两个选项

来个实例吧:

#i nclude

void main(void)

{

P2=1;

#pragma asm

MOV R7,#10

DEL:MOV R6,#20

DJNZ R6,$

DJNZ R7,DEL

#pragma endasm

P2=0;

}

另:

1、把"xx.c"加入工程中,右击"xx.c"选择“options for file"xx.c" 选择“Generate Assembler SRC File”和“Assemble SRC File”打上黑勾有效;

2、根据选择的编译模式,把相应的库文件象加"xx.c"一样加入工程中并放在"xx.c"下面,如smail模式下选"keilc51libc51s.lib"加入工程中,如果要进行浮点运算把"keilc51libc51fpl.lib"也加入工程中。

在 Keil 安装目录下的 C51LIB 目录的LIB 文件如下:

C51S.LIB - 没有浮点运算的 Small model

C51C.LIB - 没有浮点运算的 Compact model

C51L.LIB - 没有浮点运算的 Large model

C51FPS.LIB - 带浮点运算的 Small model

C51FPC.LIB - 带浮点运算的 Compact model

C51FPL.LIB - 带浮点运算的 Large model

3、在"xx.c"头文件中加入优化:比如#pragma OT(4,speed)

4、在"xx.c"中加入汇编代码

#pragma ASM

;Assembler Code Here

#pragma ENDASM

5、编译生成xx.hex

注意:

没有做第一步会有如下警告:'asm/endasm' requires src-control to be active

没有做第二步会有如下警告:UNRESOLVED EXTERNAL SYMBOL;

REFERENCE MADE TO UNRESOLVED EXTERNAL等

没有做第三步会有如下警告:UNDEFINED SYMBOL (PASS-2)

二、中断使用

interrupt xx using y

跟在interrupt 后面的xx 值得是中断号,就是说这个函数对应第几个中断端口,一般在51中

0 外部中断0

1 定时器0

2 外部中断1

3 定时器1

4 串行中断

其它的根据相应的单片机有自己的含义,实际上c在编译的时候就是把你这个函数的入口地址放到这个对应中断的跳转地址 。 using y 这个y时说这个中断函数使用的那个寄存器组就是51里面一般有4个 r0 -- r7寄存器,如果你的终端函数和别的程序用的不是同一个寄存器组则进入中断的时候就不会将寄存器组压入堆栈返回时也不会弹出来节省代码和时间。

三、关于reentrant的使用方法

云清燕 发表于 2006-11-15 21:27:00

我在程序中出现了如下警告:

*** WARNING L15: MULTIPLE CALL TO SEGMENT

SEGMENT: ?PR?_CRCDATA?PANEL_DISP

CALLER1: ?C_C51STARTUP

CALLER2: ?PR?UART_RECV?PANEL_DISP

*** WARNING L15: MULTIPLE CALL TO SEGMENT

SEGMENT: ?PR?ANALOGALLBECKON?PANEL_DISP

CALLER1: ?C_C51STARTUP

CALLER2: ?PR?UART_RECV?PANEL_DISP

*** WARNING L15: MULTIPLE CALL TO SEGMENT

SEGMENT: ?PR?SWITCHALLBECKON?PANEL_DISP

CALLER1: ?C_C51STARTUP

CALLER2: ?PR?UART_RECV?PANEL_DISP

我的程序编译出来就这3个警告,但是程序可以正常下载运行。但是我觉得有这些警告会使程序存在bug。从字面上看是它的意思是我程序中接受函数UART_RECV()多调用了analogAllBeckon()、switchAllBeckon()。

因为51的普通函数是不可重入的,变量放在固定的地址,两个函数同时运行时,就会修改同一个变量,从而导致结果错误。于是我在analogAllBeckon()、switchAllBeckon()函数后面加了void analogAllBeckon()reentrant{//All Analog data beckon使程序消除了警告。这种方法是表明函数是可被多哥任务调用而不修改函数里边的变量值,以此来实现函数的重入性。

关于reentrant的使用keil的官方论坛上有详细的讨论.

Andy Neil(官方工程师)建议

"Are you sure that you really need to make everything reentrant?...A reading of the Keil app notes knowledgebase articles on this subject showed that it was not necessary. "

由于每一次调用被reentrant声明的函数都要把函数的参数和内部变量压栈,所以很容易使堆栈区溢出,S52只有256Bytes的data段,一个简单的函数如果有一个参数三个内部变量,则需要压栈4字节以上,这还不包括函数调用堆栈.reentrant其实并不是适合低端的单片机,keil论坛上有人说对于那些有KB以上RAM的单片机reentrant才适合.

四、变量声明有关

在51系列中data,idata,xdata,pdata的区别 data:固定指前面0x00-0x7f的128个RAM,可以用acc直接读写的,速度最快,生成的代码也最校 idata:固定指前面0x00-0xff的256个RAM,其中前128和data的128完全相同,只是因为访问的方式不同。idata是用类似C中的指针方式访问的。汇编中的语句为:mox ACC,@Rx.

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

网站地图

Top