第6章 Cx51函数

合集下载

Cx51数据与运算

Cx51数据与运算
变量的格式:
[存储种类] 数据类型 [存储器类型]
变量名表
存储种类:自动(auto)、外部(extern)、静 态(static)和寄存器(register)
数据类型
位变量(bit): 变量的类型是位,其值可以是1(true) 或 0(false)。 字符变量(char):长度为8位,占用1字节。 整型变量(int):长度为16位,占用2字节。 长整型变量(long int):长度为32位,占用4字节。 浮点型变量(float):长度为32位,占用4字节。
是C51编译器的一种扩充数据类型,利用它可 以访问芯片内部的RAM中的可寻址位或特殊功 能寄存器中的可寻址位。
sfr P1=0x90; /*P1口地址为90H*/ sbit P1_1=P1^1; /*P1_1为P1中的P1.1引脚*/ 或 sbit P1_1=0x91;
3.2 常量与变量
常量:在程序运行过程中,其值不能改变的量。
code:存放指令代码和其他非易失信息。用“MOVC @A+DPTR” 指令访问。
访问片内数据存储器(data,bdata,idata)比访问片外 数据存储器(xdata,pdata)相对要快一些。
经常使用的变量置于片内数据存储器, 规模较大的、不常使用的数据置于片外数据存储器。
Cx51存储类型及其大小和值域
在固定的存储器地址上进行变量的传递,是Cx51的 标准特征之一。 在SMALL模式下,参数传递是在片内数据存储区中 完成的。 LARGE和COMPACT模式允许参数在外部存储器中 传递。 Cx51同时支持混合模式。如在LARGE模式下,生成 的程序可将一些函数放入SMALL模式中,从而加快 执行速度。
signed int 类型表示的数值范围-32768~+ 32767。字节中最高位表示数据的符号,“0” 表示正数,“1”表示负数。

第三章CX51数据与运算(修改)(1)讲述

第三章CX51数据与运算(修改)(1)讲述
指数(阶码) 尾数(补码)
用四个字节32位存放,符号位表示正负、阶码和尾数表示大小。
注:第一位均为符号位
第三章 C51数据与运算
6
二进制数的定点和浮点表示
定点表示法 ——小数点位置是“固定的” 符号位: 0—正数 1—负数 定点数可用于表示整数。整数在机器中用补码表示。 对于 int a=8,b=-8; 数值位 符号位 真值 原码 补码 a=810=10002 b=- 810=-10002
一个变量由变量名和变量值组成,变量名是存储单元地址的符号表示, 变量的值是该单元存放的内容。 定义一个变量,编译系统会自动为其安排一个存储单元,具体的地址值 用户不必关心。 无论哪种数据都是存放在存储单元中的,每一个数据究竟占用几个单元 (即数据的长度)都要提供给编译系统,正如汇编语言中存放数据的单 元要提供DB或DW伪指令进行定义,编译系统以此为根据预留存储单元。
Why?!
void main(void) { int data a ;
a=12345; a=? Because: a=1234567; a=? 12345 (3039H)的补码是 0011 0000 0011 1001 } 1234567(12D687H)的补码是 1 0010 1101 0110 1000 0111 截去多余部份(超过2个字节的左边部分)后 其原码为 1010 1001 0111 1001(-10617)
0 0000000 00001000 0 0000000 00001000
1 0000000 00001000 1 1111111 11111000 11110111
正数的原码=正数的补码 负数的原码和补码按以下规则相互转换: 符号位不变,数值位各位取反,末位加1。
第三章 C51数据与运算

单片机C语言(模块一)

单片机C语言(模块一)

《单片机原理及应用(二)》模块一C51程序设计基础任务1:实例导航第二章C与80512.1 8051的编程语言1、8051的编程语言(四种):(1)BASIC语言(2)PL/M√(3)汇编语言√(4)C语言目前,汇编语言和C语言是广泛使用的两种单片机编程语言。

在未来的一段时间内,汇编语言和C语言还将同时存在,但从发展趋势看,C语言有逐渐取代汇编语言的可能。

最好的单片机编程者应是具有汇编语言基础,又精通C语言的。

2、C语言的优点(与汇编语言相比):(P41)(1)对单片机的指令系统不要求了解,仅要求对8051的存储器结构有所了解(2)寄存器的分配、不同存储器的寻址及数据类型等细节由编译器管理(3)程序有规范的结构,由不同的函数组成,这种方式可使程序结构化(4)编程及程序调试时间显著缩短,从而提高效率(5)提供库函数,具有较强的数据处理能力3、8051单片机C语言(单片机C51语言)了解一下单片机的种类:(查资料)2.2 Cx51编译器编译:C语言源程序转换成机器语言目标程序的过程,叫做编译。

编译器:能自动完成编译过程的一种计算机软件。

(1)C语言编译器(标准C)(2)C51编译器(经典8051单片机)(3)C x51编译器(经典8051单片机及派生产品)Cx51编译器完全遵照ANSI C语言标准,支持C语言的所有标准特征。

另外,还增加了可以直接支持8051结构的特征。

典型产品:KILE套装工具软件----------uVision2 集成开发环境的使用(P 302)例2-1:用uVision2软件编译调试一个C51程序(HELLO.C)基本步骤:(1)创建一个新项目(建在一个新文件夹下)并为项目选择一个CPU(此时会自动加入启动文件)(2)创建新程序文件(或打开旧程序文件)此例中,打开c:\kile\c51\examples\hello(3)将源文件添加到项目中此时还可修改工具选项(4)编译和链接项目(Build Target命令):翻译和链接源文件,并生成一个可以载入到uvision2调试器进行调试的绝对目标模块。

指针C51.

指针C51.

C51编译器-语言扩展(3)-指针Pointers指针Cx51支持使用字符*来声时一个指针类型的变量。

Cx51的指针可以完成标准C的所有功能。

然而,由于8051及其变种的特殊构架,Cx51使用两种类的指针: memory-specific pointers and generic pointers(特定存储器类型指针和通用指针),Generic Pointers通用指针的定义方法与标准C指针的定义方法相同。

通用指针总是使用三个字节来存储。

第一个字节是存储器类型。

第二字节是偏移量的高位,第三字节是偏移量的低位。

通用指针可以访问所用的变量,而不论变量位于8051的哪一个存储区内。

因为这个原因,许多8051的运行时库都使用这个种指针。

通过使用通用指针,函数可以访问所有的内存区域注意:使用通用指针产生的代码比用特定存储器类型指针生成的代码执效率要低得多。

这是因为在运行前变量的内存区域是不知道的。

编译器不能优化存储器的访问,而是要生成适合所有存域的代码。

如果要获得高的运行速度,最好使用特定存储器类型指针。

为运行速度考虑,也可以设定指针的存储区,在声明指针时前面加上储存区类型标识就可以把指针放在特定的存储器区域。

char * xdata strptr; /* generic ptr stored in xdata */int * data numptr; /* generic ptr stored in data */long * idata varptr; /* generic ptr stored in idata */在上面的例子中,指针指向的内容可以放在任何一个空间内,但指针必须放在xdata, data, and idata中。

Memory-specific Pointers特定存储器类型指针在声明时总是包含了内存类型的声明,并且只能指向特定的内存区域。

如:char data *str; /* ptr to string in data */int xdata *numtab; /* ptr to int(s) in xdata */long code *powtab; /* ptr to long(s) in code */因为在编译的时候内存的类型就已经确定了,通用指针的存储器类型就不再需要了。

Cx51入门与Keil使用 单片机

Cx51入门与Keil使用 单片机

/* P3 */ sbit RD = 0xB7; sbit WR = 0xB6; sbit T1 = 0xB5; sbit T0 = 0xB4; sbit INT1 = 0xB3; sbit INT0 = 0xB2; sbit TXD = 0xB1; sbit RXD = 0xB0; /* SCON */ sbit SM0 = 0x9F; sbit SM1 = 0x9E; sbit SM2 = 0x9D; sbit REN = 0x9C; sbit TB8 = 0x9B; sbit RB8 = 0x9A; sbit TI = 0x99; sbit RI = 0x98; #endif
#include “display.h” #include “delay.h“
#ifndef __DISPLAY_H__ #define __DISPLAY_H__
//用户自定义头文件 用户自定义头文件 //用户自定义头文件 用户自定义头文件
extern void disp7seg ( unsigned char value); extern unsigned char code seg_tab[]; #endif #ifndef __DELAY_H__ #define __DELAY_H__ void delayms(unsigned char count); void delayx10ms(unsigned char count); #endif
/* IE */ sbit EA = 0xAF; sbit ES = 0xAC; sbit ET1 = 0xAB; sbit EX1 = 0xAA; sbit ET0 = 0xA9; sbit EX0 = 0xA8; /* IP */ sbit PS = 0xBC; sbit PT1 = 0xBB; sbit PX1 = 0xBA; sbit PT0 = 0xB9; sbit PX0 = 0xB8;

第六章 Cx51函数

第六章 Cx51函数

6.7 内部函数和外部函数
• 若一个函数只能被本文件中其他函数所调用,称为内部函 数。定义时,在函数名和函数类型前加static,即: static 类型 函数名() • 定义函数时,若在函数首部的最左端冠以关键字extern, 表示此函数是外部函数,可供其他文件调用。extern可省 略。如:extern int max(int x, int y) • 在需调用此函数的文件中,用extern声明所用函数是外部 函数
6.6 变量的存储类别
• 指数据在内存中存储的方式 • 即编译器为变量分配内存的方式,它决定变量的生存期 • 动态存储 – 根据需要临时分配存储空间,离开即释放 • 静态存储 – 在程序运行期间分配固定的存储空间不释放
程序区 静态存储区 动态存储区
全局变量、 静态变量 形参、自动变 量、函数调用 的现场等
• 自动变量:进入语句块时自动申请内存,退出时自动释放 内存 • 标准定义格式 auto 类型名 变量名; 动态局部变量 缺省的存储类型 不初始化时,值是不确定的 • 静态变量:在变量类型前面用static修饰 static int i; 变量的值可以保存到下次进入函数,使函数具有记忆功能 • 静态变量和全局变量都是静态存储类型 自动初始化为0 从静态存储区分配,生存期为整个程序运行期间 但作用域不同
6.3 函数的调用
(1)函数调用的一般格式: 函数名(实参数表); • 有返回值时 – 放到一个数值表达式中,如c=Average (a,b); – 作为另一个函数调用的参数,如 c=Average(Average(a,b),c); printf("%d\n", Average(a,b)); • 无返回值时 – 函数调用表达式,如display(a,b); (2)调用实质: – 程序执行流程转向由函数名指定的被调用函数。 – 实参数一一对应地传递给函数定义中的形参数。 – 执行函数定义中的函数体。 – 执行结束,通过return语句将值返回到调用处。 – 程序执行流程返回调用处。执行后面的语句。

51单片机调用函数的方法

51单片机调用函数的方法

51单片机调用函数的方法摘要:1.引言2.51单片机简介3.调用函数的原理4.调用函数的方法5.实例演示6.总结正文:1.引言在51单片机编程中,调用函数是非常重要的环节。

本文将详细介绍51单片机调用函数的方法,帮助读者更好地理解和应用这一技术。

2.51单片机简介51单片机是一种基于冯·诺依曼结构的微控制器,内置了CPU、RAM、ROM、I/O口等硬件资源。

它具有体积小、成本低、功耗低等特点,广泛应用于嵌入式系统领域。

3.调用函数的原理在51单片机中,调用函数实际上是通过传递参数,执行子程序的方式实现的。

调用函数的语句一般形式为:`void 函数名(参数1, 参数2,...);`4.调用函数的方法调用函数的方法主要包括以下几点:(1)声明函数在程序开头,需要对要调用的函数进行声明。

声明语句一般形式为:`void 函数名(参数类型参数名1, 参数类型参数名2,...);`(2)定义函数在程序中,需要对声明的函数进行定义。

定义语句一般形式为:`void 函数名(参数类型参数名1, 参数类型参数名2,...) {// 函数体}`(3)调用函数在主程序中,通过调用声明过的函数,传入相应的参数,实现函数的调用。

调用语句一般形式为:`函数名(参数1, 参数2,...);`5.实例演示以下是一个简单的实例,演示如何调用函数:```c#include <reg52.h>// 声明函数void delay(unsigned int ms);void main() {unsigned int i;// 调用函数,延时1000msdelay(1000);for (i = 0; i < 10; i++) {P1 = i; // 输出P1口的值delay(100); // 延时100ms}while (1); // 循环等待}// 定义函数:延时函数void delay(unsigned int ms) {unsigned int i, j;for (i = ms; i > 0; i--) {for (j = 114; j > 0; j--) {_nop_();}}}```6.总结本文从51单片机简介、调用函数的原理、调用方法等方面进行了详细的介绍,并通过一个实例演示了如何调用函数。

Cx51数据与运算

Cx51数据与运算

5、使用Keil C时应做的和应该避免的 、使用 时应做的和应该避免的
Keil C编译器能从你的程序源代码中产生高 编译器能从你的程序源代码中产生高 度优化的代码, 度优化的代码,但你可以帮助编译器产生更好的 代码。下面将讨论这方面的一些问题。 代码。下面将讨论这方面的一些问题。
(1)采用短变量 ) 一个提高代码效率的最基本的方式就是减小 变量的长度。使用C编程时 编程时, 变量的长度。使用 编程时,我们都习惯于对循 环控制变量使用int类型,这对 位的单片机来 类型, 环控制变量使用 类型 这对8位的单片机来 说是一种极大的浪费。 说是一种极大的浪费。你应该仔细考虑你所声明 的变量值可能的范围,然后选择合适的变量类型。 的变量值可能的范围,然后选择合适的变量类型。 很明显, 很明显,经常使用的变量应该是 unsigned char,只占用一个字节 ,只占用一个字节: unsigned char data n;
(4)使用位变量 ) 对于某些标志位应使用位变量而不是unsigned 对于某些标志位应使用位变量而不是 char,这将节省你的内存。你不用多浪费 位存储 ,这将节省你的内存。你不用多浪费7位存储 而且位变量在RAM中访问他们只需要一个处理 区,而且位变量在 中访问他们只需要一个处理 周期。 周期。
1、通用寄存器区(00~1FH) 、通用寄存器区 通用寄存器区由4个寄存器组 通用寄存器区由 个寄存器组 构成: 组 构成:0组(00~07H)、 、 1组(08~0FH)、 组 、 2组(10~17H)、 组 、 3组(18~1FH)。 组 。 可以通过PSW中RS0和RS1的不同取值来 中 可以通过 和 的不同取值来 选择不同的寄存器组。 选择不同的寄存器组。在函数定义中则可以使用 关键词using来指明寄存器号。 来指明寄存器号。 关键词 来指明寄存器号 上电复位后默认使用寄存器组0。 上电复位后默认使用寄存器组 。当其它组不 用时,它们都可以当作普通的RAM使用。 使用。 用时,它们都可以当作普通的 使用

