KeilC51使用详解V1.0(三)

[复制链接]
查看2293 | 回复3 | 2011-9-7 22:38:17 | 显示全部楼层 |阅读模式
<





第五章 Keil C51库函数参考
C51强大功能及其高效率的重要体现之一在于其丰富的可直接调用的库函数,多使用库函数使程序代码简单,结构清晰,易于调试和维护,下面介绍C51的库函数系统。
第一节 本征库函数(intrinsic routines)和非本征证库函数
C51提供的本征函数是指编译时直接将固定的代码插入当前行,而不是用ACALL和LCALL语句来实现,这样就大大提供了函数访问的效率,而非本征函数则必须由ACALL及LCALL调用。C51的本征库函数只有9个,数目虽少,但都非常有用,列如下:_crol_,_cror_:将char型变量循环向左(右)移动指定位数后返回_iror_,_irol_:将int型变量循环向左(右)移动指定位数后返回_lrol_,_lror_:将long型变量循环向左(右)移动指定位数后返回_nop_: 相当于插入NOP_testbit_: 相当于JBC bitvar测试该位变量并跳转同时清除。_chkfloat_: 测试并返回源点数状态。使用时,必须包含#inclucle 一行。如不说明,下面谈到的库函数均指非本征库函数。
第二节 几类重要库函数
1. 专用寄存器include文件
例如8031、8051均为REG51.h其中包括了所有8051的SFR及其位定义,一般系统都必须包括本文件。
2. 绝对地址include文件absacc.h
该文件中实际只定义了几个宏,以确定各存储空间的绝对地址。
3. 动态内存分配函数,位于stdlib.h中
4. 缓冲区处理函数位于“string.h”中
其中包括拷贝比较移动等函数如:memccpy memchr memcmp memcpy memmove memset这样很方便地对缓冲区进行处理。
5. 输入输出流函数,位于“stdio.h”中
流函数通8051的串口或用户定义的I/O口读写数据,缺省为8051串口,如要修改,比如改为LCD显示,可修改lib目录中的getkey.c及putchar.c源文件,然后在库中替换它们即可。
第三节 Keil C51库函数原型列表
1. CTYPE.H
bit isalnum(char c); bit isalpha(char c); bit iscntrl(char c); bit isdigit(char c); bit isgraph(char c); bit islower(char c); bit isprint(char c); bit ispunct(char c); bit isspace(char c); bit isupper(char c); bit isxdigit(char c); bit toascii(char c); bit toint(char c); char tolower(char c); char __tolower(char c); char toupper(char c); char __toupper(char c);
2. INTRINS.H
unsigned char _crol_(unsigned char c,unsigned char b); unsigned char _cror_(unsigned char c,unsigned char b); unsigned char _chkfloat_(float ual); unsigned int _irol_(unsigned int i,unsigned char b); unsigned int _iror_(unsigned int i,unsigned char b); unsigned long _irol_(unsigned long l,unsigned char b); unsigned long _iror_(unsigned long L,unsigned char b); void _nop_(void); bit _testbit_(bit b);
3. STDIO.H
char getchar(void); char _getkey(void); char *gets(char * string,int len); int printf(const char * fmtstr[,argument]…); char putchar(char c); int puts (const char * string); int scanf(const char * fmtstr.[,argument]…); int sprintf(char * buffer,const char *fmtstr[;argument]); int sscanf(char *buffer,const char * fmtstr[,argument]); char ungetchar(char c); void vprintf (const char *fmtstr,char * argptr); void vsprintf(char *buffer,const char * fmtstr,char * argptr);
4. STDLIB.H
float atof(void * string); int atoi(void * string); long atol(void * string); void * calloc(unsigned int num,unsigned int len); void free(void xdata *p); void init_mempool(void *data *p,unsigned int size); void *malloc (unsigned int size); int rand(void); void *realloc (void xdata *p,unsigned int size); void srand (int seed);


