资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第,10,章 单片机,C,语言程序设计,10.1 C,语言与,MCS-51,单片机,10.1.1 C,语言的特点及程序结构,一,C,语言的特点,1,语言简洁、紧凑,使用方便、灵活。,2,运算符丰富。,3,数据结构丰富。具有现代化语言的各种数据结构。,4,可进行结构化程序设计。,5,可以直接对计算机硬件进行操作。,6,生成的目标代码质量高,程序执行效率高。,7,可移植性好。,二,C,语言的程序结构,C,语言程序采用函数结构,每个,C,语言程序由一个或多个函数组成,在这些函数中至少应包含一个主函数,main(),,也可以包含一个,main(),函数和若干个其它的功能函数。不管,main(),函数放于何处,程序总是从,main(),函数开始执行,执行到,main(),函数结束则结束。在,main(),函数中调用其它函数,其它函数也可以相互调用,但,main(),函数只能调用其它的功能函数,而不能被其它的函数所调用。功能函数可以是,C,语言编译器提供的库函数,也可以是由用户定义的自定义函数。在编制,C,程序时,程序的开始部分一般是预处理命令、函数说明和变量定义等。,C,语言程序结构一般如下:,预处理命令,include,函数说明,long fun1();,float fun2();,int x,y;,float z;,功能函数,主函数,功能函数,功能函数,1 fun1(),函数体,主函数,main(),主函数体,功能函数,2 fun2(),函数体,其中,函数往往由“函数定义”和“函数体”两个部分组成。函数定义部分包括有函数类型、函数名、形式参数说明等,函数名后面必须跟一个圆括号(),形式参数在()内定义。函数体由一对花括号“,”,组成,在“,”,的内容就是函数体。如果一个函数内有多个花括号,则最外层的一对“,”,为函数体的内容。函数体内包含若干语句,一般由两部分组成:声明语句和执行语句。声明语句用于对函数中用到的变量进行定义。也可能对函数体中调用的函数进行声明。执行语句由若干语句组成,用来完成一定功能。当然也有的函数体仅有一对“,”,,其中内部既没有声明语句,也没有执行语句。这种函数称为空函数。,C,语言程序在书写时格式十分自由,一条语句可以写成一行,也可以写成几行;还可以一行内写多条语句;但每条语句后面必须以分号“;”作为结束符。,C,语言程序对大小写字母比较敏感,在程序中,同一个字母的大小写系统是作不同的处理。在程序中可以用“,/*/”,或“,/”,对,C,程序中的任何部分作注释,以增加程序的可读性。,C,语言本身没有输入输出语句。输入和输出是通过输入输出函数,scanf(),和,printf(),来实现的。输入输出函数是通过标准库函数形式提供给用户。,10.1.2 C,语言与,MCS-51,单片机,用,C,语言编写,MCS-51,单片机程序与用汇编语言编写,MCS51,单片机程序不一样,用汇编语言编写,MCS51,单片机程序必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能寄存器的使用以及按实际地址处理端口数据。用,C,语言编写的,MCS51,单片机应用程序,则不用像汇编语言那样须具体组织、分配存储器资源和处理端口数据,但在,C,语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确地映射定位。,用,C,语言编写单片机应用程序与标准的,C,语言程序也有相应的区别:,C,语言编写单片机应用程序时,需根据单片机存储结构及内部资源定义相应的数据类型和变量,而标准的,C,语言程序不需要考虑这些问题;,C51,包含的数据类型、变量存储模式、输入输出处理、函数等方面与标准的,C,语言有一定的区别。其它的语法规则、程序结构及程序设计方法等与标准的,C,语言程序设计相同。,现在支持,MCS-51,系列单片机的,C,语言编译器有很多种,如,American Automation,、,Avocet,、,BSO/TASKING,、,DUNFIELD SHAREWARE,、,KEIL/Franklin,等。各种编译器的基本情况相同,但具体处理时有一定的区别,其中,KEIL/Franklin,以它的代码紧凑和使用方便等特点优于其它编译器,现在使用特别广泛。本书以,KEIL/Franklin,编译器介绍,MCS-51,单片机,C,语言程序设计。,10.1.3 C51,程序结构,C51,的语法规定、程序结构及程序设计方法都与标准的,C,语言程序设计相同,但,C51,程序与标准的,C,程序在以下几个方面不一样:,(,1,),C51,中定义的库函数和标准,C,语言定义的库函数不同。标准的,C,语言定义的库函数是按通用微型计算机来定义的,而,C51,中的库函数是按,MCS-51,单片机相应情况来定义的;,(,2,),C51,中的数据类型与标准,C,的数据类型也有一定的区别,在,C51,中还增加了几种针对,MCS-51,单片机特有的数据类型;,(,3,),C51,变量的存储模式与标准,C,中变量的存储模式不一样,,C51,中变量的存储模式是与,MCS-51,单片机的存储器紧密相关;,(,4,),C51,与标准,C,的输入输出处理不一样,,C51,中的输入输出是通过,MCS-51,串行口来完成的,输入输出指令执行前必须要对串行口进行初始化;,(,5,),C51,与标准,C,在函数使用方面也有一定的区别,,C51,中有专门的中断函数。,10.2 C51,的数据类型,C51,的数据类型分为基本数据类型和组合数据类型,情况与标准,C,中的数据类型基本相同,但其中,char,型与,short,型相同,,float,型与,double,型相同,另外,,C51,中还有专门针对于,MCS-51,单片机的特殊功能寄存器型和位类型。,一,字符型,char,有,signed char,和,unsigned char,之分,默认为,signed char,。它们的长度均为一个字节,用于存放一个单字节的数据。对于,signed char,,它用于定义带符号字节数据,其字节的最高位为符号位,“,0”,表示正数,“,1”,表示负数,补码表示,所能表示的数值范围是,-128+127,;对于,unsigned char,,它用于定义无符号字节数据或字符,可以存放一个字节的无符号数,其取值范围为,0255,。,unsigned char,可以用来存放无符号数,也可以存放西文字符,一个西文字符占一个字节,在计算机内部用,ASCII,码存放。,二,int,整型,分,singed int,和,unsigned int,。默认为,signed int,。它们的长度均为两个字节,用于存放一个双字节数据。对于,signed int,,用于存放两字节带符号数,补码表示,数的范畴为,-32768+32767,。对于,unsigned int,,用于存放两字节无符号数,数的范围为,065535,。,三,long,长整型,分,singed long,和,unsigned long,。默认为,signed long,。它们的长度均为四个字节,用于存放一个四字节数据。对于,signed long,,用于存放四字节带符号数,补码表示,数的范畴为,-2147483648+2147483647,。对于,unsigned long,,用于存放四字节无符号数,数的范围为,04294967295,。,四,float,浮点型,float,型数据的长度为四个字节,格式符合,IEEE-754,标准的单精度浮点型数据,包含指数和尾数两部分,最高位为符号位,“,1”,表示负数,“,0”,表示正数,其次的,8,位为阶码,最后的,23,位为尾数的有效数位,由于尾数的整数部分隐含为“,1”,,所以尾数的精度为,24,位。,五*指针型,指针型本身就是一个变量,在这个变量中存放的指向另一个数据的地址。这个指针变量要占用一定的内存单元,对不同的处理器其长度不一样,在,C51,中它的长度一般为,13,个字节。,六特殊功能寄存器型,这是,C51,扩充的数据类型,用于访问,MCS-51,单片机中的特殊功能寄存器数据,它分,sfr,和,sfr16,两种类型,其中,sfr,为字节型特殊功能寄存器类型,占一个内存单元,利用它可以访问,MCS-51,内部的所有特殊功能寄存器;,sfr16,为双字节型特殊功能寄存器类型,占用两个字节单元,利用它可以访问,MCS-51,内部的所有两个字节的特殊功能寄存器。在,C51,中对特殊功能寄存器的访问必须先用,sfr,或,sfr16,进行声明。,七位类型,这也是,C51,中扩充的数据类型,用于访问,MCS-51,单片机中的可寻址的位单元。在,C51,中,支持两种位类型:,bit,型和,sbit,型。它们在内存中都只占一个二进制位,其值可以是“,1”,或“,0”,。其中用,bit,定义的位变量在,C51,编译器编译时,在不同的时候位地址是可以变化的,而用,sbit,定义的位变量必须与,MCS-51,单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位联系在一起,在,C51,编译器编译时,其对应的位地址是不可变化的。,基本数据类型,长度,取值范围,unsigned char,1,字节,0255,signed char,1,字节,-128+127,unsigned int,2,字节,065535,signed int,2,字节,-32768+32767,unsigned long,4,字节,04294967295,signed long,4,字节,-2147483648+2147483647,float,4,字节,1.175494E-38,3.402823E+38,bit,1,位,0,或,1,Sbit,1,位,0,或,1,sfr,1,字节,0255,sfr16,2,字节,065535,在,C51,语言程序中,有可能会出现在运算中数据类型不一致的情况。,C51,允许任何标准数据类型的隐式转换,隐式转换的优先级顺序如下:,bit,char,int,long,float,signed,unsigned,也就是说,当,char,型与,int,型进行运算时,先自动对,char,型扩展为,int,型,然后与,int,型进行运算,运算结果为,int,型。,C51,除了支持隐式类型转换外,还可以通过强制类型转换符“()”对数据类型进行人为的强制转换。,C5l,编译器除了能支持以上这些基本数据类型之外,还能支持一些复杂的组合型数据类型,如数组类型、指针类型、结构类型、联合类型等这些复杂的数据类型,在本书的后面将相继介绍。,10.3 c51,的运算量,10.3.1,常量,常量是指在程序执行过程中其值不能改变的量。在,C51,中支持整型常量、浮点型常量、字符型常量和字符串型常量。,一整型常量,整型常量也就是整型常数,根据其值范围在计算机中分配不同的字节数来存放。在,C51,中它可以表示成以下几种形式:,十进制整数。如,234,、,-56,、,0,等。,十六进制整数。以,0 x,开头表示,如,0 x12,表示十六进制数,12H,。,长整数。在,C51,中当一个整数的值达到长整型的范围,则该数按长整型存放,在存储器中占四个字节,另外,如一个整数后面加一个字母,L,,这个数在存储器中也按长整型存放。如,123L,在存储器中占四个字节。,二浮点型常量,浮点型常量也就是实型常数。有十进制表示形式和指数表示形式。,十进制表示形式又称定点表示形式,由数字和小数点组成。如,0.123,、,34.645,等都是十进制数表示形式的浮点型常量。,指数表示形式为:,数字,.,数字,e,数字,例如:,123.456e-3,、,-3.123e2,等都是指数形式的浮点型常量。,三字符型常量,字符型常量是用单引号引起的字符,如,a,、,1,、,F,等。可以是可显示的,ASCII,字符,也可以是不可显示的控制字符。对不可显示的控制字符须在前面加上反斜杠“,”,组成转义字符。利用它可以完成一些特殊功能和输出时的格式控制。常用的转义字符如表,4-2,所示。,转义字符,含 义,ASCII,码(十六进制数),o,空字符(,null,),00H,n,换行符(,LF,),0AH,r,回车符(,CR,),0DH,t,水平制表符(,HT,),09H,b,退格符(,BS,),08H,f,换页符(,FF,),0CH,单引号,27H,”,双引号,22H,反斜杠,5CH,四字符串型常量,字符串型常量由双引号“”括起的字符组成。如“,D”,、“,1234”,、“,ABCD”,等。注意字符串常量与字符常量是不一样,一个字符常量在计算机内只用一个字节存放,而一个字符串常量在内存中存放时不仅双引号内的字符一个占一个字节,而且系统会自动的在后面加一个转义字符“,o”,作为字符串结束符。因此不要将字符常量和字符串常量混淆,如字符常量,A,和字符串常量“,A”,是不一样的。,10.3.2,变量,变量是在程序运行过程中其值可以改变的量。一个变量由两部分组成:变量名和变量值。,在,C51,中,变量在使用前必须对变量进行定义,指出变量的数据类型和存储模式。以便编译系统为它分配相应的存储单元。定义的格式如下:,存储种类,数据类型说明符,存储器类型,变量名,1=,初值,,变量名,2,初值,;,一数据类型说明符,在定义变量时,必须通过数据类型说明符指明变量的数据类型,指明变量在存储器中占用的字节数。可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是用,typedef,定义的类型别名。,在,C51,中,为了增加程序的可读性,允许用户为系统固有的数据类型说明符用,typedef,起别名,格式如下:,typedef c51,固有的数据类型说明符 别名;,定义别名后,就可以用别名代替数据类型说明符对变量进行定义。别名可以用大写,也可以用小写,为了区别一般用大写字母表示。,【,例,10-1】,typedef,的使用。,typedef unsigned int WORD;,typedef unsigned char BYTE;,BYTE a1=0 x12;,WORD a2=0 x1234;,二变量名,变量名是,C51,区分不同变量,为不同变量取的名称。在,C51,中规定变量名可以由字母、数字和下划线三种字符组成,且第一个字母必须为字母或下划线。变量名有两种:普通变量名和指针变量名。它们的区别是指针变量名前面要带“*”号。,三存储种类,存储种类是指变量在程序执行过程中的作用范围。,C51,变量的存储种类有四种,分别是自动,(auto),、外部,(extern),、静态,(static),和寄存器,(register),。,1,auto,:,使用,auto,定义的变量称为自动变量,其作用范围在定义它的函数体或复合语句内部,当定义它的函数体或复合语句执行时,,C51,才为该变量分配内存空间,结束时占用的内存空间释放。自动变量一般分配在内存的堆栈空间中。定义变量时,如果省略存储种类,则该变量默认为自动,(auto),变量。,2,extern,:,使用,extern,定义的变量称为外部变量。在一个函数体内,要使用一个已在该函数体外或别的程序中定义过的外部变量时,该变量在该函数体内要用,extern,说明。外部变量被定义后分配固定的内存空间,在程序整个执行时间内都有效,直到程序结束才释放。,3,static,:,使用,static,定义的变量称为静态变量。它又分为内部静态变量和外部静态变量。在函数体内部定义的静态变量为内部静态变量,它在对应的函数体内有效,一直存在,但在函数体外不可见,这样不仅使变量在定义它的函数体外被保护,还可以实现当离开函数时值不被改变。外部静态变量上在函数外部定义的静态变量。它在程序中一直存在,但在定义的范围之外是不可见的。如在多文件或多模块处理中,外部静态变量只在文件内部或模块内部有效。,4,register,:,使用,register,定义的变量称为寄存器变量。它定义的变量存放在,CPU,内部的寄存器中,处理速度快,但数目少。,C51,编译器编译时能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户可以无需专门声明。,四存储器类型,存储器类型是用于指明变量所处的单片机的存储器区域情况。存储器类型与存储种类完全不同。,C51,编译器能识别的存储器类型有以下几种,见表所示。,存储器类型,描 述,data,直接寻址的片内,RAM,低,128B,,访问速度快,bdata,片内,RAM,的可位寻址区(,20H2FH,),允许字节和位混合访问,idata,间接寻址访问的片内,RAM,,允许访问全部片内,RAM,pdata,用,Ri,间接访问的片外,RAM,的低,256B,xdata,用,DPTR,间接访问的片外,RAM,,允许访问全部,64k,片外,RAM,code,程序存储器,ROM64k,空间,定义变量时也可以省“存储器类型”,省时,C51,编译器将按编译模式默认存储器类型,具体编译模式的情况在后面介绍。,【,例,4-2】,变量定义存储种类和存储器类型相关情况。,char data varl,;,/*,在片内,RAM,低,128B,定义用直接寻址方式访问的字符型变量,var1*/,int idata var2,;,/*,在片内,RAM256B,定义用间接寻址方式访问的整型变量,var2*/,auto unsigned long data var3,;,/*,在片内,RAM128B,定义用直接寻址方式访问的自动无符号长整型变量,var3*/,extern float xdata var4,;,/*,在片外,RAM64KB,空间定义用间接寻址方式访问的外部实型变量,var4*/,int code var5,;,/*,在,ROM,空间定义整型变量,var5*/,unsign char bdata var6,;,/*,在片内,RAM,位寻址区,20H2FH,单元定义可字节处理和位处理的无符号字符型变量,var6*/,五特殊功能寄存器变量,MCS-51,系列单片机片内有许多特殊功能寄存器,通过这些特殊功能寄存器可以控制,MCS-51,系列单片机的定时器、计数器、串口、,I/O,及其它功能部件,每一个特殊功能寄存器在片内,RAM,中都对应于一个字节单元或两个字节单元。,在,C51,中,允许用户对这些特殊功能寄存器进行访问,访问时须通过,sfr,或,sfr16,类型说明符进行定义,定义时须指明它们所对应的片内,RAM,单元的地址。格式如下:,sfr,或,sfr16,特殊功能寄存器名,=,地址;,sfr,用于对,MCS-51,单片机中单字节的特殊功能寄存器进行定义,,sfr16,用于对双字节特殊功能寄存器进行定义。特殊功能寄存器名一般用大写字母表示。地址一般用直接地址形式,具体特殊功能寄存器地址见前面内容。,【,例,4-3】,特殊功能寄存器的定义。,sfr PSW=0 xd0,;,sfr SCON=0 x98,;,sfr TMOD=0 x89,;,sfr P1=0 x90,;,sfr16 DPTR=0 x82,;,sfr16 T1=0X8A,;,六位变量,在,C51,中,允许用户通过位类型符定义位变量。位类型符有两个:,bit,和,sbit,。可以定义两种位变量。,bit,位类型符用于定义一般的可位处理位变量。它的格式如下:,bit,位变量名;,在格式中可以加上各种修饰,但注意存储器类型只能是,bdata,、,data,、,idata,。只能是片内,RAM,的可位寻址区,严格来说只能是,bdata,。,【,例,4-4】,bit,型变量的定义。,bit data a1,;,/*,正确*,/,bit bdata a2,;,/*,正确*,/,bit pdata a3,;,/*,错误*,/,bit xdata a4,;,/*,错误*,/,sbit,位类型符用于定义在可位寻址字节或特殊功能寄存器中的位,定义时须指明其位地址,可以是位直接地址,可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号。格式如下:,sbit,位变量名,=,位地址;,如位地址为位直接地址,其取值范围为,0 x000 xff,;如位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前面须对可位寻址变量或特殊功能寄存器进行定义。字节地址与位号之间、特殊功能寄存器与位号之间一般用“,”,作间隔。,【,例,4-5】,sbit,型变量的定义。,sbit OV=0 xd2,;,sbit CY=oxd7,;,unsigned char bdata flag,;,sbit flag0=flag0,;,sfr P1=0 x90,;,sbit P1_0=P10,;,sbit P1_1=P11,;,sbit P1_2=P12,;,sbit P1_3=P13,;,sbit P1_4=P14,;,sbit P1_5=P15,;,sbit P1_6=P16,;,sbit P1_7=P17,;,在,C51,中,为了用户处理方便,,C51,编译器把,MCS-51,单片机的常用的特殊功能寄存器和特殊位进行了定义,放在一个“,reg51.h”,或“,reg52.h”,的头文件中,当用户要使用时,只须要在使用之前用一条预处理命令,#include ,把这个头文件包含到程序中,然后就可使用殊功能寄存器名和特殊位名称。,10.3.3,存储模式,C51,编译器支持三种存储模式:,SMALL,模式、,COMPACT,模式和,LARGE,模式。不同的存储模式对变量默认的存储器类型不一样。,(,1,),SMALL,模式。,SMALL,模式称为小编译模式,在,SMALL,模式下,编译时,函数参数和变量被默认在片内,RAM,中,存储器类型为,data,。,(,2,),COMPACT,模式。,COMPACT,模式称为紧凑编译模式,在,COMPACT,模式下,编译时,函数参数和变量被默认在片外,RAM,的低,256,字节空间,存储器类型为,pdata,。,(,3,),LARGE,模式。,LARGE,模式称为大编译模式,在,LARGE,模式下,编译时函数参数和变量被默认在片外,RAM,的,64K,字节空间,存储器类型为,xdata,。,在程序中变量的存储模式的指定通过,#pragma,预处理命令来实现。函数的存储模式可通过在函数定义时后面带存储模式说明。如果没有指定,则系统都隐含为,SMALL,模式。,【,例,4-6】,变量的存储模式。,#pragma small /*,变量的存储模式为,SMALL*/,char k1;,int xdata m1;,#pragma compact /*,变量的存储模式为,SMALL*/,char k2;,int xdata m2;,int func1(int x1,int y1)large /*,函数的存储模式为,LARGE*/,return(x1+y1);,int func2(int x2,int y2)/*,函数的存储模式隐含为,SMALL*/,return(x2-y2);,程序编译时,,k1,变量存储器类型为,data,,,k2,变量存储器类型为,pdata,,而,m1,和,m2,由于定义时带了存储器类型,xdata,,因而它们为,xdata,型;函数,func1,的形参,x1,和,y1,的存储器类型为,xdata,型,而函数,func2,由于没有指明存储模式,隐含为,SMALL,模式,形参,x2,和,y2,的存储器类型为,data,。,10.3.4,绝对地址的访问,一使用,C51,运行库中预定义宏,C51,编译器提供了一组宏定义来对,51,系列单片机的,code,、,data,、,pdata,和,xdata,空间进行绝对寻址。规定只能以无符号数方式访问,定义了,8,个宏定义,其函数原型如下:,#define CBYTE(unsigned char volatile*)0 x50000L),#define DBYTE(unsigned char volatile*)0 x40000L),#define PBYTE(unsigned char volatile*)0 x30000L),#define XBYTE(unsigned char volatile*)0 x20000L),#define CWORD(unsigned int volatile*)0 x50000L),#define DWORD(unsigned int volatile*)0 x40000L),#define PWORD(unsigned int volatile*)0 x30000L),#define XWORD(unsigned int volatile*)0 x20000L),这些函数原型放在,absacc.h,文件中。使用时须用预处理命令把该头文件包含到文件中,形式为:,#include ,。,其中:,CBYTE,以字节形式对,code,区寻址,,DBYTE,以字节形式对,data,区寻址,,PBYTE,以字节形式对,pdata,区寻址,,XBYTE,以字节形式对,xdata,区寻址,,CWORD,以字形式对,code,区寻址,,DWORD,以字形式对,data,区寻址,,PWORD,以字形式对,pdata,区寻址,,XWORD,以字形式对,xdata,区寻址。访问形式如下:,宏名,地址,宏名为,CBYTE,、,DBYTE,、,PBYTE,、,XBYTE,、,CWORD,、,DWORD,、,PWORD,或,XWORD,。地址为存储单元的绝对地址,一般用十六进制形式表示。,【,例,4-7】,绝对地址对存储单元的访问,#include /*,将绝对地址头文件包含在文件中*,/,#include /*,将寄存器头文件包含在文件中*,/,#define uchar unsigned char /*,定义符号,uchar,为数据类型符,unsigned char*/,#define uint unsigned int /*,定义符号,uint,为数据类型符,unsigned int*/,void main(void),uchar var1;,uint var2;,var1=XBYTE0 x0005;/*XBYTE0 x0005,访问片外,RAM,的,0005,字节单元*,/,var2=XWORD0 x0002;/*XWORD0 x0002,访问片外,RAM,的,000,字单元*,/,.,while(1);,在上面程序中,其中,XBYTE0 x0005,就是以绝对地址方式访问的片外,RAM 0005,字节单元;,XWORD0 x0002,就是以绝对地址方式访问的片外,RAM 0002,字单元。,二通过指针访问,采用指针的方法,可以实现在,C51,程序中对任意指定的存储器单元进行访问。,【,例,4-8】,通过指针实现绝对地址的访问。,#define uchar unsigned char /*,定义符号,uchar,为数据类型符,unsigned char*/,#define uint unsigned int /*,定义符号,uint,为数据类型符,unsigned int*/,void func(void),uchar data var1;,uchar pdata *dp1,;/,*,定义一个指向,pdata,区的指针,dp1*/,uint xdata *dp2;,/,*,定义一个指向,xdata,区的指针,dp2*/,uchar data *dp3;,/,*,定义一个指向,data,区的指针,dp3*/,dp1=0 x30;/*dp1,指针赋值,指向,pdata,区的,30H,单元*,/,dp2=0 x1000;/*dp2,指针赋值,指向,xdata,区的,1000H,单元*,/,*,dp1=0 xff;,/,*,将数据,0 xff,送到片外,RAM30H,单元*,/,*dp2=0 x1234;,/,*,将数据,0 x1234,送到片外,RAM1000H,单元*,/,dp3=/*dp3,指针指向,data,区的,var1,变量*,/,*,dp3=0 x20;,/,*,给变量,var1,赋值,0 x20*/,三使用,C51,扩展关键字,_at_,使用,_at_,对指定的存储器空间的绝对地址进行访问,一般格式如下:,存储器类型,数据类型说明符 变量名,_at_,地址常数;,其中,存储器类型为,data,、,bdata,、,idata,、,pdata,等,C51,能识别的数据类型,如省略则按存储模式规定的默认存储器类型确定变量的存储器区域;数据类型为,C51,支持的数据类型。地址常数用于指定变量的绝对地址,必须位于有效的存储器空间之内;使用,_at_,定义的变量必须为全局变量。,【,例,4-9】,通过,_at_,实现绝对地址的访问。,#define uchar unsigned char /*,定义符号,uchar,为数据类型符,unsigned char*/,#define uint unsigned int /*,定义符号,uint,为数据类型符,unsigned int*/,void main(void),data uchar x1 _at_ 0 x40;/*,在,data,区中定义字节变量,x1,它的地址为,40H*/,xdata uint x2 _at_ 0 x2000;/*,在,xdata,区中定义字变量,x2,它的地址为,2000H*/,x1=0 xff;,x2=0 x1234;,.,while(1);,10.4 C51,的运算符及表达式,10.4.1,赋值运算符,赋值运算符“,=”,,在,C51,中,它的功能是将一个数据的值赋给一个变量,如,x=10,。利用赋值运算符将一个变量与一个表达式连接起来的式子称为赋值表达式,在赋值表达式的后面加一个分号“;”就构成了赋值语句,一个赋值语句的格式如下:,变量,=,表达式;,执行时先计算出右边表达式的值,然后赋给左边的变量。例如:,x=8+9,;,/*,将,8+9,的值赋绐变量,x*/,x=y=5,;,/*,将常数,5,同时赋给变量,x,和,y*/,在,C51,中,允许在一个语句中同时给多个变量赋值,赋值顺序自右向左。,10.4.2,算术运算符,C51,中支持的算术运算符有:,+,加或取正值运算符,-,减或取负值运算符,*,乘运算符,/,除运算符,%,取余运算符,加、减、乘运算相对比较简单,而对于除运算,如相除的两个数为浮点数,则运算的结果也为浮点数,如相除的两个数为整数,则运算的结果也为整数,即为整除。如,25.0/20.0,结果为,1.25,,而,25/20,结果为,1,。,对于取余运算,则要求参加运算的两个数必须为整数,运算结果为它们的余数。例如:,x=5%3,,结果,x,的值为,2,。,10.4.3,关系运算符,C51,中有,6,种关系运算符:,大于,=,大于等于,3,,结果为真(,1,),而,10=100,,结果为假(,0,)。,注意:关系运算符等于“,=”,是由两个“,=”,组成。,10.4.4,逻辑运算符,C51,有,3,种逻辑运算符:,|,逻辑或,&,逻辑与,!逻辑非,关系运算符用于反映两个表达式之间的大小关系,逻辑运算符则用于求条件式的逻辑值,用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。,逻辑与,格式:,条件式,1&,条件式,2,当条件式,1,与条件式,2,都为真时结果为真(非,0,值),否则为假(,0,值)。,逻辑或,格式:,条件式,1|,条件式,2,当条件式,1,与条件式,2,都为假时结果为假(,0,值),否则为真(非,0,值)。,逻辑非,格式:,!条件式,当条件式原来为真(非,0,值),逻辑非后结果为假(,0,值)。当条件式原来为假(,0,值),逻辑非后结果为真(非,0,值)。,例如:若,a=8,,,b=3,,,c=0,,则!,a,为假,,a&b,为真,,b&c,为假。,10.4.5,位运算符,C51,语言能对运算对象按位进行操作,它与汇编语言使用一样方便。位运算是按位对变量进行运算,但并不改变参与运算的变量的值。如果要求按位改变变量的值,则要利用相应的赋值运算。,C51,中位运算符只能对整数进行操作,不能对浮点数进行操作。,C51,中的位运算符有:,&,按位与,|,按位或,按位异或,按位取反,右移,【,例,4-10】,设,a=0 x45=01010100B,,,b=0 x3b=00111011B,,则,a&b,、,a|b,、,ab,、,a,、,a2,分别为多少?,a&b=00010000b=0 x10,。,a|b=01111111B=0 x7f,。,ab=01101111B=0 x6f,。,a=10101011B=0 xab,。,a2=00001110B=0 x0e,。,10.4.6,复合赋值运算符,C51,语言中支持在赋值运算符“,=”,的前面加上其它运算符,组成复合赋值运算符。下面是,C51,中支持的复合赋值运算符:,+=,加法赋值,+,减法赋值,*,=,乘法赋值,/=,除法赋值,%=,取模赋值,&=,逻辑与赋值,|=,逻辑或赋值,=,逻辑异或赋值,=,逻辑非赋值,=,右移位赋值,=2,相当于,x=x2,。,10.4.7,逗号运算符,在,C51,语言中,逗号“,”是一个特殊的运算符,可以用它将两个或两个以上的表达式连接起来,称为逗号表达式。逗号表达式的一般格式为:,表达式,1,,表达式,2,,,,表达式,n,程序执行时对逗号表达式的处理:按从左至右的顺序依次计算出各个表达式的值,而整个逗号表达式的值是最右边的表达式(表达式,n,)的值。例如:,x=(a=3,6*3),结果,x,的值为,18,。,10.4.8,条件运算符,条件运算符“?:”是,C51,语言中唯一的一个三目运算符,它要求有三个运算对象,用它可以将三个表达式连接在一起构成一个条件表达式。条件表达式的一般格式为:,逻辑表达式?表达式,1,:表达式,2,其功能是先计算逻辑表达式的值,当逻辑表达式的值为真(非,0,值)时,将计算的表达式,1,的值作为整个条件表达式的值;当逻辑表达式的值为假(,0,值)时,将计算的表达式,2,的值作为整个条件表达式的值。例如:条件表达式,max=(ab)?a:b,的执行结果是将,a,和,b,中较大的数赋值给变量,max,。,10.4.9,指针与地址运算符,指针是,C51,语言中的一个十分重要的概念,在,C51,中的数据类型中专门有一种指针类型。指针为变量的访问提供了另一种方式,变量的指针就是该变量的地址,还可以定义一个专门指向某个变量的地址的指针变量。为了表示指针变量和它所指向的变量地址之间的关系,,C51,中提供了两个专门的运算符:,*指针运算符,&,取地址运算符,指针运算符“*”放在指针变量前面,通过它实现访问以指针变量的内容为地址所指向的存储单元。例如:指针变量,p,中的地址为,2000H,,则*,p,所访问的是地址为,2000H,的存储单元,,x=*p,,实现把地址为,2000H,的存储单元的内容送给变量,x,。,取地址运算符“,&”,放在变量的前面,通过它取得变量的地址,变量的地址通常送给指针变量。例如:设变量,x,的内容为,12H,,地址为,2000H,,则,&x,的值为,2000H,,如有一指针变量,p,,则通常用,p=&x,,实现将,x,变量的地址送给指针变量,p,,指针变量,p,指向变量,x,,以后可以通过*,p,访问变量,x,。,10.5,表达式语句及复合语句,10.5.1,表达式语句,在表达式的后边加一个分号“;”就构成了表达式语句,如,:,a=+b*9,;,x=8,;,y=7,;,+k,;,可以一行放一个表达式形成表达式语句,也可以一行放多个表达式形成表达式语句,这时每个表达式后面都必须带“;”号,另外,还可以仅由,个分号“;”占一行形成一个表达式语句,这种语句称为空语句。,空语句在程序设计中通常用于两种情况:,(,1,)在程序中为有关语句提供标号,用以标记程序执行的
展开阅读全文