C51单片机堆栈深入剖析

C51单片机堆栈深入剖析

51单片机堆栈深入剖析用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。

Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。

应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己的特点。

本文介绍的是Cx51程序设计时堆栈的计算方法。

1.堆栈的溢出问题。

MCS51系列单片机将堆栈设置在片内RAM中,由于片内RAM资源有限,堆栈区的范围也是有限的。

堆栈区留得太大,会减少其他数据的存放空间,留得太少则很容易溢出。

所谓堆栈溢出,是指在堆栈区已经满了的时候还要进行新的压栈操作,这时只好将压栈的内容存放到非堆栈区的特殊功能寄存器(SFR)中或者堆栈外的数据区中。

特殊功能寄存器的内容影响系统的状态,数据区的内容又很容易被程序修改,这样一来,之后进行出栈操作(如子程序返回)时内容已变样,程序也就乱套了。

因此,堆栈区必须留够,宁可大一些。

要在Cx51程序设计中防止堆栈的溢出,要解决两个问题:第一,精确计算系统分配给用户的堆栈大小,假设是M;第二,精确计算用户需要堆栈的大小,假设是N。

要求M≥N,下面分别分析这两个问题。

2.计算系统分配给用户的堆栈大小Cx51程序设计中,因为动态局部变量是长驻内存中的,实际上相当于局部静态变量,即使在函数调用结束时也不释放空间(这一点不同于标准C语言)。

Cx51编译器按照用户的设置,将所有的变量存放在片内和片外的RAM中。

片内变量分配好空间后,将剩下的空间全部作为堆栈空间,这个空间是最大可能的堆栈空间。

当然,因为Cx51是一种可以访问寄存器的C语言(特殊功能寄存器),因此可在程序中访问SP,将堆栈空间设置得小一点。

不过,一般没有人这么做。

本文只是讨论放在片内RAM的变量。

我们把变量分为两种情况:①用作函数的参数和函数返回值的局部变量。

这种变量尽量在寄存器组中存放。

为了讨论方便,假设统一用寄存器组0,具体的地址为0x00~0x07。

Keil的使用与Cx51程序设计基础

Keil的使用与Cx51程序设计基础

• 所有的bit 变量放在8051 内部存储区的位段,因为这区 域只有16 字节长,所以在某个范围内只能声明最多128 个位变量。 • 存储类型应包含在一个bit 变量的声明中,因为bit 变 量存储在8051 的内部数据区,所以只能用data 和idata 存储类型,别的存储类型不能用。 • bit 变量和bit 声明的限制如下: • 禁止中断的函数#pragma disable 和用一个明确的寄存 器组using n 声明的函数不能返回一个位值。Cx51编译 器对这类函数想要返回一个bit类型产生一个错误信息。 • 不能定义位指针,例如:bit *ptr; /* invalid */ • 不能定义一个bit类型的数组,例如:bit ware[5]; /* invalid */
存储类型 • Cx51编译器明确支持8051和派生系列结 构,可访问8051的所有存储区,每个变 量可以明确的和特定的存储空间相关连。 • 访问内部数据区比访问外部数据区快的 多,基于这个原因把频繁使用的变量放 在内部数据区,把较大的较少使用的变 量放在外部存储区。
明确声明存储类型
在变量声明中包含一个存储类型标识符,可以指定 变量的存放区域。 下面的表综合了可用的存储类型标识符:
Cx51与C的关系 与 的关系 • Keil Cx51是一种专为8051单片机设计 的C编译器,支持ANSI C,同时针对 8051单片机自身特点作了一些特殊扩展: 存储类型; 存储模式; 数据类型; 存储区。
• • • •
ANSI C 的关键字 • ANSI C一共规定了32个关键字: • auto, break , case, char, const, continue, default, do, double, else, enum, extern, float, for, goto, if, int, long, register, return, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, volatile, while.

c51库函数的使用

c51库函数的使用
再入属性: non-reentrant 功能: cos 计算并返回 x 的余弦值,sin 计算并返回 x 的正弦值,tan 计算并返回 x 的正切值,所有函数的
变量
范围都是-pi/2~+pi/2 ,变量的值必须在正负 65535 之间,否则产生一个 NaN 错误。
函数原型: float acos(float x); float asin(float x); float atan(float x);
函数原型: #define FARRAY(object,base)((object volatile far *) ((base)+0x10000L)) #define FCARRAY(object,base)((object const far *) ((base)+0x810000L))
功能: 宏 FARRAY 和 FCARRAY 用于访问位于 far 和 const far 存储区的数组类型目标,FARRAY 用于 访问 far
空间(存储类为 HDATA),FCARRAY 用于访问 const far 空间(存储类为 HCONST)。
内部函数 INTRINS.H 内部函数的原型声明包含在头文件 INTRINS.H 函数原型: unsigned char _crol_(unsigned char val,unsigned char n); unsigned int _irol_(unsigned int val,unsigned char n); unsigned long _irol_(unsigned long val,unsigned char n);
功能: pow 计算并返回 x^y 的值,如果 x 不等 于 0 而 y=0,则返回 1.当 x=0 且 y<=0 或当 x<0 且 y 不是 整数时则返

C51函数-免费下载

C51函数-免费下载
例3-3:试编写一段延时程序。
应用程序: main() { char a;
for (a=1;a<100; a++); }
第3章 C51 函数
3.2.2其它函数
除了主函数main外,C语言的其他函数可归类 为下列四大类:
(1)无参数输入,无参数返回 (2)无参数输入,有参数返回 (3)有参数输入,无参数返回 (4)有参数输入,有参数返回
第3章 C51 函数
1、无参数输入,无参数返回
这种函数在调用时,无须输入任何参 数给函数,而函数结束时也无须返回任何 参数。
例3-4:试编写一段程序调用延时程序。
main() {delay( ); }
第3章 C51 函数
应用程序
void delay(void) {char a; for (a=1;a<100; a++); }
第3章 C51 函数
有参数函数:
在调用此种函数时,必须提供实际的 输人参数。此种函数在被调用时,必须说 明与实际参数一一对应的形式参数,并在 函数结束时返回结果,供调用它的函数使 用。
第3章 C51 函数
空函数:
此种函数体内无语句,是空白的。调 用此种空函数时,什么工作也不做,不起 任何作用。而定义这种函数的目的并不是 为了执行某种操作,而是为了以后程序功 能的扩充。
第3章 C51 函数
function_n (形式参数表) / * 函数 n * / 形式参数说明 { 局部变量说明 执行语句 }
第3章 C51 函数
3.2.1主函数
主函数是C语言程序的开头,也就是 说C语言都是从主函数开始执行的, main的数据格式是viod;无论何时都没有 返回值。

ch06Cx51函数

ch06Cx51函数

}
程序中int(*p)()是函数指针定义语句,说明p是一个指向函数 的指针变量,此函数的返回值类型为int。 注意(*p)()不能写成*p(),第一个括号不能省略,表示p先 与*结合,是指针变量,然后再与()结合,表示此指针指向函数。 如写为*p(),则表示p为一个函数,该函数的返回值类型是指针。 语句p=factorial;的作用时将函数factorial()的入口地址赋给指 针变量p。此后调用(*p)(j)就是调用factorial(j)函数。 在main()中赋值语句c=(*p)(j),包含函数调用,等同于
6.4.4 函数的嵌套调用
嵌套调用——指一个函数调用A函数,A函数的函数体中 又调用B函数。
6.4.5 函数的递归调用
1、递归调用的定义
函数的递归调用是指一个函数直接或间接地调用自己。 例:在函数f1( )中又有调用f1 的语句,这称为直接递归调用。
2、递归调用的条件
在解决实际问题时,能否用递归的方法来解决,取决 于问题自身的特点。某一问题要用递归的方法来解决,需 满足以下条件: 原问题可转化为一个新问题,而这个新问题与原问题有 相同的解决方法。 新问题可继续这种转化。在转化过程中问题有规律的递 增或递减。 在有限次转化后,问题得到解决。
return <表达式> ;
return语句的执行过程如下: 先计算出<表达式>的值.
若<表达式>的值的类型与函数的类型不同,将<表
达式>的类型强制转换为函数的类型.
将表达式的值返回给调用函数. 将程序的控制权由被调用函数转给调用函数用只 能有一个返回值。
6.4 函数的调用
6.4.1 函数调用的一般形式
函数调用的形式为:

第6章06-Cx51函数

第6章06-Cx51函数

6.4.2 函数调用的方式
1. 函数用作语句
把被调用函数名称以及传给它的实际参数当作一 条语句,不关心它的返回结果: void main() { : Func(); : }
2. 函数结果作为表达式的一个运算对象
被调用函数代表其返回结果出现在一个运算表 达式中: void main() { : a=12*Func(2)*b; : }
3. 空函数的定义方法
空函数的定义形式为: 返回值类型关键词 函数名(形式参数列表)参数说明 {return 默认值;} 空函数也可以没有返回值,此时其返回类型 关键词为void,函数体则为空:
int fun(int a) { void fun(int a){} return a; } 没有返回值时其返回类型关键词为void,没有 返回类型说明的默认为int,具有int返回值的函数 没有返回语句return时编译器不会提供警告信息。
6.1 函数的分类
从C语言程序的结构上分,C语言函数分为主函 数main()和普通函数两种。对于普通函数,从用户 的角度划分,函数后标准库函数和用户自定义函数 两种: A. 标准库函数: 运行库中提供了很多短小精悍的函数,你可以 很方便地使用它们,你自己很难写出比它们更好的 代码了。
标准库函数如下表所示:
cosh exp memcc sqrt malloc sin ceil acos strrpbrk
B. 用户自定义函数:
用户自定义函数就是用户根据自己任务的需要 而设计的函数。 从函数定义的形式上分,则C语言函数可以分为 无参数函数、有参数函数和空函数三种: A. 无参数函数: 此种函数在调用时,无需参数输入,有时甚至 也不返回任何结果,使用它的目的只是完成某个无 需初始化的任务; B. 有参数函数: 此种函数在调用时必须提供参数输入,完成需 要根据某些条件完成的任务;

KEIL CX51编译器 说明书

KEIL CX51编译器 说明书