热帖推荐
aini | 2011-9-7 22:38:39 | 显示全部楼层
9. dScope命令语句
dScope提供了一系列调试命令。在命令文件中,dScope只支持这些语句及前述定义的表达式,C语言的语句均不被支持,但在命令文件所包含的用户自定义函数(非用户源程序中的函数)中支持C语句,但用户自定义函数中同样不支持数组、结构、联合和指针。
(1) ASM
在线汇编命令,格式如下:ASM C:0Xnnnn (或标号);设定插入汇编指令的地址ASM 汇编指令ASM 汇编指令插入完毕后,在debug窗口内选择“Assemble->Assemble”完成编译。
(2) Assign
串行口分配指令,格式如下:Assign channeloutreg对MCS51为:Assign Win Soot但目前的dScope版本并未提供完整串口窗口功能。
(3) Define
用户自定义变量指令,格式如下:Define <类型> <变量名>类型一为如前所述的变量类型,Define指令定义的变量可能为全局变量,可为用户自定义函数所引用。
(4) Display
内存显示命令,格式如下二:D 起始地址,结束地址地址如前所述的地址常数,标识符常量。
(5) Enter
内存修改指令,格式如下:E 类型地址=表达式 [表达式2],[……]类型如前所述,地址如前所述的地址常数。表达式如前所述,但如果是函数名称(含标号、指针变量),则关键字E→EP
(6) Map/Reset map
Map为内存段修改指令,Reset map将内存段复位或缺省值。
(7) Object
用以引用用户源程序中的结构(联合)、数组、格式如下:Obj表达式 [n,],[Line]表达式为用户源程序中的数组,结构(联合)名称。当Line缺省时,数目、结构(联合)的内容按n行输出;如有Line,则单行输出。
(8) U
反汇编命令,格式如下: U [地址]地址包括地址常 数及标识符常量,指明反汇编的起始地址。
(9) WK
观察点删除命令,格式如下: WK n1[n2 ],[……] ;删除指定的观察点,n为字符型,整型 常数 WK * ;删除所有的观察点
(10) WS
观察点设置命令,格式如下:WS 表达式[,n][LINE]关键字LINE存在时,观察点表达式单行输出LINE缺省时,观察点表达式n行输出。
(11) G
连续运行命令,格式如下: G [起始地址],[终止地址]地址为标识符常量或地址常数,地址缺省时,为连续运行。
(12) T/P
单步运行指令,格式如下: T/P n ;n指至单行运行的步数,P指给用户当调用某函数时,把它作为一步处理,并不进入该函数运行。
(13) PA
性能分析操作指令,其分以下几种:PA显示当前所设置的性能分析程度段PA Kill *删除当前所设置的所有性能分析程序段PA Kill n1 [,n2],[……]删除指定的性能分析程序段PA 地址范围设置性能分析程序段,地址范围可以起始地址和结束地址的方式给出,也可给出函数名,行号范围。PA Reset复位性能分析窗口(PA Windows),清除所有的记录。
(14) BD
断点失效命令,格式如下:BD n1 [,n2],[,……] ;disable指定的断点DB * ;disable所有的断点
(15) BE
断点使能命令,格式如下:BE M [,n2],[,……] ;使能指定的断点BE * ;使能所有的断点
(16) BK
断点删除指令,格式如下:BK M[,n2],[,……] ;删除指定的断点BK * ;删除所有的断点
(17) BL
断点显示指令,显示所有被定义的断点。
(18) BS
断点定义指令,dScope支持多达40个断点,具体格式如下:a.BS 表达式[,count] [,“cmd”]count:经过该断点的次数 [选项]“cmd”:断点到达后附带执行的dScope命令(连项)表达式一个条件表达式,此时该断点称为条件断点(运算符为


abb | 2011-9-7 22:38:34 | 显示全部楼层
(2) 地址空间类型
C:代码空间D:内部直接寻址空间I: 内部间接寻址空间X:外部数据空间B:位寻址空间P:I/O口EB:扩展的位寻址空间(MCS251专有)ED:扩展的数据空间(MCS251专有)CO:常数空间(MCS251专有)HC:正常数空间(MCS251专有)
2. 常量
dScope支持十六进制、八进制、十进制、二进制常数,其后缀分别为H、Q(O)、T(或无)、Y;dScope不区分常量的大、小写。
(1) 整型常量
分为整型(int),无符号整型(uint,00rd),长整型(long),无符号长整型(Wlong、Word)。
(2) 浮点型常量
与ANSI C相同。
(3) 字符串常量
与ANSI C相同
(4) 字符常量
分为字符型(Char)和无符号字符型(Uchar)一种。
(5) 行号常数
指用户程序中的行号,实际上是个地址
(6) 位常量(Bit):
0和1
(7) 地址常数
地址常数的种类很多,地址常数不同于行号常数,行号常数就是一个地址,而地址数被引用时,实际上是取该地址中的数据。C:代码地址常数,如C:0X0012或0XFF:0X0012D:内部直接寻址地址常数,如D:0X0068或0X00:0X0068I:内部间按寻址地址常数,如I:0X0010或0X00:0X0010X:外部数据空间地址常数,如X:0X0028或0X01:0X0028B:位地址常数,如B:0X20或B:0X24.0EB:扩展的位地址常数(MCS251专有), ED:扩展的数据空间地址常数(MCS251专有)CO:常数空间地址常数(MCS251专有)HC:正常数空间地址常数(MCS251专有)
(8) 标识符常量
即用户源程序中的标号、函数名等,实际上代表某一地址。
(9) 用户源程序中定义的常数
3. 变量
dScope所支持的变量名或标识符最多可由31个字符组成,第一个字母为A~Z,a~z,下划线或问号,后续字符可为字母、数字、下划线和问号。除CPU变量和系统变量外,dScope不支持全局变量,但可视“define”命令定义的变量为全局变量。Dscope所, 支持的变量分为以下几种(变量名称不区分大、小写),支持类型转换:
(1) 整型变量
分为整型变量(int)、无符号整型变量(uint/word),长整型(Long) 、无符号长整型(Ulong/dword)。
(2) 浮点型变量(float)
与ANSI C相同。
(3) 字符型变量L
分为字符型(char)变量和无符号字符型(Uchar)
(4) 位变量(Bit)
(5) 系统变量
dScope自己定义了一系列内部变量,用户可对这些变量进行读或读/写操作, 可被用户自定义数所引用。a. Cycles (Read Only)32位变量(Ulong),指示当前程序执行已花费的指令周期(cycle)。b. Ramsize(R/W)16位变量(Uint),指示内部可直接寻址的数据空间大小。c. Radix(R/N)8位变量(Uchar),决定输出的数制Radix=0X0A (10进制),Radix=0X10 (16进制)d. -IIP-(R/W)8位变量(Uchar),指示当前的中断嵌套数目。e. $ (R/W)32位变量(Ulong),指出PC值,通过对其进行写操作,可改变程序执行的流程。f. Itrace (R/W)8位变量(Uchar),决定是否对程序运行情况进行记录 Itrace=1,使能记录操作 Itrace=0,根本上记录操作g. __Break__(R/W)8位变量(Uchar) __Break__=1,中止程序的运行h. __Mode__和__Frame size__是MCS 251专有的变量。
(6) CPU变量
即R0~R7、A、C(位变量)、B、DPTR及特殊功能寄存器变量,对这些变量均可进行读、写操作。
(7) 用户源程序中定义的变量、数组、结构等
4. 运算符
dScope支持ANSI C的运算符,包括算术运算符,逻辑运算符,关系运算符。
5. 表达式
以运算符将dScope所支持的常量、变量、函数等连接在一起,就构成了dScope的表达式。
6. 数组
dScope不支持在命令文件中定义数组,但可引用用户程序中的数组,引用方式如同C。
7. 结构和联合
dScope不支持在命令文件中定义结构和联合,但可引用用户程序中的结构和联合,引用方式如同C,但如要输出整个结构或联合的结果,就要用命令“OBJ”。
8. 指针:
不可自定义指针,但支持用户源程序中的指针变量。


subi | 2011-9-7 22:38:23 | 显示全部楼层
5. STRING.H
void *memccpy (void *dest,void *src,char c,int len); void *memchr (void *buf,char c,int len); char memcmp(void *buf1,void *buf2,int len); void *memcopy (void *dest,void *SRC,int len); void *memmove (void *dest,void *src,int len); void *memset (void *buf,char c,int len); char *strcat (char *dest,char *src); char *strchr (const char *string,char c); char strcmp (char *string1,char *string2); char *strcpy (char *dest,char *src); int strcspn(char *src,char * set); int strlen (char *src); char *strncat (char 8dest,char *src,int len); char strncmp(char *string1,char *string2,int len); char strncpy (char *dest,char *src,int len); char *strpbrk (char *string,char *set); int strpos (const char *string,char c); char *strrchr (const char *string,char c); char *strrpbrk (char *string,char *set); int strrpos (const char *string,char c); int strspn(char *string,char *set);
第六章 Keil C51例子:Hello.c
Hello位于/C51/excmples/Hello/目录,其功能是向串口输出“Hello,world”整个程序如下:#pragma DB OE CD#indule #includevoid main(void) { SCOn=0x50; TMOD=0x20 TH1=0xf3; Tri=1; TI=1; printf(“Hello,world /n”); while(1) { } }
第一节 uVision for Windows的使用步骤
(1) file_new新建一个hello.c文件,输入如上内容或直接用目录下源文件。(2) file_save或工具栏将文件存盘。(3) project_new project创建一个project名为hello,并在其中加入hello.c。这时该project已是打开状态,或用open project打开已存在的project。(4) option_C51 compiler中选出至少包括两项DB OE。(5) option_dscope Debugger选中hello/DS51.INI查看DS51.INI看其是否为: “load…/…/BIN/8051.DLL map 0, 0xffff”否则修改。(6) 在option_make选make文件顺序。(7) project选Build project,看是否有语法错误,若无则生成HEX文件,若有则修改源文件后重复以上部分步骤。(8) run_dScope debugger进入dScope51后装入hello则可用go直接运行看serial窗口有无输出,正常每系统运行一次,serial窗口均出现一个“Hello,world”表明运行无误。
第二节 Ishell for Dos使用步骤
(1) 进入Ishell 用Setup editer选择编辑器。然后单击Edit或用Edit命令编辑hello.c源文件,存盘,也可以在files窗口中直接选中hello.c。(2) 用cd改换project目录至hello目录。(3) 在setup_target一项目选8051。(4) 在setup_C51中输出DB OE。(5) 在setup_project输入project名hello。(6) 在setup_save保存Ishell.CFG文件。(7) 编辑一个Link文件hello.lin中有“hell.obj”一行。(8) 由光标落在files菜单中的Hello.c上,单击“translate”,如无语法错,再击“link”,则Hex文件生成。(9) 单击Simulate如在8051.CDF中选Simulate为dScope则进入dScope调试直接“Go”,看serial窗口输出为“Hello.world”。(10) 如程序有误修改源代码后不必再translate或link了,只要一步Amake即可。若project中包括不止一个文件,在DOS的Ishell中不能用Translate编译,而应建立bat文件,直接在命令窗编译,然后link连接。如还需用Translate则只能多个文件分别编译,然后连接。
第七章 Keil C51的代码效率
C51程序编译生成汇编代码的效率,是由许多因素共同决定的,对于Keil C51,主要受以下两种因素影响:
第一节 存储模式的影响
存储模式决定了缺省变量的存储空间,而访问各空间变量的汇编代码的繁简程度决定了代码率的高低。例如:一个整形变量i,如放于内存18H、19H空间,则 i的操作编译成四条语句:INC 0x19MOV A,0x19JNZ 0x272DINC 0x180x272D:而如果放于外存空间0000H、0001H则 i的操作编译成九条语句:MOV DPTR,0001MOVX A,@ DPTRINC AMOVX @ DPTR,AJNz #5MOV OPTR,#0000MOVX A,@DPTRINC AMOVX @ DPTR,A就汇编之后的语句而言,对外部存储器的操作较内部存储器操作代码率要低得多,生成的语句为内存的两倍以上,而程序中有大量的这种操作,可见存储模式对代码率的响了。因此程序设计的原则是1、存储模式从small-Compact-large依次选择,实在是变量太多,才选large模式。2、即使选择了large模式,对一些常用的局部的或者可放于内存中的变量,最好放于内存中,以尽量提高程序的代码率。


您需要登录后才可以回帖 登录 | 立即注册

本版积分规则