Cx51编译器对传统和扩展的8051微处理器的优化的C 编译器和库参考用户手册09.2001Keil Software – Cx51编译器用户手册—ፉᑗኔፉᑗኔ由于本人的英语水平有限所以在使用KEIL C51的过程中老要去看那英文的手册总感到不是那么方便老要用词霸查来查去的烦的很因此在看到C51BBS上的倡议后就动了把它翻译出来的念头我想这对自己和别人都会带来些好处利用工作之余的时间经过几个月的努力终于把它翻译完了但由于水平所限文中肯定有很多不是十分恰当的地方或许没有用大家比较熟悉的惯用语或许可能引起误解所以在这里我请大家能指出其中的错误和不当之处请大家EMAIL告诉我使我能够作出改正对于大家的建议我会很高兴的接受我最大的愿望是希望我的翻译不会误导大家且能对大家有所帮助不明之处可以参考英文原文感谢C51BBS版主龙啸九天的帮助欢迎大家与我交流我的e-mail jx_lxh@Keil Software声明本文档所述信息不属于我公司的承诺范围其内容的变化也不会另行通知本文档所述软件的出售必须经过授权或签订特别协议本文档所述软件的使用必须遵循协议约定在协议约定以外的任何媒体上复制本软件将触犯法律购买者可以备份为目的而做一份拷贝在未经书面许可之前本手册的任何一部分都不允许为了购买者个人使用以外的目的而以任何形式和任何手段(电子的机械的)进行复制或传播版权1988-2001所有者Keil Elektronik GmbH和Keil Software公司Keil C51™Keil CX51™,和uVision TM是Keil Elektronik GmbH的商标Microsoft®和Windows™是Microsoft Corporation的商标或注册商标IBM®PC®和PS/2®是International Business Machines Corporation的注册商标Intel®MCS®51MCS®251ASM-51®和PL/M-51®是Intel的注册商标我们尽全力去做来保证这本手册的正确从而保证我们个人公司和在此提及的商标的形象前言本手册讲述对8051的目标环境如何使用C x51优化C编译器编译C程序C x51编译器包可以用在所有的8051系列处理器上可以在WINDOWS 32位命令行中执行本手册假定你熟悉WINDOWS操作系统知道如何编程8051处理器并会用C语言编程注意本手册用条件窗口来指明32位WINDOWS版本是WINDOWS95WINDOWS98WINDOWS ME WINDOWS NT WINDOWS 2000或WINDWOS XP如果你对C编程有问题或者你想知道C语言编程的更多信息可参考16页的关于C 语言的书手册中讨论的许多例子和描述是从WINDOWS命令提示符下调用的这对在一个集成环境如µVision2中运行C x51的情况是不适用的本手册中的例子是通用的可以应用到所有编程环境手册组织本用户手册分成下面的章节和附录第一章介绍概述C x51编译器第二章用C x51编译解释怎样用C x51交叉编译器编译一个源文件本章叙述控制文件处理编译和输出的命令行提示第三章语言扩展叙述支持8051系统结构必须的C语言扩展本章提供一个在ANSI C说明中没有的命令函数和控制的详细列表第四章预处理器叙述C x51编译器预处理器的组成和包含的例子第五章派生的8051叙述C x51编译器支持的8051派生系列本章还包括能帮助提高目标程序性能的技巧第六章高级编程技术对有经验的开发人员的重要信息本章包括定制文件描述优化器详细资料和段名约定本章还讨论了C x51编译器产生的程序和别的8051编程语言如何接口第七章错误信息列出了在使用C x51编译器时可能遇到的致命错误语法错误和警告第八章库参考提高一个扩展的C x51库参考分类列出了库例程和相关的包含文件本章最后有一个按字母顺序的参考包括每个库例程的例子代码附录中包含不同编译器版本间的差异作品编号和别的有些信息文档约定本文档有下列约定例子说明README .TXT 粗体大写用在可执行程序名数据文件名源文件名环境变量和输入WINDOWS 命令行的命令上表示你必须手工输入的文本不一定要大写例CLS DIR BL51.EXELanguage Elements C 语言的构成包括关键词操作符和库函数用粗体例if != longisdigit main >>Courier 这种字体的文本代表显示在屏幕上或打印出的信息这字体也用在讨论或描述命令行中Variables 斜体字必须提供的信息例如在语法字符串中的projectfile 表示需要提供实际的工程文件名重复的成分…例子中使用的省略号…表示重复的成分省略代码 . . .垂直省略号用在源代码例子中表示省略一段程序例子void main(void ) {...while(1);[可选项]命令行中的可选参数和选择项用方括号表示例C51 TEST.C PRINT [(filename )]{opt1|opt2}大括号中的文本用竖线分隔代表一组选项必须从中选一项大括号中包含了所有选项竖线分隔选项KeysSans serif 字体的文本代表键盘的键例如按Enter 继续ContentsChapter 1. Introduction (15)Support for all 8051 Variants (15)Books About the C Language (16)Chapter 2. Compiling with the C x51 Compiler (17)Environment Variables (17)Running C x51 from the Command Prompt (18)ERRORLEVEL (19)C x51 Output Files (19)Control Directives (20)Directive Categories (20)Reference (23)AREGS / NOAREGS (24)ASM / ENDASM (26)BROWSE (28)CODE (29)COMPACT (30)COND / NOCOND (31)DEBUG (33)DEFINE (34)DISABLE (35)EJECT (37)FLOATFUZZY (38)INCDIR (39)INTERVAL (40)INTPROMOTE / NOINTPROMOTE (41)INTVECTOR / NOINTVECTOR (44)LARGE (46)LISTINCLUDE (47)MAXARGS (48)MOD517 / NOMOD517 (49)MODA2 / NOMODA2 (51)MODAB2 / NOMODAB2 (52)MODDA2 / NOMODDA2 (53)MODDP2 / NOMODDP2 (54)MODP2 / NOMODP2 (55)NOAMAKE (56)NOEXTEND (57)OBJECT / NOOBJECT (58)OBJECTADVANCE (59)OBJECTEXTEND (60)ONEREGBANK (61)OMF2 (62)OPTIMIZE (63)ORDER (65)PAGELENGTH (66)PAGEWIDTH (67)PREPRINT (68)PRINT / NOPRINT (69)REGFILE (70)REGISTERBANK (71)REGPARMS / NOREGPARMS (72)RET_PSTK, RET_XSTK (74)ROM (76)SAVE / RESTORE (77)SMALL (78)SRC (79)STRING (80)SYMBOLS (81)USERCLASS (82)VARBANKING (84)WARNINGLEVEL (85)XCROM (86)Chapter 3. Language Extensions (89)Keywords (89)Memory Areas (90)Program Memory (90)Internal Data Memory (91)External Data Memory (92)Far Memory (93)Special Function Register Memory (93)Memory Models (94)Small Model (94)Compact Model (95)Large Model (95)Memory Types (95)Explicitly Declared Memory Types (96)Implicit Memory Types (97)Data Types (97)Bit Types (98)Bit-addressable Objects (99)Special Function Registers (101)sfr (101)sfr16 (102)sbit (102)Absolute Variable Location (104)Pointers (106)Generic Pointers (106)Memory-specific Pointers (109)Pointer Conversions (111)Abstract Pointers (114)Function Declarations (118)Function Parameters and the Stack (119)Passing Parameters in Registers (120)Function Return Values (120)Specifying the Memory Model for a Function (121)Specifying the Register Bank for a Function (122)Register Bank Access (124)Interrupt Functions (125)Reentrant Functions (129)Alien Function (PL/M-51 Interface) (132)Real-time Function Tasks (133)Chapter 4. Preprocessor (135)Directives (135)Stringize Operator (136)Token-pasting operator (137)Predefined Macro Constants (138)Chapter 5. 8051 Derivatives (139)Analog Devices MicroConverter B2 Series (140)Atmel 89x8252 and Variants (141)Dallas 80C320, 420, 520, and 530 (142)Dallas 80C390, 80C400, 5240, and Variants (143)Arithmetic Accelerator (144)Infineon C517, C509, 80C537, and Variants (145)Data Pointers (145)High-speed Arithmetic (146)Library Routines (146)Philips 8xC750, 8xC751, and 8xC752 (147)Philips 80C51MX Architecture (148)Philips and Atmel WM Dual DPTR (148)Chapter 6. Advanced Programming Techniques (149)Customization Files (150)STARTUP.A51 (151)INIT.A51 (153)XBANKING.A51 (154)Basic I/O Functions (156)Memory Allocation Functions (156)Optimizer (157)General Optimizations (157)8051-Specific Optimizations (158)Options for Code Generation (158)Segment Naming Conventions (159)Data Objects (160)Program Objects (161)Interfacing C Programs to Assembler (163)Function Parameters (163)Parameter Passing in Registers (164)Parameter Passing in Fixed Memory Locations (165)Function Return Values (165)Using the SRC Directive (166)Register Usage (168)Overlaying Segments (168)Example Routines (168)Small Model Example (169)Compact Model Example (171)Large Model Example (173)Interfacing C Programs to PL/M-51 (175)Data Storage Formats (176)Bit Variables (176)Signed and Unsigned Characters, Pointers to data, idata, and pdata (177)Signed and Unsigned Integers, Enumerations, Pointers to xdata andcode (177)Signed and Unsigned Long Integers (177)Generic and Far Pointers (178)Floating-point Numbers (179)Floating-point Errors (182)Accessing Absolute Memory Locations (184)Absolute Memory Access Macros (184)Linker Location Controls (185)The _at_ Keyword (186)Debugging (187)Chapter 7. Error Messages (189)Fatal Errors (189)Actions (190)Errors (191)Syntax and Semantic Errors (193)Warnings (205)Chapter 8. Library Reference (209)Intrinsic Routines (209)Library Files (210)Standard Types (211)jmp_buf (211)va_list (211)Absolute Memory Access Macros (212)CBYTE (212)CWORD (212)DBYTE (213)DWORD (213)FARRAY, FCARRAY (214)FVAR, FCVAR, (215)PBYTE (216)PWORD (216)XBYTE (217)XWORD (217)Routines by Category (218)Buffer Manipulation (218)Character Conversion and Classification (219)Data Conversion (220)Math Routines (221)Memory Allocation Routines (223)Stream Input and Output Routines (224)String Manipulation Routines (226)Variable-length Argument List Routines (227)Miscellaneous Routines (227)Include Files (228)8051 Special Function Register Include Files (228)80C517.H (228)ABSACC.H (229)ASSERT.H (229)CTYPE.H (229)INTRINS.H (229)MATH.H (230)SETJMP.H (230)STDARG.H (230)STDDEF.H (230)STDIO.H (231)STDLIB.H (231)STRING.H (231)Reference (232)abs (233)acos / acos517 (234)asin / asin517 (235)assert (236)atan / atan517 (237)atan2 (238)atof / atof517 (239)atoi (240)atol (241)cabs (242)calloc (243)ceil (244)_chkfloat_ (245)cos / cos517 (246)cosh (247)_crol_ (248)_cror_ (249)exp / exp517 (250)fabs (251)floor (252)fmod (253)free (254)getchar (255)_getkey (256)gets (257)init_mempool (258)_irol_ (259)_iror_ (260)isalnum (261)isalpha (262)iscntrl (263)isdigit (264)isgraph (265)islower (266)isprint (267)ispunct (268)isspace (269)isupper (270)isxdigit (271)labs (272)log / log517 (273)log10 / log10517 (274)longjmp (275)_lrol_ (277)_lror_ (278)malloc (279)memccpy (280)memchr (281)memcmp (282)memcpy (283)memmove (284)memset (285)modf (286)_nop_ (287)offsetof (288)pow (289)printf / printf517 (290)putchar (296)puts (297)rand (298)realloc (299)scanf (300)setjmp (304)sin / sin517 (305)sinh (306)sprintf / sprintf517 (307)sqrt / sqrt517 (309)srand (310)sscanf / sscanf517 (311)strcat (313)strchr (314)strcmp (315)strcpy (316)strcspn (317)strlen (318)strncat (319)strncmp (320)strncpy (321)strpbrk (322)strpos (323)strrchr (324)strrpbrk (325)strrpos (326)strspn (327)strstr (328)strtod / strtod517 (329)strtol (331)strtoul (333)tan / tan517 (335)tanh (336)_testbit_ (337)toascii (338)toint (339)tolower (340)_tolower (341)toupper (342)_toupper (343)ungetchar (344)va_arg (345)va_end (347)va_start (348)vprintf (349)vsprintf (351)Appendix A. Differences from ANSI C (353)Compiler-related Differences (353)Library-related Differences (353)Appendix B. Version Differences (357)Version 6.0 Differences (357)Version 5 Differences (358)Version 4 Differences (359)Version 3.4 Differences (361)Version 3.2 Differences (362)Version 3.0 Differences (363)Version 2 Differences (364)Appendix C. Writing Optimum Code (367)Memory Model (367)Variable Location (369)Variable Size (369)Unsigned Types (370)Local Variables (370)Other Sources (370)Appendix D. Compiler Limits (371)Appendix E. Byte Ordering (373)Appendix F. Hints, Tips, and Techniques (375)Recursive Code Reference Error (375)Problems Using the printf Routines (376)Uncalled Functions (377)Using Monitor-51 (377)Trouble with the bdata Memory Type (378)Function Pointers (379)Glossary (383)Index (391)࢒ጙᐺ஑࿬C语言是一个通用的编程语言它提供高效的代码结构化的编程和丰富的操作符C不是一种大语言不是为任何特殊应用领域而设计它一般来说限制较少可以为各种软件任务提供方便和有效的编程许多应用用C比其他语言编程更方便和有效优化的C x51 C编译器完整的实现了ANSI的C语言标准对8051来说C x51不是一个通用的C编译器它首先的目标是生成针对8051的最快和最紧凑的代码C x51具有C编程的弹性和高效的代码和汇编语言的速度C语言不能执行的操作如输入和输出需要操作系统的支持这些操作作为标准库的一部分提供因为这些函数和语言本身无关所以C特别适合对多平台提供代码既然C x51是一个交叉编译器C语言的某些方面和标准库就有了改变或增强以适应一个嵌套的目标处理器的特性更多的细节参考89页的第三章.语言扩展支持所有的8051变种8051系列是增长最快的微处理器构架之一从不同的芯片厂家提供了400多种芯片新扩展的8051芯片如PHILIPS 8051MX有几M字节的代码和数据空间可被用到大的应用中为了支持这些不同的8051芯片KEIL提供了几种开发工具如下表所列一个新的输出文件格式OMF2允许支持最多16MB代码和数据空间CX51编译器适用于新的PHILIPS 8051MX结构开发工具支持的微处理器说明C51编译器A51宏汇编BL51连接器对传统的8051开发工具包括支持32 x64KB 的代码库C51编译器有OMF2输出AX51宏汇编LX51连接器对传统的8051和扩展的8051芯片如DALLAS 390的开发工具包括支持代码库和最多16MB代码和XDATA存储区CX51编译器AX51宏汇编LX51连接器对PHILIPS 8051MX的开发工具支持最多16MB 代码和XDATA存储区C x 51编译器在不同的包中提供上表是完整的8051开发工具参考注意Cx51指两种编译器C51编译器和CX51编译器C 语言的书有许多书介绍C 语言有更多的书详细介绍用C 完成的任务下面的列表不是一个完整的列表列表只是作为参考The C Programming Language, Second Edition Kernighan & RitchiePrentice-Hall, Inc.ISBN 0-13-110370-9C: A Reference Manual, Second EditionHarbison & SteelPrentice-Hall Software SeriesISBN 0-13-109810-1C and the 8051: Programming and MultitaskingSchultzP T R Prentice-Hall, Inc.ISBN 0-13-753815-4࢒औᐺ፿Cx51ܠፉ໭ܠፉ本章说明怎样编译C源文件讨论编译器的控制命令这些命令可以命令C x51编译器产生列表文件控制包含在OBJ文件中的信息的数量指定优化级别和存储模式注意一般来说你应在µVision2 IDE中使用Cx51关于使用µVision2IDE的更多信息参考用户手册Getting Started with µVision2 and C51”.环境变量如果在µVision2IDE中运行Cx51编译器计算机不需要另外的设置如果想要在命令行中运行C x51编译器和工具必须手工创建下面的环境变量变量路径环境变量说明PATH\C51\BIN C51和CX51可执行程序的路径TMP编译器产生的临时文件的路径如果指定的路径不存在编译器会生成错误并停止编译C51INC\C51\INC Cx51头文件的路径C51LIB\C51\LIB Cx51库文件的路径对WINSOWS NT WINDOWS 2000和WINDOWS XP这些环境变量在Control Panel –System – Advanced – Environment Variables中输入对WINDOWS 95WINDOWS 98和WINDOWS ME这些设置放在AUTOEXEC.BAT中PATH=C\KEIL\C51\BIN;%PATH%SET TMP=D:\SET C51INC=C:\KEIL\C51\INCSET C51LIB=C:\KEIL\C51\LIB从命令行运行Cx51调用C51或CX51编译器在命令行输入C51或CX51在命令行中必须包含要编译的C源文件和必需的编译控制命令C x51命令行的格式C51 sourcefile [directives…]CX51 sourcefile [directives…]或C51 @commandfileCX51 @commandfile这里sourcefile要编译的源文件名directives用来控制编译器功能的命令参考20页的控制命令commandfile包含源文件名和命令的命令输入文件当C x51调用行较复杂超过了WINDOWS命令行的限制时使用commandfile下面的命令行例子调用C51指定源文件SAMPLE.C用控制DEBUG CODE和PREPRINTC51 SAMPLE.C DEBUG CODE PREPRINTC x51编译器在成功编译后显示下面的信息C51 COMPILER V6.10C51 COMPILATION COMPLETE. 0 WARNING S0 ERROR S错误级别在编译后错误和警告的数目输出在屏幕上C x51编译器设置ERRORLEVEL指示编译的状态值如下表所列错误级别意义0没有错误或警告1只有警告2错误和可能的警告3致命错误可以在批处理文件中访问ERRORLEVEL变量关于ERRORLEVEL或批处理文件可以参考WINDOWS命令索引或在线帮助Cx51输出文件C x51编译器在编译时产生许多输出文件缺省的输出文件和源文件同名但文件的扩展名不同下面的表列出了文件并有简短的说明文件扩展说明Filename.LST列表文件包含格式化的源文件和编译中检测到的错误列表文件可以选择包含所用的符号和生成汇编代码更多的信息参考PRINT命令Filename.OBJ包含可重定位目标代码的OBJ模块OBJ模块用Lx51连接器连接到一个绝对的OBJ模块Filename.I包含由预处理器扩展的源文件所有的宏都扩展了所有的注释都删除了可参考PREPRINT命令Filename.SRC C源代码产生的汇编源文件可以用A51汇编可参考SRC命令控制命令C x51编译器提供许多控制命令控制编译除了指定的命令由一个或多个字母或数字组成在命令行中在文件名后指定或在源文件中用#pragma命令例如C51 testfile.c SYMBOLS CODE DEBUG#pragma SYMBOLS CODE DEBUG在说明的例子中SYMBOLS CODE和DEBUG都是控制命令testfile.C是要编译的源文件注意对命令行和#pragma语法是相同的在#pragma可指定多个选项典型的每个控制命令只在源文件的开头指定一次如果一个命令指定多次编译器产生一个致命错误退出编译可以指定多次的命令在下面部分注明命令种类控制命令可以分成三类源文件控制目标控制和列表控制源文件控制定义命令行的宏定义要编译的文件名目标控制影响产生的目标模块*.OBJ的形式和内容这些命令指定优化级别或在OBJ文件中包含调试信息列表控制管理列表文件*.LST的各种样式特别是格式和指定的内容上下表按字母顺序列出了控制命令有下划线的字母表示命令的缩写命令类说明AREGS NOAREGS Object 使能或不使能绝对寄存器ARn地址ASM ENDASM Source 标志内嵌汇编块的开始和结束BROWSE †Object 产生浏览器信息CODE †Listing 加一个汇编列表到列表文件COMPACT †Object 设置COMPACT 存储模式COND NOCOND †Listing 包含或执行预处理器跳过的源程序行DEBUG †Object 在OBJ 文件中包含调试信息DEFINE Source 在Cx51调用行定义预处理器名DISABLE Object 在一个函数内不允许中断EJECTListing 在列表文件中插入一个格式输入字符FLOATFUZZY Object 在浮点比较中指定位数INCDIR †Source 指定头文件的附加路径名INTERVAL †Object 对SIECO 芯片指定中断矢量间隔INTPROMOTE NOINTPROMOTE†Object 使能或不使能ANSI 整数同时提升INTVECTOR NOINTVECTOR †Object 指定中断矢量的基地址或不使能矢量LARGE †Object 选择LARGE 存储模式LISTINCLUDE Listing 在列表文件中显示头文件MAXAREGS †Object 指定可变参数列表的大小MOD517NOMOD517Object 使能或不使能代码支持80C517和派生的额外的硬件特征MODA2NOMODA2Object 使能或不使能ATMEL 82x8252和变种的双DPTR 寄存器MODAB2NOMODAB2Object 使能或不使能模拟设备ADuC B2系列支持双DPTR 寄存器MODDA NOMODDA Object 使能或不使能DALLAS 80C39080C400和5240支持算法加速器MODDP2NOMODDP2Object 使能或不使能DALLAS 的320520530550和变种支持双DPTR 寄存器MODP2NOMODP2Object 使能或不使能PHILIPS 和ATMELWM 派生的支持双DPTR 寄存器NOAMAKE †Object 不记录µVision2更新信息NOEXTEND †Source Cx51不扩展到ANSI COBJECT NOOBJECT †Object 指定一个OBJ 文件或禁止OBJ 文件OBJECTEXTEND†Object 在OBJ 文件中包含变量类型信息ONEREGBANKObject假定在中断中只用寄存器组0命令类说明OMF2†Object 产生OMF2输出文件格式OPTIMIZE Object 指定编译器的优化级别ORDER †Object 按源文件中变量的出现顺序分配PAGELENGTH †Listing 指定页的行数PAGEWIDTH †Listing 指定页的列数PREPRINT †Listing 产生一个预处理器列表文件扩展所有宏PRINTNOPRINT †Listing 指定一个列表文件名或不使能列表文件REGFILE †Object 对全局寄存器优化指定一个寄存器定义文件REGISTERBANK Object 为绝对寄存器访问选择寄存器组REGPARMS NOREGPARMS Object 使能或不使能寄存器参数传递RET_PSTK † RET_XSTK †Object 用重入堆栈保存返回地址ROM †Object AJMP/ACALL 指令产生控制SAVERESTORE Object 保存和恢复AREGS REGPARMS 和OPTIMIZE 命令设置SMALL†Object 选择SMALL 存储模式缺省SRC †Object 产生一个汇编源文件不产生OBJ 模块STRING †Object 定位固定字符串到XDATA 或远端存储区SYMBOLS †Listing 模块中所有符号的列表文件USERCLASS †Object 对可变的变量位置重命名存储区类VARBANKING †Object 使能FAR 存储类型变量WARNINGLEVEL†Listing 选择警告检测级别XCROM †Object对CONST XDATA 变量假定ROM 空间† 这些命令在命令行或源文件开头的#pragma中只指定一次在一个源文件中不能使用多次控制命令和参数除了用DEFINE 命令的参数是大小写无关的参考本章的余下部分按字母顺序描述C x51编译器控制命令他们分成如下部分缩写可以替代命令的缩写参数命令可选和要求的参数缺省命令的缺省设置µVision2控制怎样指定命令说明详细的说明命令和使用参考相关命令例子命令使用的例子有时也列出结果AREGS/NOAREGS缩写无参数无缺省AREGSµVision2控制Options – C51 – Don‘t use absolute register access说明AREGS控制使编译器对寄存器R0到R7用绝对寄存器地址绝对地址提高了代码的效率例如PUSH和POP指令只能用直接或绝对地址用AREGS命令可以直接PUSH或POP寄存器可用REGISTERBANK命令定义使用的寄存器组NOAREGS命令对寄存器R0到R7不使能绝对寄存器地址用NOAREGS编译的函数可以使用所有的8051寄存器组命令可用在被别的函数用不同的寄存器组调用的函数中注意虽然可能在一个程序中定义了几次AREGS/NOAREGS选项只有定义在函数声明为有效例子下面是一个使用NOAREGS 和AREGS 的源程序和代码的列表注意保存R7到堆栈中的不同方法函数noaregfunc 产生的代码是MOV A R7PUSHACC同时对aregfunc 函数的代码是PUSHAR7stmt levelsource1extern char func ();2char k;34#pragma NOAREGS 5noaregfunc (){61k =func ()+func ();71}89#pragma AREGS 10aregfunc (){111k =func ()+func ();121};FUNCTION noaregfunc (BEGIN);SOURCE LINE #60000120000E LCALL func 0003EF MOV A,R70004C0E0PUSH ACC 0006120000E LCALL func 0009D0E0POP ACC 000B 2F ADD A,R7000C F500R MOV k,A;SOURCE LINE #7000E22RET;FUNCTION noaregfunc (END);FUNCTION aregfunc (BEGIN);SOURCE LINE #110000120000E LCALL func 0003C007PUSH AR70005120000E LCALL func 0008D0E0POP ACC 000A 2F ADD A,R7000B F500R MOV k,A;SOURCE LINE #12000D22RET;FUNCTION aregfunc (END)ASM/ENDASM缩写无参数无缺省无µVision2控制本命令不能在命令行指定说明ASM命令标志一块源程序的开始它可以直接合并到由SRC命令产生的.SRC文件中这些源程序可以认为是内嵌的汇编然而它只输出到由SRC命令产生的源文件中源程序不汇编和输出到OBJ文件中在µVision2应对C源文件中包含ASM/ENDASM段如下设置一个文件指定选项右键点击PROJECT窗口 – 文件表中的文件选择Options for…打开选项 – 属性页使能Generate Assembler SRC file使能Assemble SRC file用这些设置µVision2产生一个汇编源文件.SRC并用汇编编译产生一个OBJ文件.OBJENDASM命令标志一个源程序块的结束注意ASM和ENDASM命令只能在源文件中使用且作为#pragma命令的一部分例子#pragma asm / #pragma endasm 下面是C 源文件产生下面的.SRC 文件...stmt levelsource1extern void test ();23main (){41test ();5161#pragma asm 71JMP $;endless loop 81#pragma endasm 91}..;ASM.SRC generated from:ASM.C NAME ASM ?PR?main?ASM SEGMENT CODE EXTRN CODE (test)EXTRN CODE (?C_STARTUP)PUBLIC main;extern void test ();;;main (){RSEG ?PR?main?ASM USING 0main:;SOURCE LINE #3;test ();;SOURCE LINE #4LCALL test;;#pragma asmJMP $;endless loop;#pragma endasm ;};SOURCE LINE #9RET ;END OF mainENDBROWSE缩写BR参数无缺省不创建浏览信息µVision2控制Options – Output – Browse Information说明用BROWSE编译器产生浏览信息浏览信息包括标识符包含预处理器符号他们的存储空间类型定义和参考列表信息可以在µVision2内显示选择View – Source Browser打开µVision2源浏览器参考µVision2用户手册第四章µVision2功能源浏览器例子C51 SAMPLE.C BROWSE#pragma browseCODE缩写CD参数无缺省不产生汇编代码列表µVision2控制Options – Listing – C Compiler Listing – Assembly Code说明CODE命令附加一个汇编助记符列表到列表文件汇编程序代码代表源程序中的每个函数缺省的在列表文件中没有汇编代码例子C51 SAMPLE.C CD#pragma code下面例子显示C源程序和它产生的OBJ结果代码和助记符在汇编间显示了产生代码的行号字符R和E代表可重定位和外部的stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61c=14+15*((b/c)+252);71}...ASSEMBLY LISTING OF GENERATED OBJECT CODE;FUNCTION main(BEGIN);SOURCE LINE#5;SOURCE LINE#60000E500E MOV A,b00028500F0R MOV B,c000584DIV AB000675F00F MOV B,#0FH0009A4MUL AB000A24D2ADD A,#0D2H000C F500R MOV c,A;SOURCE LINE#7000E22RET;FUNCTION main(END)COMPACT缩写CP参数无缺省SMALLµVision2控制Options – Target – Memory Model说明本命令选择COMPACT存储模式在COMPACT存储模式中所有的函数和程序变量和局部数据段定位在8051系统的外部数据存储区外部数据存储区可有最多256字节一页在本模式中外部数据存储区的短地址用@R0/R1不管什么存储类型可以在任何8051的存储范围内声明变量但是把常用的变量如循环计数器和数组索引放在内部数据存储区可以显著的提高系统性能注意函数调用所用的堆栈经常放在IDATA存储区参考SAMLL LARGE ROM例子C51 SAMPLE.C COMPACT#pragma compactCOND/NOCOND缩写CO参数无缺省CONDµVision2控制Options – Listing – C Compiler Listing - Conditional说明本命令定义这些部分的受条件编译影响的源程序是否显示在列表文件中COND命令在列表文件中包含编译省略的行行号和嵌套级不输出以便于阅读本命令影响预处理器删除的行NOCOND命令不在列表文件中包含编译省略的行例子下面的例子显示用COND命令编译产生的一个列表文件...stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61#if defined(VAX)c=13;#elif defined(__TIME__)91b=14;101a=15;111#endif121}..下面的例子用NOCOND命令编译产生的一个列表文件...stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61#if defined(VAX)91b=14;101a=15;111#endif121}...缩写DB参数无缺省不产生调试信息µVision2控制Options – Output – Debug Information说明DEBUG命令指示编译器在OBJ文件中包含调试信息缺省OBJ 文件不包含调试信息对程序的符号测试必需有调试信息信息包括全局和局部变量定义和地址和函数名和行号包含在目标模块中的调试信息在连接过程中仍有效这些信息可以被µVision2调试器或任何INTEL兼容的模拟器使用注意OBJECTEXTEND命令用来指示编译器在目标文件中包含附加的变量类型定义信息参考OBJECTEXTEND例子C51 SAMPLE.C DEBUG#pragma db缩写DF参数一个或多个符合C语言约定的的名称用逗号分隔对每个名称可有一个参数用DEFINE给出缺省无µVision2控制在Options –C x51 – Define输入名称说明DEFINE命令定义调用行的名称预处理器要用#if#ifdef和#ifndef查询这些名称定义的名称在输入后被复制这些命令是大小写相关的作为一个选项每个名称可跟一个值注意DEFINE命令只能在命令行中指定在一个C源程序中用C预处理器命令#define例子C51 SAMPLE.C DEFINE check,NoExtRamC51 MYPROG.C DF (X1=“1+5”,iofunc=“getkey()”)DISABLE缩写无参数无缺省无µVision2控制本命令不能在命令行中指定只能在源文件中指定说明DISABLE命令指示编译器在产生代码时在一个函数内不使能所有中断DISABLE必须在一个函数声明前一行用#pragma命令指定DISABLE控制只用到一个函数对每个新的函数必须重新指定注意DISABLE只能用#pragma命令指定不能在命令行指定DISABLE可在一个源文件中指定多次对每个函数只能指定一次执行后不使能中断一个不使能中断的函数不能对调用者返回一个位值例子本例子是一个用DISABLE命令函数的源程序和代码列表注意EA指定函数寄存器在函数进入时清除JBC EA C002在结尾时恢复MOV EA C...stmt level source1typedef unsigned char uchar;23#pragma disable/*Disable Interrupts*/4uchar dfunc(uchar p1,uchar p2){51return(p1*p2+p2*p1);61};FUNCTION_dfunc(BEGIN)0000D3SETB C000110AF01JBC EA,?C00020004C3CLR C0005?C0002:0005C0D0PUSH PSW;----Variable'p1'assigned to register'R7'----;----Variable'p2'assigned to register'R5'----;SOURCE LINE#4;SOURCE LINE#50007ED MOV A,R500088FF0MOV B,R7000A A4MUL AB000B25E0ADD A,ACC000D FF MOV R7,A;SOURCE LINE#6000E?C0001:000E D0D0POP PSW001092AF MOV EA,C001222RET;FUNCTION_dfunc(END)...EJECT缩写EJ参数无缺省无µVision2控制本命令不能在命令行中指定只能在源文件中指定说明EJECT命令在列表文件中插入一个格式输入字符注意EJECT只在源文件中出现必须是#pragma命令的一部分例子#pragma ejectFLOATFUZZY缩写FF参数0到7间的一个数字缺省FLOATFUZZY3µVision2控制Options - C x51 – Bits to round for float compare说明FLOATFUZZY命令在一个浮点比较前定义位数缺省值3指定最少有三个有效位例子C51 MYFILE.C FLOATFUZZY2#pragma FF(0)INCDIR缩写无参数指定头文件的路径缺省无µVision2控制Options - C x51 – Include Paths说明INCDIR命令指定Cx51编译器头文件的位置编译器最多50个路径声明如果需要多个路径路径名必须用分号分开如果指定#include“filename.h”Cx51编译器首先搜索当前目录然后是源文件目录当找不到或用了#include <filename.h>就搜索INCDIR指定的路径当仍找不到就使用C51INC环境变量指定的路径例子C51 SAMPLE.C INDIR C\KEIL\C51\MYINC;C:\CHIP-DIRINTERVAL缩写无参数对中断矢量表可选用括号括住缺省INTERV AL8µVision2控制Options - C x51 – Misc controls:enter the directive说明INTERV AL命令指定中断矢量的间隔指定间隔是SIECO-51派生系列要求的它定义中断矢量在3字节间隔用本命令编译器定位中断矢量在绝对地址如下计算(interval×n)+offset+3,这里interval INTERV AL命令的参数缺省为8n中断号offset INTVECTOR命令的参数缺省为0参考INTVECTOR/NOINTVECTOR例子C51 SAMPLE.C INTERV AL3#pragma interval(3)INTPROMOTE/NOINTPROMOTE缩写IP/NOIP参数无缺省INTPROMOTEµVision2控制Options - C x51 – Enable ANSI integer promotion rules说明INTPROMOTE命令使能ANSI整数提升规则如果提升声明了在比较前所用的表达式从小类型提升到整数表达式这使MICROSOFT C和BORLAND C改动很少就可用到Cx51上因为8051是8位处理器使用INTPROMOTE命令可能在某些应用中降低效率NOINTPROMOTE命令不使能自动整数提升整数提升使Cx51和别的ANSI编译器间有更大的兼容性然而整数提升可能降低效率例子C51 SAMPLE.C INTPROMOTE#pragma intpormoteC51 SAMPLE.C NOINTPROMOTE下面的代码示范用INTPROMOTE和NOINTPROMOTE命令产生的代码stmt lvl source1char c;2unsigned char c1,c2;3int i;45main(){61if(c==0xff)c=0;/*never true!*/71if(c==-1)c=1;/*works*/81i=c+5;91if(c1<c2+4)c1=0;101}Code generated with INTPROMOTE Code generated with NOINTPROMOTE;FUNCTION main(BEGIN);SOURCE LINE#60000AF00MOV R7,c0002EF MOV A,R7000333RLC A000495E0SUBB A,ACC0006FE MOV R6,A0007EF MOV A,R70008F4CPL A00094E ORL A,R6000A7002JNZ?C0001000C F500MOV c,A000E?C0001:;SOURCE LINE#7000E E500MOV A,c0010B4FF03CJNE A,#0FFH,?C0002 0013750001MOV c,#01H0016?C0002:;SOURCE LINE#80016AF00MOV R7,c0018EF MOV A,R7001933RLC A001A95E0SUBB A,ACC001C FE MOV R6,A001D EF MOV A,R7001E2405ADD A,#05H0020F500MOV i+01H,A0022E4CLR A00233E ADDC A,R60024F500MOV i,A;SOURCE LINE#90026E500MOV A,c200282404ADD A,#04H002A FF MOV R7,A002B E4CLR A002C33RLC A002D FE MOV R6,A002E C3CLR C002F E500MOV A,c100319F SUBB A,R70032EE MOV A,R600336480XRL A,#080H0035F8MOV R0,A00367480MOV A,#080H003898SUBB A,R000395003JNC?C0004003B E4CLR A003C F500MOV c1,A;SOURCE LINE#10003E?C0004:003E22RET;FUNCTION main(END);FUNCTION main(BEGIN);SOURCE LINE#60000AF00MOV R7,c0002EF MOV A,R7000333RLC A000495E0SUBB A,ACC0006FE MOV R6,A0007EF MOV A,R70008F4CPL A00094E ORL A,R6000A7002JNZ?C0001000C F500MOV c,A000E?C0001:;SOURCE LINE#7000E E500MOV A,c0010B4FF03CJNE A,#0FFH,?C0002 0013750001MOV c,#01H0016;SOURCE LINE#80016E500MOV A,c00182405ADD A,#05H001A FF MOV R7,A001B33RLC A001C95E0SUBB A,ACC001E F500MOV i,A00208F00MOV i+01H,R7;SOURCE LINE#90022E500MOV A,c200242404ADD A,#04H0026FF MOV R7,A0027E500MOV A,c10029C3CLR C002A9F SUBB A,R7002B5003JNC?C0004002D E4CLR A002E F500MOV c1,A;SOURCE LINE#100030?C0004:003022RET;FUNCTION main(END)CODE SIZE = 63 Bytes CODE SIZE = 49 BytesINTVECTOR/NOINTVECTOR缩写IV/NOIV参数对中断矢量表一个可选的偏移在括号中缺省INTVECTOR0µVision2控制Options - C x51 – Misc controls:enter the directive说明INTVECTOR命令指示编译器对要求的函数产生中断矢量如果矢量表不从0开始需输入一个偏移用本命令编译器产生一个中断矢量入口根据ROM命令指定的程序存储区用AJMP或LJMP指令跳转NOINTVECTOR命令禁止产生中断矢量表这也许用户用别的编程工具提供中断矢量编译器通常用一个3字节跳转指令LJMP产生一个中断矢量矢量用绝对地址表示(interval × n) + offset + 3,这里n中断号interval INTERV AL命令的参数缺省为8offset INTVECTOR命令的参数缺省为0参考INTERV AL。

Cx51 编译器 说明书 09.2001

Cx51 编译器 说明书 09.2001

Cx51编译器对传统和扩展的8051微处理器的优化的C 编译器和库参考用户手册09.2001Keil Software – Cx51编译器用户手册—ፉᑗኔፉᑗኔ由于本人的英语水平有限所以在使用KEIL C51的过程中老要去看那英文的手册总感到不是那么方便老要用词霸查来查去的烦的很因此在看到C51BBS上的倡议后就动了把它翻译出来的念头我想这对自己和别人都会带来些好处利用工作之余的时间经过几个月的努力终于把它翻译完了但由于水平所限文中肯定有很多不是十分恰当的地方或许没有用大家比较熟悉的惯用语或许可能引起误解所以在这里我请大家能指出其中的错误和不当之处请大家EMAIL告诉我使我能够作出改正对于大家的建议我会很高兴的接受我最大的愿望是希望我的翻译不会误导大家且能对大家有所帮助不明之处可以参考英文原文感谢C51BBS版主龙啸九天的帮助欢迎大家与我交流我的e-mail**************Keil Software声明本文档所述信息不属于我公司的承诺范围其内容的变化也不会另行通知本文档所述软件的出售必须经过授权或签订特别协议本文档所述软件的使用必须遵循协议约定在协议约定以外的任何媒体上复制本软件将触犯法律购买者可以备份为目的而做一份拷贝在未经书面许可之前本手册的任何一部分都不允许为了购买者个人使用以外的目的而以任何形式和任何手段(电子的机械的)进行复制或传播版权1988-2001所有者Keil Elektronik GmbH和Keil Software公司Keil C51™Keil CX51™,和uVision TM是Keil Elektronik GmbH的商标Microsoft®和Windows™是Microsoft Corporation的商标或注册商标IBM®PC®和PS/2®是International Business Machines Corporation的注册商标Intel®MCS®51MCS®251ASM-51®和PL/M-51®是Intel的注册商标我们尽全力去做来保证这本手册的正确从而保证我们个人公司和在此提及的商标的形象前言本手册讲述对8051的目标环境如何使用C x51优化C编译器编译C程序C x51编译器包可以用在所有的8051系列处理器上可以在WINDOWS 32位命令行中执行本手册假定你熟悉WINDOWS操作系统知道如何编程8051处理器并会用C语言编程注意本手册用条件窗口来指明32位WINDOWS版本是WINDOWS95WINDOWS98WINDOWS ME WINDOWS NT WINDOWS 2000或WINDWOS XP如果你对C编程有问题或者你想知道C语言编程的更多信息可参考16页的关于C 语言的书手册中讨论的许多例子和描述是从WINDOWS命令提示符下调用的这对在一个集成环境如µVision2中运行C x51的情况是不适用的本手册中的例子是通用的可以应用到所有编程环境手册组织本用户手册分成下面的章节和附录第一章介绍概述C x51编译器第二章用C x51编译解释怎样用C x51交叉编译器编译一个源文件本章叙述控制文件处理编译和输出的命令行提示第三章语言扩展叙述支持8051系统结构必须的C语言扩展本章提供一个在ANSI C说明中没有的命令函数和控制的详细列表第四章预处理器叙述C x51编译器预处理器的组成和包含的例子第五章派生的8051叙述C x51编译器支持的8051派生系列本章还包括能帮助提高目标程序性能的技巧第六章高级编程技术对有经验的开发人员的重要信息本章包括定制文件描述优化器详细资料和段名约定本章还讨论了C x51编译器产生的程序和别的8051编程语言如何接口第七章错误信息列出了在使用C x51编译器时可能遇到的致命错误语法错误和警告第八章库参考提高一个扩展的C x51库参考分类列出了库例程和相关的包含文件本章最后有一个按字母顺序的参考包括每个库例程的例子代码附录中包含不同编译器版本间的差异作品编号和别的有些信息文档约定本文档有下列约定README .TXT 粗体大写用在可执行程序名数据文件名源文件名环境变量和输入WINDOWS 命令行的命令上表示你必须手工输入的文本不一定要大写例CLS DIR BL51.EXELanguage Elements C 语言的构成包括关键词操作符和库函数用粗体例if != longisdigit main >>Courier 这种字体的文本代表显示在屏幕上或打印出的信息这字体也用在讨论或描述命令行中Variables 斜体字必须提供的信息例如在语法字符串中的projectfile 表示需要提供实际的工程文件名重复的成分…例子中使用的省略号…表示重复的成分省略代码 . . .垂直省略号用在源代码例子中表示省略一段程序例子void main(void ) { . . .while(1);[可选项]命令行中的可选参数和选择项用方括号表示例C51 TEST.C PRINT [(filename )]{opt1|opt2}大括号中的文本用竖线分隔代表一组选项必须从中选一项大括号中包含了所有选项竖线分隔选项KeysSans serif 字体的文本代表键盘的键例如按Enter 继续ContentsChapter 1. Introduction (15)Support for all 8051 Variants (15)Books About the C Language (16)Chapter 2. Compiling with the C x51 Compiler (17)Environment Variables (17)Running C x51 from the Command Prompt (18)ERRORLEVEL (19)C x51 Output Files (19)Control Directives (20)Directive Categories (20)Reference (23)AREGS / NOAREGS (24)ASM / ENDASM (26)BROWSE (28)CODE (29)COMPACT (30)COND / NOCOND (31)DEBUG (33)DEFINE (34)DISABLE (35)EJECT (37)FLOATFUZZY (38)INCDIR (39)INTERVAL (40)INTPROMOTE / NOINTPROMOTE (41)INTVECTOR / NOINTVECTOR (44)LARGE (46)LISTINCLUDE (47)MAXARGS (48)MOD517 / NOMOD517 (49)MODA2 / NOMODA2 (51)MODAB2 / NOMODAB2 (52)MODDA2 / NOMODDA2 (53)MODDP2 / NOMODDP2 (54)MODP2 / NOMODP2 (55)NOAMAKE (56)NOEXTEND (57)OBJECT / NOOBJECT (58)OBJECTADVANCE (59)OBJECTEXTEND (60)ONEREGBANK (61)OMF2 (62)OPTIMIZE (63)ORDER (65)PAGELENGTH (66)PAGEWIDTH (67)PREPRINT (68)PRINT / NOPRINT (69)REGFILE (70)REGISTERBANK (71)REGPARMS / NOREGPARMS (72)RET_PSTK, RET_XSTK (74)ROM (76)SAVE / RESTORE (77)SMALL (78)SRC (79)STRING (80)SYMBOLS (81)USERCLASS (82)VARBANKING (84)WARNINGLEVEL (85)XCROM (86)Chapter 3. Language Extensions (89)Keywords (89)Memory Areas (90)Program Memory (90)Internal Data Memory (91)External Data Memory (92)Far Memory (93)Special Function Register Memory (93)Memory Models (94)Small Model (94)Compact Model (95)Large Model (95)Memory Types (95)Explicitly Declared Memory Types (96)Implicit Memory Types (97)Data Types (97)Bit Types (98)Bit-addressable Objects (99)Special Function Registers (101)sfr (101)sfr16 (102)sbit (102)Absolute Variable Location (104)Pointers (106)Generic Pointers (106)Memory-specific Pointers (109)Pointer Conversions (111)Abstract Pointers (114)Function Declarations (118)Function Parameters and the Stack (119)Passing Parameters in Registers (120)Function Return Values (120)Specifying the Memory Model for a Function (121)Specifying the Register Bank for a Function (122)Register Bank Access (124)Interrupt Functions (125)Reentrant Functions (129)Alien Function (PL/M-51 Interface) (132)Real-time Function Tasks (133)Chapter 4. Preprocessor (135)Directives (135)Stringize Operator (136)Token-pasting operator (137)Predefined Macro Constants (138)Chapter 5. 8051 Derivatives (139)Analog Devices MicroConverter B2 Series (140)Atmel 89x8252 and Variants (141)Dallas 80C320, 420, 520, and 530 (142)Dallas 80C390, 80C400, 5240, and Variants (143)Arithmetic Accelerator (144)Infineon C517, C509, 80C537, and Variants (145)Data Pointers (145)High-speed Arithmetic (146)Library Routines (146)Philips 8xC750, 8xC751, and 8xC752 (147)Philips 80C51MX Architecture (148)Philips and Atmel WM Dual DPTR (148)Chapter 6. Advanced Programming Techniques (149)Customization Files (150)STARTUP.A51 (151)INIT.A51 (153)XBANKING.A51 (154)Basic I/O Functions (156)Memory Allocation Functions (156)Optimizer (157)General Optimizations (157)8051-Specific Optimizations (158)Options for Code Generation (158)Segment Naming Conventions (159)Data Objects (160)Program Objects (161)Interfacing C Programs to Assembler (163)Function Parameters (163)Parameter Passing in Registers (164)Parameter Passing in Fixed Memory Locations (165)Function Return Values (165)Using the SRC Directive (166)Register Usage (168)Overlaying Segments (168)Example Routines (168)Small Model Example (169)Compact Model Example (171)Large Model Example (173)Interfacing C Programs to PL/M-51 (175)Data Storage Formats (176)Bit Variables (176)Signed and Unsigned Characters, Pointers to data, idata, and pdata (177)Signed and Unsigned Integers, Enumerations, Pointers to xdata andcode (177)Signed and Unsigned Long Integers (177)Generic and Far Pointers (178)Floating-point Numbers (179)Floating-point Errors (182)Accessing Absolute Memory Locations (184)Absolute Memory Access Macros (184)Linker Location Controls (185)The _at_ Keyword (186)Debugging (187)Chapter 7. Error Messages (189)Fatal Errors (189)Actions (190)Errors (191)Syntax and Semantic Errors (193)Warnings (205)Chapter 8. Library Reference (209)Intrinsic Routines (209)Library Files (210)Standard Types (211)jmp_buf (211)va_list (211)Absolute Memory Access Macros (212)CBYTE (212)CWORD (212)DBYTE (213)DWORD (213)FARRAY, FCARRAY (214)FVAR, FCVAR, (215)PBYTE (216)PWORD (216)XBYTE (217)XWORD (217)Routines by Category (218)Buffer Manipulation (218)Character Conversion and Classification (219)Data Conversion (220)Math Routines (221)Memory Allocation Routines (223)Stream Input and Output Routines (224)String Manipulation Routines (226)Variable-length Argument List Routines (227)Miscellaneous Routines (227)Include Files (228)8051 Special Function Register Include Files (228)80C517.H (228)ABSACC.H (229)ASSERT.H (229)CTYPE.H (229)INTRINS.H (229)MATH.H (230)SETJMP.H (230)STDARG.H (230)STDDEF.H (230)STDIO.H (231)STDLIB.H (231)STRING.H (231)Reference (232)abs (233)acos / acos517 (234)asin / asin517 (235)assert (236)atan / atan517 (237)atan2 (238)atof / atof517 (239)atoi (240)atol (241)cabs (242)calloc (243)ceil (244)_chkfloat_ (245)cos / cos517 (246)cosh (247)_crol_ (248)_cror_ (249)exp / exp517 (250)fabs (251)floor (252)fmod (253)free (254)getchar (255)_getkey (256)gets (257)init_mempool (258)_irol_ (259)_iror_ (260)isalnum (261)isalpha (262)iscntrl (263)isdigit (264)isgraph (265)islower (266)isprint (267)ispunct (268)isspace (269)isupper (270)isxdigit (271)labs (272)log / log517 (273)log10 / log10517 (274)longjmp (275)_lrol_ (277)_lror_ (278)malloc (279)memccpy (280)memchr (281)memcmp (282)memcpy (283)memmove (284)memset (285)modf (286)_nop_ (287)offsetof (288)pow (289)printf / printf517 (290)putchar (296)puts (297)rand (298)realloc (299)scanf (300)setjmp (304)sin / sin517 (305)sinh (306)sprintf / sprintf517 (307)sqrt / sqrt517 (309)srand (310)sscanf / sscanf517 (311)strcat (313)strchr (314)strcmp (315)strcpy (316)strcspn (317)strlen (318)strncat (319)strncmp (320)strncpy (321)strpbrk (322)strpos (323)strrchr (324)strrpbrk (325)strrpos (326)strspn (327)strstr (328)strtod / strtod517 (329)strtol (331)strtoul (333)tan / tan517 (335)tanh (336)_testbit_ (337)toascii (338)toint (339)tolower (340)_tolower (341)toupper (342)_toupper (343)ungetchar (344)va_arg (345)va_end (347)va_start (348)vprintf (349)vsprintf (351)Appendix A. Differences from ANSI C (353)Compiler-related Differences (353)Library-related Differences (353)Appendix B. Version Differences (357)Version 6.0 Differences (357)Version 5 Differences (358)Version 4 Differences (359)Version 3.4 Differences (361)Version 3.2 Differences (362)Version 3.0 Differences (363)Version 2 Differences (364)Appendix C. Writing Optimum Code (367)Memory Model (367)Variable Location (369)Variable Size (369)Unsigned Types (370)Local Variables (370)Other Sources (370)Appendix D. Compiler Limits (371)Appendix E. Byte Ordering (373)Appendix F. Hints, Tips, and Techniques (375)Recursive Code Reference Error (375)Problems Using the printf Routines (376)Uncalled Functions (377)Using Monitor-51 (377)Trouble with the bdata Memory Type (378)Function Pointers (379)Glossary (383)Index (391)࢒ጙᐺ஑࿬C语言是一个通用的编程语言它提供高效的代码结构化的编程和丰富的操作符C不是一种大语言不是为任何特殊应用领域而设计它一般来说限制较少可以为各种软件任务提供方便和有效的编程许多应用用C比其他语言编程更方便和有效优化的C x51 C编译器完整的实现了ANSI的C语言标准对8051来说C x51不是一个通用的C编译器它首先的目标是生成针对8051的最快和最紧凑的代码C x51具有C编程的弹性和高效的代码和汇编语言的速度C语言不能执行的操作如输入和输出需要操作系统的支持这些操作作为标准库的一部分提供因为这些函数和语言本身无关所以C特别适合对多平台提供代码既然C x51是一个交叉编译器C语言的某些方面和标准库就有了改变或增强以适应一个嵌套的目标处理器的特性更多的细节参考89页的第三章.语言扩展支持所有的8051变种8051系列是增长最快的微处理器构架之一从不同的芯片厂家提供了400多种芯片新扩展的8051芯片如PHILIPS 8051MX有几M字节的代码和数据空间可被用到大的应用中为了支持这些不同的8051芯片KEIL提供了几种开发工具如下表所列一个新的输出文件格式OMF2允许支持最多16MB代码和数据空间CX51编译器适用于新的PHILIPS 8051MX结构C51编译器A51宏汇编BL51连接器对传统的8051开发工具包括支持32 x64KB 的代码库C51编译器有OMF2输出AX51宏汇编LX51连接器对传统的8051和扩展的8051芯片如DALLAS 390的开发工具包括支持代码库和最多16MB代码和XDATA存储区CX51编译器AX51宏汇编LX51连接器对PHILIPS 8051MX的开发工具支持最多16MB 代码和XDATA存储区C x 51编译器在不同的包中提供上表是完整的8051开发工具参考注意Cx51指两种编译器C51编译器和CX51编译器C 语言的书有许多书介绍C 语言有更多的书详细介绍用C 完成的任务下面的列表不是一个完整的列表列表只是作为参考The C Programming Language, Second Edition Kernighan & RitchiePrentice-Hall, Inc.ISBN 0-13-110370-9C: A Reference Manual, Second EditionHarbison & SteelPrentice-Hall Software SeriesISBN 0-13-109810-1C and the 8051: Programming and MultitaskingSchultzP T R Prentice-Hall, Inc.ISBN 0-13-753815-4࢒औᐺ፿Cx51ܠፉ໭ܠፉ本章说明怎样编译C源文件讨论编译器的控制命令这些命令可以命令C x51编译器产生列表文件控制包含在OBJ文件中的信息的数量指定优化级别和存储模式注意一般来说你应在µVision2 IDE中使用Cx51关于使用µVision2IDE的更多信息参考用户手册Getting Started with µVision2 and C51”.环境变量如果在µVision2IDE中运行Cx51编译器计算机不需要另外的设置如果想要在命令行中运行C x51编译器和工具必须手工创建下面的环境变量PATH\C51\BIN C51和CX51可执行程序的路径TMP编译器产生的临时文件的路径如果指定的路径不存在编译器会生成错误并停止编译C51INC\C51\INC Cx51头文件的路径C51LIB\C51\LIB Cx51库文件的路径对WINSOWS NT WINDOWS 2000和WINDOWS XP这些环境变量在Control Panel –System – Advanced – Environment Variables中输入对WINDOWS 95WINDOWS 98和WINDOWS ME这些设置放在AUTOEXEC.BAT中PATH=C\KEIL\C51\BIN;%PATH%SET TMP=D:\SET C51INC=C:\KEIL\C51\INCSET C51LIB=C:\KEIL\C51\LIB从命令行运行Cx51调用C51或CX51编译器在命令行输入C51或CX51在命令行中必须包含要编译的C源文件和必需的编译控制命令C x51命令行的格式C51 sourcefile [directives…]CX51 sourcefile [directives…]或C51 @commandfileCX51 @commandfile这里sourcefile要编译的源文件名directives用来控制编译器功能的命令参考20页的控制命令commandfile包含源文件名和命令的命令输入文件当C x51调用行较复杂超过了WINDOWS命令行的限制时使用commandfile下面的命令行例子调用C51指定源文件SAMPLE.C用控制DEBUG CODE和PREPRINTC51 SAMPLE.C DEBUG CODE PREPRINTC x51编译器在成功编译后显示下面的信息C51 COMPILER V6.10C51 COMPILATION COMPLETE. 0 WARNING S0 ERROR S错误级别在编译后错误和警告的数目输出在屏幕上C x51编译器设置ERRORLEVEL指示编译的状态值如下表所列0没有错误或警告1只有警告2错误和可能的警告3致命错误可以在批处理文件中访问ERRORLEVEL变量关于ERRORLEVEL或批处理文件可以参考WINDOWS命令索引或在线帮助Cx51输出文件C x51编译器在编译时产生许多输出文件缺省的输出文件和源文件同名但文件的扩展名不同下面的表列出了文件并有简短的说明Filename.LST列表文件包含格式化的源文件和编译中检测到的错误列表文件可以选择包含所用的符号和生成汇编代码更多的信息参考PRINT命令Filename.OBJ包含可重定位目标代码的OBJ模块OBJ模块用Lx51连接器连接到一个绝对的OBJ模块Filename.I包含由预处理器扩展的源文件所有的宏都扩展了所有的注释都删除了可参考PREPRINT命令Filename.SRC C源代码产生的汇编源文件可以用A51汇编可参考SRC命令控制命令C x51编译器提供许多控制命令控制编译除了指定的命令由一个或多个字母或数字组成在命令行中在文件名后指定或在源文件中用#pragma命令例如C51 testfile.c SYMBOLS CODE DEBUG#pragma SYMBOLS CODE DEBUG在说明的例子中SYMBOLS CODE和DEBUG都是控制命令testfile.C是要编译的源文件注意对命令行和#pragma语法是相同的在#pragma可指定多个选项典型的每个控制命令只在源文件的开头指定一次如果一个命令指定多次编译器产生一个致命错误退出编译可以指定多次的命令在下面部分注明命令种类控制命令可以分成三类源文件控制目标控制和列表控制源文件控制定义命令行的宏定义要编译的文件名目标控制影响产生的目标模块*.OBJ的形式和内容这些命令指定优化级别或在OBJ文件中包含调试信息列表控制管理列表文件*.LST的各种样式特别是格式和指定的内容上下表按字母顺序列出了控制命令有下划线的字母表示命令的缩写AREGS NOAREGS Object 使能或不使能绝对寄存器ARn 地址ASM ENDASM Source 标志内嵌汇编块的开始和结束BROWSE †Object 产生浏览器信息CODE †Listing 加一个汇编列表到列表文件COMPACT †Object 设置COMPACT 存储模式COND NOCOND †Listing 包含或执行预处理器跳过的源程序行DEBUG †Object 在OBJ 文件中包含调试信息DEFINE Source 在Cx51调用行定义预处理器名DISABLE Object 在一个函数内不允许中断EJECTListing 在列表文件中插入一个格式输入字符FLOATFUZZY Object 在浮点比较中指定位数INCDIR †Source 指定头文件的附加路径名INTERVAL †Object 对SIECO 芯片指定中断矢量间隔INTPROMOTE NOINTPROMOTE†Object 使能或不使能ANSI 整数同时提升INTVECTOR NOINTVECTOR †Object 指定中断矢量的基地址或不使能矢量LARGE †Object 选择LARGE 存储模式LISTINCLUDE Listing 在列表文件中显示头文件MAXAREGS †Object 指定可变参数列表的大小MOD517NOMOD517Object 使能或不使能代码支持80C517和派生的额外的硬件特征MODA2NOMODA2Object 使能或不使能ATMEL 82x8252和变种的双DPTR 寄存器MODAB2NOMODAB2Object 使能或不使能模拟设备ADuC B2系列支持双DPTR 寄存器MODDA NOMODDA Object 使能或不使能DALLAS 80C39080C400和5240支持算法加速器MODDP2NOMODDP2Object 使能或不使能DALLAS 的320520530550和变种支持双DPTR 寄存器MODP2NOMODP2Object 使能或不使能PHILIPS 和ATMELWM 派生的支持双DPTR 寄存器NOAMAKE †Object 不记录µVision2更新信息NOEXTEND †Source Cx51不扩展到ANSI COBJECT NOOBJECT †Object 指定一个OBJ 文件或禁止OBJ 文件OBJECTEXTEND†Object 在OBJ 文件中包含变量类型信息ONEREGBANKObject假定在中断中只用寄存器组0OMF2†Object 产生OMF2输出文件格式OPTIMIZE Object 指定编译器的优化级别ORDER †Object 按源文件中变量的出现顺序分配PAGELENGTH †Listing 指定页的行数PAGEWIDTH †Listing 指定页的列数PREPRINT †Listing 产生一个预处理器列表文件扩展所有宏PRINTNOPRINT †Listing 指定一个列表文件名或不使能列表文件REGFILE †Object 对全局寄存器优化指定一个寄存器定义文件REGISTERBANK Object 为绝对寄存器访问选择寄存器组REGPARMS NOREGPARMS Object 使能或不使能寄存器参数传递RET_PSTK † RET_XSTK †Object 用重入堆栈保存返回地址ROM †Object AJMP/ACALL 指令产生控制SAVERESTORE Object 保存和恢复AREGS REGPARMS 和OPTIMIZE 命令设置SMALL†Object 选择SMALL 存储模式缺省SRC †Object 产生一个汇编源文件不产生OBJ 模块STRING †Object 定位固定字符串到XDATA 或远端存储区SYMBOLS †Listing 模块中所有符号的列表文件USERCLASS †Object 对可变的变量位置重命名存储区类VARBANKING †Object 使能FAR 存储类型变量WARNINGLEVEL†Listing 选择警告检测级别XCROM †Object对CONST XDATA 变量假定ROM 空间† 这些命令在命令行或源文件开头的#pragma中只指定一次在一个源文件中不能使用多次控制命令和参数除了用DEFINE 命令的参数是大小写无关的参考本章的余下部分按字母顺序描述C x51编译器控制命令他们分成如下部分缩写可以替代命令的缩写参数命令可选和要求的参数缺省命令的缺省设置µVision2控制怎样指定命令说明详细的说明命令和使用参考相关命令例子命令使用的例子有时也列出结果AREGS/NOAREGS缩写无参数无缺省AREGSµVision2控制Options – C51 – Don‘t use absolute register access说明AREGS控制使编译器对寄存器R0到R7用绝对寄存器地址绝对地址提高了代码的效率例如PUSH和POP指令只能用直接或绝对地址用AREGS命令可以直接PUSH或POP寄存器可用REGISTERBANK命令定义使用的寄存器组NOAREGS命令对寄存器R0到R7不使能绝对寄存器地址用NOAREGS编译的函数可以使用所有的8051寄存器组命令可用在被别的函数用不同的寄存器组调用的函数中注意虽然可能在一个程序中定义了几次AREGS/NOAREGS选项只有定义在函数声明为有效例子下面是一个使用NOAREGS 和AREGS 的源程序和代码的列表注意保存R7到堆栈中的不同方法函数noaregfunc 产生的代码是MOV A R7PUSHACC同时对aregfunc 函数的代码是PUSHAR7stmt levelsource1extern char func ();2char k;34#pragma NOAREGS 5noaregfunc (){61k =func ()+func ();71}89#pragma AREGS 10aregfunc (){111k =func ()+func ();121};FUNCTION noaregfunc (BEGIN);SOURCE LINE #60000120000E LCALL func 0003EF MOV A,R70004C0E0PUSH ACC 0006120000E LCALL func 0009D0E0POP ACC 000B 2F ADD A,R7000C F500R MOV k,A;SOURCE LINE #7000E22RET;FUNCTION noaregfunc (END);FUNCTION aregfunc (BEGIN);SOURCE LINE #110000120000E LCALL func 0003C007PUSH AR70005120000E LCALL func 0008D0E0POP ACC 000A 2F ADD A,R7000B F500R MOV k,A;SOURCE LINE #12000D22RET;FUNCTION aregfunc (END)ASM/ENDASM缩写无参数无缺省无µVision2控制本命令不能在命令行指定说明ASM命令标志一块源程序的开始它可以直接合并到由SRC命令产生的.SRC文件中这些源程序可以认为是内嵌的汇编然而它只输出到由SRC命令产生的源文件中源程序不汇编和输出到OBJ文件中在µVision2应对C源文件中包含ASM/ENDASM段如下设置一个文件指定选项右键点击PROJECT窗口 – 文件表中的文件选择Options for…打开选项 – 属性页使能Generate Assembler SRC file使能Assemble SRC file用这些设置µVision2产生一个汇编源文件.SRC并用汇编编译产生一个OBJ文件.OBJENDASM命令标志一个源程序块的结束注意ASM和ENDASM命令只能在源文件中使用且作为#pragma命令的一部分例子#pragma asm / #pragma endasm 下面是C 源文件产生下面的.SRC 文件...stmt levelsource1extern void test ();23main (){41test ();5161#pragma asm 71JMP $;endless loop 81#pragma endasm 91}..;ASM.SRC generated from:ASM.C NAME ASM PRmainASM SEGMENT CODE EXTRN CODE (test)EXTRN CODE (?C_STARTUP)PUBLIC main;extern void test ();;;main (){RSEG ?PR?main?ASM USING 0main:;SOURCE LINE #3;test ();;SOURCE LINE #4LCALL test;;#pragma asmJMP $;endless loop;#pragma endasm ;};SOURCE LINE #9RET ;END OF mainENDBROWSE缩写BR参数无缺省不创建浏览信息µVision2控制Options – Output – Browse Information说明用BROWSE编译器产生浏览信息浏览信息包括标识符包含预处理器符号他们的存储空间类型定义和参考列表信息可以在µVision2内显示选择View – Source Browser打开µVision2源浏览器参考µVision2用户手册第四章µVision2功能源浏览器例子C51 SAMPLE.C BROWSE#pragma browseCODE缩写CD参数无缺省不产生汇编代码列表µVision2控制Options – Listing – C Compiler Listing – Assembly Code说明CODE命令附加一个汇编助记符列表到列表文件汇编程序代码代表源程序中的每个函数缺省的在列表文件中没有汇编代码例子C51 SAMPLE.C CD#pragma code下面例子显示C源程序和它产生的OBJ结果代码和助记符在汇编间显示了产生代码的行号字符R和E代表可重定位和外部的stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61c=14+15*((b/c)+252);71}...ASSEMBLY LISTING OF GENERATED OBJECT CODE;FUNCTION main(BEGIN);SOURCE LINE#5;SOURCE LINE#60000E500E MOV A,b00028500F0R MOV B,c000584DIV AB000675F00F MOV B,#0FH0009A4MUL AB000A24D2ADD A,#0D2H000C F500R MOV c,A;SOURCE LINE#7000E22RET;FUNCTION main(END)COMPACT缩写CP参数无缺省SMALLµVision2控制Options – Target – Memory Model说明本命令选择COMPACT存储模式在COMPACT存储模式中所有的函数和程序变量和局部数据段定位在8051系统的外部数据存储区外部数据存储区可有最多256字节一页在本模式中外部数据存储区的短地址用@R0/R1不管什么存储类型可以在任何8051的存储范围内声明变量但是把常用的变量如循环计数器和数组索引放在内部数据存储区可以显著的提高系统性能注意函数调用所用的堆栈经常放在IDATA存储区参考SAMLL LARGE ROM例子C51 SAMPLE.C COMPACT#pragma compactCOND/NOCOND缩写CO参数无缺省CONDµVision2控制Options – Listing – C Compiler Listing - Conditional说明本命令定义这些部分的受条件编译影响的源程序是否显示在列表文件中COND命令在列表文件中包含编译省略的行行号和嵌套级不输出以便于阅读本命令影响预处理器删除的行NOCOND命令不在列表文件中包含编译省略的行例子下面的例子显示用COND命令编译产生的一个列表文件...stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61#if defined(VAX)c=13;#elif defined(__TIME__)91b=14;101a=15;111#endif121}..下面的例子用NOCOND命令编译产生的一个列表文件...stmt level source1extern unsigned char a,b;2unsigned char c;34main()5{61#if defined(VAX)91b=14;101a=15;111#endif121}...缩写DB参数无缺省不产生调试信息µVision2控制Options – Output – Debug Information说明DEBUG命令指示编译器在OBJ文件中包含调试信息缺省OBJ 文件不包含调试信息对程序的符号测试必需有调试信息信息包括全局和局部变量定义和地址和函数名和行号包含在目标模块中的调试信息在连接过程中仍有效这些信息可以被µVision2调试器或任何INTEL兼容的模拟器使用注意OBJECTEXTEND命令用来指示编译器在目标文件中包含附加的变量类型定义信息参考OBJECTEXTEND例子C51 SAMPLE.C DEBUG#pragma db缩写DF参数一个或多个符合C语言约定的的名称用逗号分隔对每个名称可有一个参数用DEFINE给出缺省无µVision2控制在Options –C x51 – Define输入名称说明DEFINE命令定义调用行的名称预处理器要用#if#ifdef和#ifndef查询这些名称定义的名称在输入后被复制这些命令是大小写相关的作为一个选项每个名称可跟一个值注意DEFINE命令只能在命令行中指定在一个C源程序中用C预处理器命令#define例子C51 SAMPLE.C DEFINE check,NoExtRamC51 MYPROG.C DF (X1=“1+5”,iofunc=“getkey()”)DISABLE缩写无参数无缺省无µVision2控制本命令不能在命令行中指定只能在源文件中指定说明DISABLE命令指示编译器在产生代码时在一个函数内不使能所有中断DISABLE必须在一个函数声明前一行用#pragma命令指定DISABLE控制只用到一个函数对每个新的函数必须重新指定注意DISABLE只能用#pragma命令指定不能在命令行指定DISABLE可在一个源文件中指定多次对每个函数只能指定一次执行后不使能中断一个不使能中断的函数不能对调用者返回一个位值例子本例子是一个用DISABLE命令函数的源程序和代码列表注意EA指定函数寄存器在函数进入时清除JBC EA C002在结尾时恢复MOV EA C...stmt level source1typedef unsigned char uchar;23#pragma disable/*Disable Interrupts*/4uchar dfunc(uchar p1,uchar p2){51return(p1*p2+p2*p1);61};FUNCTION_dfunc(BEGIN)0000D3SETB C000110AF01JBC EA,?C00020004C3CLR C0005?C0002:0005C0D0PUSH PSW;----Variable'p1'assigned to register'R7'----;----Variable'p2'assigned to register'R5'----;SOURCE LINE#4;SOURCE LINE#50007ED MOV A,R500088FF0MOV B,R7000A A4MUL AB000B25E0ADD A,ACC000D FF MOV R7,A;SOURCE LINE#6000E?C0001:000E D0D0POP PSW001092AF MOV EA,C001222RET;FUNCTION_dfunc(END)...EJECT缩写EJ参数无缺省无µVision2控制本命令不能在命令行中指定只能在源文件中指定说明EJECT命令在列表文件中插入一个格式输入字符注意EJECT只在源文件中出现必须是#pragma命令的一部分例子#pragma ejectFLOATFUZZY缩写FF参数0到7间的一个数字缺省FLOATFUZZY3µVision2控制Options - C x51 – Bits to round for float compare说明FLOATFUZZY命令在一个浮点比较前定义位数缺省值3指定最少有三个有效位例子C51 MYFILE.C FLOATFUZZY2#pragma FF(0)INCDIR缩写无参数指定头文件的路径缺省无µVision2控制Options - C x51 – Include Paths说明INCDIR命令指定Cx51编译器头文件的位置编译器最多50个路径声明如果需要多个路径路径名必须用分号分开如果指定#include“filename.h”Cx51编译器首先搜索当前目录然后是源文件目录当找不到或用了#include <filename.h>就搜索INCDIR指定的路径当仍找不到就使用C51INC环境变量指定的路径例子C51 SAMPLE.C INDIR C\KEIL\C51\MYINC;C:\CHIP-DIRINTERVAL缩写无参数对中断矢量表可选用括号括住缺省INTERV AL8µVision2控制Options - C x51 – Misc controls:enter the directive说明INTERV AL命令指定中断矢量的间隔指定间隔是SIECO-51派生系列要求的它定义中断矢量在3字节间隔用本命令编译器定位中断矢量在绝对地址如下计算(interval×n)+offset+3,这里interval INTERV AL命令的参数缺省为8n中断号offset INTVECTOR命令的参数缺省为0参考INTVECTOR/NOINTVECTOR例子C51 SAMPLE.C INTERV AL3#pragma interval(3)INTPROMOTE/NOINTPROMOTE缩写IP/NOIP参数无缺省INTPROMOTEµVision2控制Options - C x51 – Enable ANSI integer promotion rules说明INTPROMOTE命令使能ANSI整数提升规则如果提升声明了在比较前所用的表达式从小类型提升到整数表达式这使MICROSOFT C和BORLAND C改动很少就可用到Cx51上因为8051是8位处理器使用INTPROMOTE命令可能在某些应用中降低效率NOINTPROMOTE命令不使能自动整数提升整数提升使Cx51和别的ANSI编译器间有更大的兼容性然而整数提升可能降低效率例子C51 SAMPLE.C INTPROMOTE#pragma intpormoteC51 SAMPLE.C NOINTPROMOTE下面的代码示范用INTPROMOTE和NOINTPROMOTE命令产生的代码stmt lvl source1char c;2unsigned char c1,c2;3int i;45main(){61if(c==0xff)c=0;/*never true!*/71if(c==-1)c=1;/*works*/81i=c+5;91if(c1<c2+4)c1=0;101};FUNCTION main(BEGIN);SOURCE LINE#60000AF00MOV R7,c0002EF MOV A,R7000333RLC A000495E0SUBB A,ACC0006FE MOV R6,A0007EF MOV A,R70008F4CPL A00094E ORL A,R6000A7002JNZ?C0001000C F500MOV c,A000E?C0001:;SOURCE LINE#7000E E500MOV A,c0010B4FF03CJNE A,#0FFH,?C0002 0013750001MOV c,#01H0016?C0002:;SOURCE LINE#80016AF00MOV R7,c0018EF MOV A,R7001933RLC A001A95E0SUBB A,ACC001C FE MOV R6,A001D EF MOV A,R7001E2405ADD A,#05H0020F500MOV i+01H,A0022E4CLR A00233E ADDC A,R60024F500MOV i,A;SOURCE LINE#90026E500MOV A,c200282404ADD A,#04H002A FF MOV R7,A002B E4CLR A002C33RLC A002D FE MOV R6,A002E C3CLR C002F E500MOV A,c100319F SUBB A,R70032EE MOV A,R600336480XRL A,#080H0035F8MOV R0,A00367480MOV A,#080H003898SUBB A,R000395003JNC?C0004003B E4CLR A003C F500MOV c1,A;SOURCE LINE#10003E?C0004:003E22RET;FUNCTION main(END);FUNCTION main(BEGIN);SOURCE LINE#60000AF00MOV R7,c0002EF MOV A,R7000333RLC A000495E0SUBB A,ACC0006FE MOV R6,A0007EF MOV A,R70008F4CPL A00094E ORL A,R6000A7002JNZ?C0001000C F500MOV c,A000E?C0001:;SOURCE LINE#7000E E500MOV A,c0010B4FF03CJNE A,#0FFH,?C0002 0013750001MOV c,#01H0016;SOURCE LINE#80016E500MOV A,c00182405ADD A,#05H001A FF MOV R7,A001B33RLC A001C95E0SUBB A,ACC001E F500MOV i,A00208F00MOV i+01H,R7;SOURCE LINE#90022E500MOV A,c200242404ADD A,#04H0026FF MOV R7,A0027E500MOV A,c10029C3CLR C002A9F SUBB A,R7002B5003JNC?C0004002D E4CLR A002E F500MOV c1,A;SOURCE LINE#100030?C0004:003022RET;FUNCTION main(END)CODE SIZE = 63 Bytes CODE SIZE = 49 BytesINTVECTOR/NOINTVECTOR缩写IV/NOIV参数对中断矢量表一个可选的偏移在括号中缺省INTVECTOR0µVision2控制Options - C x51 – Misc controls:enter the directive说明INTVECTOR命令指示编译器对要求的函数产生中断矢量如果矢量表不从0开始需输入一个偏移用本命令编译器产生一个中断矢量入口根据ROM命令指定的程序存储区用AJMP或LJMP指令跳转NOINTVECTOR命令禁止产生中断矢量表这也许用户用别的编程工具提供中断矢量编译器通常用一个3字节跳转指令LJMP产生一个中断矢量矢量用绝对地址表示(interval × n) + offset + 3,这里n中断号interval INTERV AL命令的参数缺省为8offset INTVECTOR命令的参数缺省为0参考INTERV AL。

第5章 Cx51构造数据类型(4学时)

第5章 Cx51构造数据类型(4学时)

2 枚举变量的取值 p122
如果有 enum direct {up,down,left=10,right}; 则有
clerk1.birthday.year=1957;
//只能给最后一级的成员赋值
floatsum=clerk1.wages+cle rk2.wages;
5.3.2 结构数组
也可定义为: struct{ struct string{ char char name[8]; name[8]; char sex[2]; char sex[2]; int age; int age; char addr[40]; char }; addr[40]; struct string student[40]; }student[40 ];


1.指针变量定义 类型标识符 *指针名1, *指针名2,…; *表示变量为指针变量;

int a,b,c; int *ap,*bp,*cp; 编译后变量定位
变量赋值
a=6; b=8; c=10; 编译后
2.指针变量的引用(赋值)
ap=&a;
ap=&b;
ap=&c;
例 p110
注意:
1)p109
最后一行应是 *(p+1)+3; 2) p110 第一行应是 *(*(p+1)+3); 3) p110 第3-4行行首都应 加*号;
5.2.4 关于KEIL Cx51的指针 类型 p110-111
1
基于存储器的指针(1-2个字节) char xdata *px; char xdata *data pdx; 上述二者的区别: 1)定义1中指针的存放由编译模式 决定; 2)定义2明确指出指针位于内部存

单片机C语言(C51)的常用库函数

单片机C语言(C51)的常用库函数

C51的常用库函数详解C51语言的编译器中包含有丰富的库函数,使用库函数可以大大简化用户程序设计的工作量,提高编程效率。

每个库函数都在相应的头文件中给出了函数原型声明,在使用时,必须在源程序的开始处使用预处理命令#include将有关的头文件包含进来。

C51库函数中类型的选择考虑到了8051单片机的结构特性,用户在自己的应用程序中应尽可能地使用最小的数据类型,以最大限度地发挥8051单片机的性能,同时可减少应用程序的代码长度。

下面将C51的库函数分类列出并详细介绍其用法。

1 字符函数字符函数的原型声明包含在头文件CTYPE.H中。

常用的一些字符函数介绍如下。

1.1 检查英文字母函数检查英文字母函数用于检查形参字符是否为英文字母,其函数原型如下:bit isalpha(char c);其中,c为待判断的字符,如果是英文字母则返回1,否则返回0。

程序示例如下:1.2 检查字母数字函数检查字母数字函数用于检查形参字符是否为英文字母或数字字符,其函数原型如下:bit isalnum(char c);1.3 检查控制字符函数检查控制字符函数用于检查形参字符是否为控制字符,其函数原型:bit iscntrl (char c);其中,c为待判断的字符。

控制字符其取值范围为0x00~0xlF之间或等于0x7F,如果是,则返回1,否则返回0。

1.4 十进制数字检查函数十进制数字检查函数用于检查形参字符是否为十进制数字,其函数原型如下:bit isdigit (char c);其中,c为待判断的字符,如果是十进制数字则返回1,否则返回0。

1.5 可打印字符检查函数可打印字符检查函数用于检查形参字符是否为可打印字符,其函数原型如下:bit isgraph (char c);其中,c为待判断的字符。

可打印字符的取值范围为0x21~0x7C,不包含空格,如果是可打印字符则返回1,否则返回0。

1.6 包含空格的可打印字符检查函数包含空格的可打印字符检查函数用于检查形参字符是否为可打印字符以及空格,其函数原型如下:bit isprint (char c);其中,c为待判断字符。

单片机ch5Cx51构造数据类型

单片机ch5Cx51构造数据类型

当用指针来引用结构或联合的成员时,可用如下方法: time_ptr->days=234; *time_ptr.hour=12;
数组指针和指向数组的指针变量
指针既可以指向变量,也可以指向数组。
数组的指针:数组的起始地址; 指向数组的指针变量:用于存放数组起始位置的变量。
1、指向数组的指针变量定义、引用和赋值
int a[]={1,2,3,4,5};
二维数组
1、二维数组的定义方式
二维数组说明的一般形式是: 类型说明符 存储类型 数组名[常量表达式1][常量表达式2]…;
常量表达式1——第一维下标的长度, 常量表达式2 ——第二维下标的长度 例如: int a[3][4]; 说明了一个三行四列的数组,数组名为a,其下标变量的类 型为整型。
数组与存储空间
当程序中设定了一个数组后,C编译器就会 在系统的存储空间开辟一个区域用于存储该数组 的内容。
对于字符数组而言,数据占据了存储器中一 串连续的字节位置。对于其它数组,如整形(int) 数组,将在存储区占据一串连续的双字节位置, 由此类推。
对于多维数组来说,一个10x10x10的三 维浮点数组需要大约4k的存储空间。一般情况 下数组存储空间不能大于64k。
1、一维数组的定义方式
数组说明的一般形式为: 类型说明符 存储类型 数组名[常量表达式],……;
➢类型说明符——任一种基本数据类型或构造数据类型。 ➢数 组 名——用户定义的数组标识符。 ➢常量表达式——数据元素的个数,也称为数组的长度。
例如:
int data a[10]; 说明整型数组a,有10个元素。
int data a [3][3]={ { 0, 1 }, { 0, 0, 2 },{ 3 } }; 赋值后的元素值为 0 1 0 0 0 2 3 0 0

Cx51流程控制语句

Cx51流程控制语句

P为真? 为真? 为真
利用选择结构, 利用选择结构,我们可以做一些典型的智能判 断工作,比如: 断工作,比如: 1、依靠条件选择开关,打开或者关闭水泵; 、依靠条件选择开关,打开或者关闭水泵; 2、如果上面的工作重复操作了22次,那么执行 、如果上面的工作重复操作了 次 下面另一个操作; 下面另一个操作; 3、连续监测一个信号,这个信号指示语言芯片可 、连续监测一个信号, 以接受下一个字的代码; 以接受下一个字的代码; ……
其中表达式是while语句能否继续的条件,而语句部分 语句能否继续的条件, 其中表达式是 语句能否继续的条件 则是循环体,用来完成某些任务。 则是循环体,用来完成某些任务。 只要表达式为真,就重复执行其中的循环体, 只要表达式为真,就重复执行其中的循环体,直到表 达式结果为假时,中断这个循环,继续执行循环体之外的 达式结果为假时,中断这个循环, 其它任务。 其它任务。 若表达式一开始就是假的, 若表达式一开始就是假的,那么就没有机会执行循环 体内的任务;反之加入表达式一直为真, 体内的任务;反之加入表达式一直为真,那么就不会从循 环体跳出,出现死循环。 环体跳出,出现死循环。
4.2.1 选择语句 选择语句if
C语言的一个基本判断 条件选择 语句就是 语言的一个基本判断(条件选择 语句就是if 语言的一个基本判断 条件选择)语句就是 语句,它是串行多分子结构的关键语句, 语句,它是串行多分子结构的关键语句,它的基本 结构如下所示: 结构如下所示: if(表达式 表达式) 表达式 {语句 语句;} 语句 else if(表达式 表达式) 表达式 {语句 语句;} 语句 else {语句 语句;} 语句 //基本条件判断 基本条件判断 //基本任务 基本任务 //补充条件 可选 补充条件(可选 补充条件 可选) //补充条件下的任务 补充条件下的任务 //条件之外情况 可选 条件之外情况(可选 条件之外情况 可选) //条件之外任务 条件之外任务
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

设n=5,求5!的过程如下:
例如,在上图中5!转化了6次后,0!=1。也就是说,必须有一 个递归结束的条件。
3、递归调用的过程
递归调用的过程可分为如下两个阶段:
第一阶段称为“递推”,将原问题不断地分解为新问题,逐
渐地从未知的方向,向已知的方向推测,最终达到递归结束条 件。这时递推阶段结束。
第二个阶段称为“回归”,从递归结束条件出发,按照递推
6.2 函数的定义
1、无参函数的定义
返回值类型 函数名( ) {函数体语句}
如果函数没有返回值,可以将返回值类型设为void。
2、有参函数的定义
返回值类型 函数名 (形式参数列表 ) { 函数体语句 return(返回参数名) }
3、空函数的定义
返回值类型 函数名 ( ) { }
6.3 函数的参数和函数值
6.1 函数的分类
从用户使用角度划分,函数分为库函数和用户自定义函数。
1、标准库函数 标准库函数是编译系统为用户设计的一系列标准函 数,用户只需调用,而无需自己去编写这些复杂的函数。 如前面所用到的头文件reg51.h、absacc.h等,有 的头文件中包括一系列函数,要使用其中的函数必须先 使用#include包含语句,然后才能调用。
此时get函数中的a, b应为实参,其以返回值参予式中的运算。 ③ 被调函数作为另一个函数的实际参数
如, m=max ( a, get ( a, b) );
函数get ( a, b )作为函数max()的一个实际参数。
6.4.3 对被调函数的说明
如果被调函数出现在主调函数之后,在主调函数前应对被 调函数作以说明,形式为: 返回值类型 被调函数名(形参表列); 如果被调函数出现在主调函数之前,可不对被调函数说明。
main(){ Int max(),min(),add(); Int a=6,b=2; printf(“a=%d b=%d \n”,a,b); printf(“max=”); process(a,b,max); printf(“min=”); process(a,b,min); printf(“sum=”); process(a,b,add); } max(intx,inty){ Int z; If(x>y) z=x; else z=y; return(z); }
一个函数可以有一个以上的return语句。但每次调用只 能有一个返回值。
(1)函数返回值的类型一般在定义函数时,用返回类型标 识符指定。
(2)C语言规定,凡是不加返回类型标识符说明的函数, 都按整型(int)来处理。 (3)如果函数返回类型说明和return语句中的表达式的变 量类型不一致,则以函数返回类型标识符为标准进行强制类 型转换。 (4)如果函数不要求返回结果,一般都被定义为void函数。
第 6 章 Cx51 函 数
6.1 函数的分类 6.2 函数的定义 6.3 函数的参数和函数值 6.4 函数的调用 6.5 数组、指针作为函数的参数
模块化程序设计


基本思想:将一个大的程序按功能分割成一些小模 块 特点:




各模块相对独立、功能单一、结构清晰、接口简单 控制了程序设计的复杂性 提高元件的可靠性 缩短开发周期 避免程序开发的重复劳动 易于维护和功能扩充
main( ) { struct record note; note.number = 3361; = “vgk”; note.score[ 0 ] = 11.25; note.score[ 1 ] = 43.34; note.score[ 2 ] = 56.67;
show( &note ); }
2、用户自定义函数 用户自定义函数是用户根据任务编写的函数。 从函数定义的形式上分为:无参函数、有参函数和空函数。 无参函数——在调用此种函数时,既无参数输入,也不 返回结果给调用函数。 有参函数——在调用此种函数时,用实际参数代替形式 参数,调用完返回结果给调用函数。 空函数——此种函数内没有语句,是空白。
返回地址
函数的返回值是在被调用时, 通过返回语句来实现 的. 返回语句的一般格式为: return <表达式> ;
return语句的执行过程如下: 先计算出<表达式>的值. 若<表达式>的值的类型与函数的类型不同,将<表
达式>的类型强制转换为函数的类型.
将表达式的值返回给调用函数. 将程序的控制权由被调用函数转给调用函数.
6.5.3 用指向结构的指针变量作为函数的参数
含义:用指向结构变量的指针变量作实际参数,将结构变 量的地址传递给被调用函数的形式参数。 例:分析以下的程序
struct record { int number; char name[20]; float score[3]; } void show ( struct record *p ) { int i; printf ( “ note.number = %d/n”, p-> number ); printf ( “ note.number = %s/n”, p-> name ); for ( i = 1; i< 3; i++ ) { printf ( “ note.score[ %d ] = %f/n”, i, p-> score[ i ] ); } }
(1)形参、实参都用数组名 (2)形参、实参都用指针变量 (3)形参用指针变量、实参用数组名 (4)形参用数组名、实参用指针变量
例:将数组a中n个整数按逆序存放
void inv ( int a[ ], int n) { int t,i; for(i=0;i<(n-1)/2;i++) { t=a[i]; a[i]=a[n-1-i]; a[n-1-i]=t; } } main( ) { int i,a[10]; for(i=0;i<10;i++) scanf("%d",&a[i]); inv(a,10); for(i=0;i<10;i++) printf("%4d",a[i]); }

开发方法: 自上向下,逐步分解,分而治之

C是模块化程序设计语言
C程序
源程序文件1
源程序文件i
源程序文件n
预编译命令
函数1
函数n
说明部分
执行部分
C51程序结构 C51是函数式语言 必须有且只能有一个名为main的主函数 C程序的执行总是从main函数开始,在main中结束 函数不能嵌套定义,可以嵌套调用
3、用函数的指针变量调用函数的方法
用函数指针变量调用函数时,只需将(*p)代替函数 名即可(p为指针变量名),在(*p)之后的括弧中根据 需要写上实参。
(*p)( 实 参 )
6.5 数组、指针作为函数的参数
6.5.1 用数组作为函数的参数
数组名作形参时,接收实参数组的起始地址; 作实参时,将数组的起始地址传递给形参数组。 引入指向数组的指针变量后,数组及指向数组的指针变量作 函数参数时,可有4种等价形式:
6.4 函数的调用
6.4.1 函数调用的一般形式
函数调用的形式为: 函数名(实际参数表列);
6.4.2 函数调用的方式 函数的调用方式有三种:
① 函数调用语句 即把被调函数名作为调用函数的一个语句; 如:fun1( )。
② 被调函数作为表达式的运算对象
如, result=2 * get ( a, b )
例 有一个数据档案记录,每个记录中含有四项数据,要求用返回指针的 函数来实现。 程序如下:
float *view(float(pp)[4],int j){ float *pt; pt=*(pp+j); return(pt); } main(){ float score[][4]={ {8.87,8.83,8.64,8.91}, {12.11,12.23,12.34,12.20}, {30.44,30.66,30.58,30.40}, {20.12,20.08,20.21,20.66}}; float *view; float *p; int I,n=2; printf(“the record of NO. %d are:\n”,n); p=view(score,n); for(i=0;i<4;i++) printf(“%5.2f\t”,*(p+i)); }
6.4.4 函数的嵌套调用
嵌套调用——指一个函数调用A函数,A函数的函数体中 又调用B函数。
6.4.5 函数的递归调用
1、递归调用的定义
函数的递归调用是指一个函数直接或间接地调用自己。
例:在函数f1( )中又有调用f1 )的语句,这称为直接递归调用。
2、递归调用的条件
在解决实际问题时,能否用递归的方法来解决,取决 于问题自身的特点。某一问题要用递归的方法来解决,需 满足以下条件: 原问题可转化为一个新问题,而这个新问题与原问题有 相同的解决方法。 新问题可继续这种转化。在转化过程中问题有规律的递 增或递减。 在有限次转化后,问题得到解决。
int fun1(int a, int b) { int c; c=a+b; return(c); } main() { int d, u = 3, v = 2; d = 2 * fun ( u, v ); }
被调函数在主调函 数前,不用说明。
被调函数在主调函数后, 在前面对被调函数进行说明。
int fun1(a,b); main( ) { int d,u=3,v=2; d=2*func; c=a+b; return(c); }
2、函数指针变量的定义
定义格式为: 函数值类型
( *指针变量)( );
如 float (*pf) ( ); 则标识符pf是一个指针变量,它可以指向函数值为float类 型的任何一个函数,即pf的值可以是函数值为float类型的 任何一个函数在内存的入口地址。 下面有三个函数: float f1( float x, float y) { . . . } float f2( float x) { . . . } long f3( int x, int y) { . . . } 那么 pf=f1; pf=f2; 都是正确的赋值语句, 但 pf=f3; 则是不正确的。
相关文档
最新文档