资源预览内容
第1页 / 共77页
第2页 / 共77页
第3页 / 共77页
第4页 / 共77页
第5页 / 共77页
第6页 / 共77页
第7页 / 共77页
第8页 / 共77页
第9页 / 共77页
第10页 / 共77页
亲,该文档总共77页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
第3章 单片机C51语言设计基础3.1 C513.1 C51的数据的数据3.2 C513.2 C51对单片机主要资源的控制对单片机主要资源的控制3.3 C513.3 C51的基本运算与流程控制的基本运算与流程控制3.4 C513.4 C51的数组与指针的数组与指针3.5 C513.5 C51函数函数3.6 C513.6 C51的预处理命令的预处理命令3.1 C51的数据3.1.1 3.1.1 数据类型数据类型 常量与变量常量与变量3.1.3 3.1.3 数据存储类型数据存储类型3.1.4 3.1.4 局部变量与全局变量局部变量与全局变量 3.1.1 数据类型3.1.2 常量与变量1 1常量常量 C51 C51语言中的常量是不接受程序修改的固定值,常量可以是任意数据语言中的常量是不接受程序修改的固定值,常量可以是任意数据类型。类型。 C51 C51中的常量有中的常量有整型常量、实型常量、字符型常量、字符串常量符号整型常量、实型常量、字符型常量、字符串常量符号常量常量等。等。(2 2)实型常量)实型常量 在整型常量后加一个字母在整型常量后加一个字母“L L”或或“l l”,表示该数位长整型。,表示该数位长整型。例如例如23L23L、0Xfd4l0Xfd4l等。等。 如果需要的是负值,则必须将负号如果需要的是负值,则必须将负号“- -”放置于常量表达式放置于常量表达式的最前面,例如的最前面,例如-0x56-0x56、-9-9等。等。实型常量又称实型常量又称浮点常量浮点常量,是一个十进制表示的符号,是一个十进制表示的符号实数。实型常量的值包括整数部分、尾数部分和指实数。实型常量的值包括整数部分、尾数部分和指数部分。实型常量的形式如下:数部分。实型常量的形式如下: digits.digitsEdigits.digitsE+/-digits+/-digits一些实型常量的示例如下:一些实型常量的示例如下:、1575E-31575E-3、25E-425E-4。(3)字符型常量 字符型常量是指用一对字符型常量是指用一对单引号单引号括起来的一个字符。如括起来的一个字符。如aa、99、 ! 等。字符常量中的单引号只起定界作用并不表示字符本身。等。字符常量中的单引号只起定界作用并不表示字符本身。 在在C51C51语言中,字符是按其对应的语言中,字符是按其对应的ASCIIASCII码值码值来存储的,来存储的,1 1个字符占个字符占1 1个个字节字节 字符串常量是指用一对双引号括起来的一串字符,双引号只起定界作用,字符串常量是指用一对双引号括起来的一串字符,双引号只起定界作用,如如ChinaChina、123456123456等。等。 (5)符号常量 C51 C51语言中允许将程序中的常量定义为一个标识符,称为语言中允许将程序中的常量定义为一个标识符,称为符号常量符号常量。 符号常量一般使用符号常量一般使用大写大写英文字母表示,以区别于一般用小写字母表英文字母表示,以区别于一般用小写字母表示的变量。示的变量。 符号常量在使用前必须符号常量在使用前必须先定义先定义,定义的形式是:,定义的形式是: #define#define 标识符标识符 常量常量2变量变量的定义:变量的定义: 数据类型数据类型 变量名变量名; ; int i,j,k; int i,j,k; unsigned char si; unsigned char si; unsigned int ui; unsigned int ui; double balance,profit,loss; double balance,profit,loss; C51 C51中常用的:中常用的:bitbit、charchar、intint(1)整型变量(INT) 16位数据有符号:有符号:signed intsigned int -32 768 -32 76832 767 32 767 无符号:无符号:unsigned intunsigned int 0 065 535 65 535 0x1234 0x1234存储形式存储形式(3 3)实型变量)实型变量(2 2)长整型变量()长整型变量(long intlong int) 长整型变量长度是长整型变量长度是3232位,占用位,占用4 4个字节(个字节(bytebyte),其他),其他方面和整型变量(方面和整型变量(intint)相似。)相似。分为单精度(分为单精度(floatfloat)型和双精度()型和双精度(doubledouble)型。)型。其定义形式为:其定义形式为: float float x,yx,y; /; /指定指定x,yx,y为单精度实数为单精度实数 double z; / double z; /指定指定z z为双精度实数为双精度实数 在一般系统中,一个在一般系统中,一个floatfloat型数据在内存中占型数据在内存中占4 4个字节个字节(3232位),一个位),一个doubledouble型数据占型数据占8 8个字节(个字节(6464位)。单精位)。单精度实数提供度实数提供7 7位有效数字,双精度实数提供位有效数字,双精度实数提供15151616位有效位有效数字。数字。(4)字符变量CHAR字符变量用来存放字符常量。注意只能存放字符变量用来存放字符常量。注意只能存放1 1个字符。个字符。字符变量的定义形式如下:字符变量的定义形式如下:char char 变量名变量名; ;例如:例如: char c1,c2; char c1,c2;它表示它表示c1c1和和c2c2为字符变量,各存放为字符变量,各存放1 1个字符。可以用下面的语句对个字符。可以用下面的语句对c1c1、c2c2赋赋值:值:c1=a;c2=b;c1=a;c2=b;字符变量的长度是字符变量的长度是1 1字节(字节(bytebyte)即)即8 8位。这很适合于位。这很适合于80518051单片机,因为单片机,因为80518051单片机每次可以处理单片机每次可以处理8 8位数据位数据。变量的类型是位,位变量的值可以是变量的类型是位,位变量的值可以是1 1(truetrue)或)或0 0(falsefalse)。)。与与80518051硬件特性操作有关的位变量必须定位在硬件特性操作有关的位变量必须定位在80518051单片机片内存储区单片机片内存储区(RAMRAM)的可位寻址空间中。)的可位寻址空间中。3有符号/无符号问题说明(1 1)尽量使用无符号变量)尽量使用无符号变量(2 2)在编程时,为了书写方便,经常使用简化的缩写形式来定义)在编程时,为了书写方便,经常使用简化的缩写形式来定义变量的数据类型:变量的数据类型: #define uchar unsigned char #define uchar unsigned char #define uint unsigned int #define uint unsigned int3.1.3 数据存储类型 数据时存放在数据时存放在5151单片机的存储器中的,因此要规定数据单片机的存储器中的,因此要规定数据的存储类型。的存储类型。P53 P53 表表3-43-4 常用:常用:datadata、xdataxdata、codecode 另外:另外:bdatabdata(1 1)DATADATA区区datadata区的寻址是最快的,所以应该把经常使区的寻址是最快的,所以应该把经常使用的变量放在用的变量放在datadata区,但是区,但是datadata区的空间是区的空间是有限的,有限的,datadata区除了包含程序变量外,还包区除了包含程序变量外,还包含了堆栈和寄存器组。含了堆栈和寄存器组。datadata区声明中的存储类型标式符为区声明中的存储类型标式符为datadata,通,通常指片内常指片内RAMRAM的低的低128128字节的内部数据存储的字节的内部数据存储的变量,可直接寻址。变量,可直接寻址。声明举例如下:声明举例如下: unsigned char data system_status=0; unsigned int data unit_id2; char data inp_string16;bdatabdata实际是实际是datadata中的位寻址区,在这个区中声中的位寻址区,在这个区中声明变量就可以进行位寻址。位变量的声明对状明变量就可以进行位寻址。位变量的声明对状态寄存器来说是十分有用的,因为它可能仅仅态寄存器来说是十分有用的,因为它可能仅仅需要某一位,而不是整个字节。需要某一位,而不是整个字节。bdatabdata区声明中的存储类型标识符为区声明中的存储类型标识符为bdatabdata,指,指内部可位寻址的内部可位寻址的1616字节存储区(字节存储区(20H20H到到2FH2FH),),数据类型是可位寻址变量的数据类型。数据类型是可位寻址变量的数据类型。 (2) BDATA区区以下是在BDATA区中声明的位变量和使用位变量的例子: unsigned char bdata status_byte; unsigned int bdata status_word; unsigned long bdata status_dword; sbit stat_flag=status_byte4; if(status_word15) stat_flag=1;(3)IDATA区idataidata区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。idataidata区声明中的存储类型标识符为区声明中的存储类型标识符为idataidata,指内部的,指内部的256256字节的存储区,字节的存储区,但是只能间接寻址,速度比直接寻址慢。但是只能间接寻址,速度比直接寻址慢。声明举例如下:声明举例如下:unsigned char idata system_status=0;unsigned int idata unit_id2;char idata inp_string16;float idata out_value;pdatapdata区和区和xdataxdata区属于外部数据存储区,外部数据区是可读可写的存区属于外部数据存储区,外部数据区是可读可写的存储区,最多可以有储区,最多可以有64KB64KB。在这两个区,变量的声明与在其他区的语法是一样的,但在这两个区,变量的声明与在其他区的语法是一样的,但pdatapdata区只区只有有256256字节而字节而xdataxdata区可达区可达65 53665 536字节。字节。声明举例如下:unsigned char xdata system_status=0;unsigned int pdata unit_id2 ;char xdata inp_string16 ;float pdata out_value;外部地址段中除了包含存储器地址外,还包含外部地址段中除了包含存储器地址外,还包含I/OI/O器件的地址器件的地址。对外部器件寻址可以通过指针。对外部器件寻址可以通过指针或或C51C51提供的宏,使用宏对外部器件提供的宏,使用宏对外部器件I/OI/O口进行口进行寻址更具可读性。寻址更具可读性。(5 5)程序存储区)程序存储区CODECODE 程序存储区的数据是不可改变的,跳转向量和程序存储区的数据是不可改变的,跳转向量和状态表对状态表对codecode段访问和对段访问和对xdataxdata区访问的时间是一区访问的时间是一样的。编译的时候要对程序存储区中的对象进行初样的。编译的时候要对程序存储区中的对象进行初始化,否则就会产生错误。程序存储区始化,否则就会产生错误。程序存储区codecode声明的声明的标识符为标识符为codecode,在,在C51C51语言编译器中可以用语言编译器中可以用codecode存存储区类型标识符来访问程序存储区。下面是程序存储区类型标识符来访问程序存储区。下面是程序存储区声明的例子:储区声明的例子:unsigned char code a =0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15;变量存储类型定义举例:char data var1;bit bdata flags;float idata x,y,z;unsigned int pdata dimension;unsigned char xdata vector1044;3.1.4 3.1.4 局部变量与全局变量局部变量与全局变量 从变量的作用范围来区分,变量可以被分为从变量的作用范围来区分,变量可以被分为全局变量和局部变量全局变量和局部变量; 某些变量在程序运行过程中是始终存在的某些变量在程序运行过程中是始终存在的-全局变量全局变量。 某些变量只是在进入某个函数时才开始存在某些变量只是在进入某个函数时才开始存在-局部变量。局部变量。1局部变量局部变量局部变量是在某个函数中存在的变量,也可以称为内部变量,它只在该是在某个函数中存在的变量,也可以称为内部变量,它只在该函数内部有效。函数内部有效。局部变量可以分为局部变量可以分为动态局部变量动态局部变量和和静态局部变量静态局部变量,使用关键词,使用关键词autoauto定义定义动态局部变量(动态局部变量(autoauto可以省略),使用关键词可以省略),使用关键词staticstatic定义静态局部变量,定义静态局部变量,例如例如:auto int a;static unsigned char j;动态局部变量动态局部变量在程序执行完毕后其存储空间被释放,而在程序执行完毕后其存储空间被释放,而静态局部变量静态局部变量在在程序执行完成后其存储空间并不释放,而且其值保持不变。程序执行完成后其存储空间并不释放,而且其值保持不变。如果该函数再次被调用,则该函数初始化后其初始值为上次的数值。如果该函数再次被调用,则该函数初始化后其初始值为上次的数值。动态局部变量和静态局部变量的区别如下:动态局部变量和静态局部变量的区别如下: 动态局部变量在函数被调用时分配存储空间和动态局部变量在函数被调用时分配存储空间和初始化,每次函数调用时都需要初始化;静态初始化,每次函数调用时都需要初始化;静态局部变量在编译程序时分配存储空间和初始化,局部变量在编译程序时分配存储空间和初始化,仅初始化一次。仅初始化一次。 动态局部变量存放在动态存储区,在每次退出动态局部变量存放在动态存储区,在每次退出所属函数时释放;静态局部变量存放在静态存所属函数时释放;静态局部变量存放在静态存储区,每次调用后函数不释放,保持函数执行储区,每次调用后函数不释放,保持函数执行完毕之后的数值到下一次调用。完毕之后的数值到下一次调用。 如果在建立时动态局部变量不初始为一个不确如果在建立时动态局部变量不初始为一个不确定的数,静态局部变量不初始化,则它们的值定的数,静态局部变量不初始化,则它们的值为为0 0或者是空字符。或者是空字符。2 2全局变量全局变量 全局变量是在整个源文件中都存在的变量,又称为外部变量。全全局变量是在整个源文件中都存在的变量,又称为外部变量。全局变量的有效区间是从定义点开始到源文件结束,其中的所有函数都局变量的有效区间是从定义点开始到源文件结束,其中的所有函数都可以直接访问该变量,如果定义点之前的函数需要访问该变量,则需可以直接访问该变量,如果定义点之前的函数需要访问该变量,则需要使用要使用externextern关键词对该变量进行声明,如果全局变量声明文件之外关键词对该变量进行声明,如果全局变量声明文件之外的源文件需要访问该变量,也需要使用的源文件需要访问该变量,也需要使用externextern关键词进行声明。关键词进行声明。全局变量有以下特点: 全局变量是整个文件都可以访问的变量,可以用于在函数之间共享全局变量是整个文件都可以访问的变量,可以用于在函数之间共享大量的数据,存在周期长,在程序编译时就存在,如果两个函数需要大量的数据,存在周期长,在程序编译时就存在,如果两个函数需要在不互相调用时共享数据,则可以使用全局变量进行参数传递;在不互相调用时共享数据,则可以使用全局变量进行参数传递; C51C51语言程序的函数只支持一个函数返回值,如果一个函数需要返回语言程序的函数只支持一个函数返回值,如果一个函数需要返回多个值,除了使用指针外,还要使用全局变量;多个值,除了使用指针外,还要使用全局变量; 使用全局变量进行参数传递可以减少从实际参数向形式参数传递时使用全局变量进行参数传递可以减少从实际参数向形式参数传递时所必需的堆栈操作;所必需的堆栈操作; 在一个文件中,如果某个函数的局部变量和全局变量同名,则在这在一个文件中,如果某个函数的局部变量和全局变量同名,则在这个局部变量的作用范围内局部变量不起作用,全局变量起作用;个局部变量的作用范围内局部变量不起作用,全局变量起作用; 全局变量一直存在,占用了大量的内存单元,并且加大了程序的耦全局变量一直存在,占用了大量的内存单元,并且加大了程序的耦合性,不利于程序的移植或复用。合性,不利于程序的移植或复用。 静态局部变量的作用范围仅仅是在定义的函数内,不静态局部变量的作用范围仅仅是在定义的函数内,不能被其他的函数访问,全局变量的作用范围是整个程序,能被其他的函数访问,全局变量的作用范围是整个程序,静态全局变量的作用范围是该变量定义的文件;静态全局变量的作用范围是该变量定义的文件; 静态局部变量是在函数内部定义,全局变量是在所有静态局部变量是在函数内部定义,全局变量是在所有函数外定义;函数外定义; 静态局部变量仅仅在第静态局部变量仅仅在第1 1次调用时被初始化,再次调用次调用时被初始化,再次调用时使用上次调用结束时的数值,全局变量在程序运行时时使用上次调用结束时的数值,全局变量在程序运行时建立,值为最近一条访问该全局变量的语句执行的结果。建立,值为最近一条访问该全局变量的语句执行的结果。 另外,另外,mainmain函数虽然是函数虽然是.c.c文件的主文件,但也是一文件的主文件,但也是一个函数,在其内部定义的变量也属于局部变量。全局变个函数,在其内部定义的变量也属于局部变量。全局变量一般在量一般在.c.c文件的开始部分定义或在文件的开始部分定义或在. .件中定义,由件中定义,由.c.c文件引用。文件引用。C51C51语言程序多使用全局变量传递参数,因语言程序多使用全局变量传递参数,因为这样可以降低程序处理的难度,加快程序执行的速度,为这样可以降低程序处理的难度,加快程序执行的速度,提高程序的时效性。提高程序的时效性。3.2 C513.2 C51对单片机资源的控制对单片机资源的控制3.2.1 3.2.1 特殊功能寄存器的特殊功能寄存器的C51C51语言定义语言定义3.2.2 3.2.2 绝对地址的访问绝对地址的访问3.2.3 3.2.3 位变量的位变量的C51C51语言定义语言定义3.2.1 3.2.1 特殊功能寄存器的特殊功能寄存器的C51C51定义定义2121个特殊功能寄存器。两种方式:个特殊功能寄存器。两种方式:1 1使用关键字使用关键字sfrsfr定义定义 sfr sfr 特功器名字特功器名字= =特功器地址特功器地址; ; sfrsfr SCON=0x98; SCON=0x98; /* /*串口控制寄存器地址串口控制寄存器地址98H*/98H*/ sfrsfr TMOD=0X89; TMOD=0X89; /* /*定时器定时器/ /计数器方式控制寄存器地址计数器方式控制寄存器地址9H*/9H*/2 2通过头文件访问通过头文件访问SFRSFR#include #include /使用的单片机为使用的单片机为IntelIntel公司的公司的MCS-51MCS-51void main(void)void main(void) TL0=0xb0; TL0=0xb0; TH0=0x3c;TH0=0x3c;TR0=1; TR0=1; /启动定时器启动定时器0 0.3SFR中位定义3种方式(1 1)第)第1 1种方法种方法sbit sbit 位名位名= =特殊功能寄存器名特殊功能寄存器名 位置位置; ;(2 2)第)第2 2种方法种方法sbit sbit 位名位名= =字节地址字节地址 位置位置; ;(3 3)第)第3 3种方法种方法sbit sbit 位名位名= =位地址位地址; ;例:例:unsigned char bdata flag;sbit flag0=flag0;sfr P1=0x90;sbit P1_0=P10;sbit P1_1=P11;sbit P1_6=P16;sbit P1_7=P17;P60 P60 例例3-33-3 sbit sbit型变量的定义型变量的定义P60 P60 例例3-43-4 片内片内I/OI/O口及其位的定义口及其位的定义3.2.2 绝对地址的访问包括:包括:片内片内RAMRAM、片外、片外RAMRAM及及I/OI/O口。口。可以有两种方式:可以有两种方式:用用#include#include可使用其中声明的宏来访问绝对地址,可使用其中声明的宏来访问绝对地址, DBYTEDBYTE以字节形式对以字节形式对datadata区寻址;区寻址; DWORDDWORD以字形式对以字形式对datadata区寻址;区寻址; XBYTEXBYTE以字节形式对以字节形式对xdataxdata区寻址;区寻址; XWORDXWORD以字形式对以字形式对xdataxdata区寻址;区寻址;另外:另外: CBYTE CBYTE以字节形式对以字节形式对codecode区寻址;区寻址; CWORDCWORD以字形式对以字形式对codecode区寻址;区寻址; PBYTEPBYTE以字节形式对以字节形式对pdatapdata区寻址;区寻址; PWORDPWORD以字形式对以字形式对pdatapdata区寻址。区寻址。例例3-5( P61 )3-5( P61 )#include #include #define PA XBYTE0xffec#define PA XBYTE0xffec/将将PAPA定义为外部定义为外部I/OI/O口,地址为口,地址为0xffec0xffec#define NRAM DBYTE0x40#define NRAM DBYTE0x40/*/*将将NRAMNRAM定义为片内定义为片内RAMRAM,地址为,地址为40H40H,长度为,长度为8 8位位*/*/ void main( ) void main( ) PA=0x3A;PA=0x3A;NRAM=0x01;NRAM=0x01; #include#include #define PORTA#define PORTA XBYTE XBYTE0xFFC00xFFC0 /*/*将将PORTPORT定义为外部定义为外部I/OI/O口,地址为口,地址为0xFFC00xFFC0,长度为,长度为8 8位位* */ /#define NRAM #define NRAM DBYTEDBYTE0x400x40/*/*将将NRAMNRAM定义为片内定义为片内RAMRAM,地址为,地址为40H40H,长度为,长度为8 8位位* */ /例例3-63-6(P62)P62)data unsigned char x1 _at_ 0x40;/*在在data区定义字节变量区定义字节变量x1,它的地址为它的地址为40H*/xdata unsigned int x2 _at_ 0x2000; /*在在xdata区定义字变量区定义字变量x2,它的地址为它的地址为2000H*/void main(void)x1=0xff;x2=0x1234H;.while(1); 可以使用关键字可以使用关键字_at_at_对指定的存储器空间的绝对地址进行访问。对指定的存储器空间的绝对地址进行访问。一般格式如下:一般格式如下: 【存储类型存储类型】 数据类型符数据类型符 变量名变量名 _at_ _at_ 地址常数地址常数; ;3.2.3 3.2.3 位变量的位变量的C51C51语言定义语言定义1 1位变量的位变量的C51C51语言定义语言定义 采用关键字采用关键字bitbit进行定义。例如:进行定义。例如: bit direction_bit; bit direction_bit;/* /* 将将direction_bitdirection_bit定义为位变量定义为位变量 */ */ bit lock_pointer; bit lock_pointer;/* /* 将将lock_pointerlock_pointer定义为位变量定义为位变量 */ */ bit display_invers; bit display_invers;/* /* 将将display_inversdisplay_invers定义为位变量定义为位变量 */ */2 2可位寻址对象可位寻址对象 可位寻址对象指可以字节或位寻址的对象。该对象应位于可位寻址对象指可以字节或位寻址的对象。该对象应位于80518051片内可位寻址片内可位寻址RAMRAM区中,区中,C51C51语言编译器允许数据类型为语言编译器允许数据类型为idataidata的对象放入的对象放入80518051片内可位寻址片内可位寻址RAMRAM区。区。 位变量的存储类型只能是位变量的存储类型只能是bdatabdata。 在程序设计时,对于可位寻址的对象,即可以字节寻址也可以位寻址的变量,在程序设计时,对于可位寻址的对象,即可以字节寻址也可以位寻址的变量,但其存储类型只能是但其存储类型只能是bdatabdata。 使用时应先说明字节变量的数据类型和存储类型,然后可使用使用时应先说明字节变量的数据类型和存储类型,然后可使用bitbit定义可寻址访定义可寻址访问的对象位。例如:问的对象位。例如:bdata int ibase; /* ibase /* ibase定义为定义为bdatabdata整型变量整型变量 * */ /bdata char bary4; /* bary /* bary定义为定义为bdatabdata字符型数组字符型数组 * */ /sbit mybit0=ibase0; /* mybit0/* mybit0定义为定义为ibaseibase的第的第0 0位位* */ /sbit mybit15=ibase15; /* mybit15/* mybit15定义位定义位ibaseibase的第的第1515位位* */ /sbit Ary07=bary07; /* Ary07/* Ary07定义为定义为bary0bary0的第的第7 7位位* */ /sbit Ary37=bary37; /*Ary37/*Ary37定义为定义为bary3bary3的第的第7 7位位* */ /Ary37=0; Ary37=0; /* bary3/* bary3的第的第7 7位赋值为位赋值为0 */0 */bary3=a; bary3=a; /* /* 字节寻址:字节寻址:bary3bary3赋值为赋值为a */a */ sbitsbit定定义义要要求求基基址址对对象象的的存存储储类类型型为为bdatabdata,只只有有这这样样其其特特殊殊位位定定义义(sbitsbit)是是合合法法的的。 位位置置(操操作作符符)后后的的最最大大值值依依赖赖于于指指定定的的基基类类型型,对对于于char/ucharchar/uchar而言是而言是0 07 7,对于,对于int/uintint/uint而言是而言是0 01515,对于,对于long/ulonglong/ulong而言是而言是0 03131。3.3 C513.3 C51的基本运算与流程控制的基本运算与流程控制3.3.1 3.3.1 基本运算基本运算3.3.2 3.3.2 选择(分支)控制语句选择(分支)控制语句3.3.3 3.3.3 循环结构流程控制语句循环结构流程控制语句3.3.4 break3.3.4 break语句、语句、continuecontinue语句、语句、gotogoto语句语句3.3.1 基本运算(运算符)运算符运算符是表示特定的算术或逻辑运算的符号,也称是表示特定的算术或逻辑运算的符号,也称操作符操作符。把需要进行运算的各个量通过运算符连接起来,便构成把需要进行运算的各个量通过运算符连接起来,便构成表达式表达式。算术运算符、关系运算符、算术运算符、关系运算符、逻辑运算符、位运算符、逻辑运算符、位运算符、赋值运算符、特殊运算符赋值运算符、特殊运算符算术运算的操作符:算术运算的操作符:+ + (加法运算符)、(加法运算符)、- - (减法运算符)(减法运算符)* * (乘法运算符)、(乘法运算符)、/ / (除法运算符)(除法运算符) (模运算或取余运算符)(模运算或取余运算符)+为自增运算符为自增运算符- - -为自减运算符。为自减运算符。注意:注意:/ /:结果的整数部分;结果的整数部分;% %:结果的余数部分;结果的余数部分;- -:除进行减法外,还可以进行取负操作。除进行减法外,还可以进行取负操作。+:自增。表示自增。表示操作数加操作数加1 1。X+ X+ 等同于等同于X=X+1X=X+1。+X +X 表示先加表示先加1 1,再取,再取值;值;X+X+表示先取值,再加表示先取值,再加1 1。例例3-83-8:自增和自减运算符的程序:自增和自减运算符的程序#include void main( ) int x, y, z1, z2; x=10; y=21; z1=(x+)+(x+); printf(“x=%d, z1=%dn”, x, z1); z2=(+y)+(+y); printf(“y=%d, z2=%dn”, y, z2); 二、关系运算成立或不成立主要用于比较操作数的大小关系。主要用于比较操作数的大小关系。包括:包括: (小于)、(小于)、= (大于)、(大于)、= (大于等(大于等于)、于)、= = = (等于)、(等于)、!= = (不等于)(不等于)看看关系是否成立关系是否成立。结果:。结果:0 0或或1 1例3-9 关系运算符运算的程序示例#include void main( ) int a, b, c, d; a=-2.30; b=71=32; c=7!=0; d=-12=0; printf(“a=%d, b=%d, c=%d,d=%dn”, a, b, c, d);三、逻辑运算结果是真或假进行逻辑运算的操作符。包括:进行逻辑运算的操作符。包括:& & (逻辑与)、(逻辑与)、| | (逻辑或)、!(逻辑非)(逻辑或)、!(逻辑非)看看结果是否为真结果是否为真。结果:。结果:0 0或或1 1。例3-10 逻辑运算的程序示例#include void main( ) int a, b, c, d, e ; a=!0 ; b=15&22 ; c=35&0 ; d=17.3|0 ; e=17.3|2.6 ;printf(“a=%d, b=%d,c=%d, d=%d, e=%dn”, a, b, c, d, e);四、位运算四、位运算将两个操作数按二进制数展开,然后对应位进行逻辑运算。包括:将两个操作数按二进制数展开,然后对应位进行逻辑运算。包括:& &(按位与)、(按位与)、| |(按位或)、(按位或)、(按位异或)、(按位异或)、(按位取反)、(按位取反)、(位右移)(位右移)位运算的操作对象只能是整型和字符型数据。这些位运算和汇编语言位运算的操作对象只能是整型和字符型数据。这些位运算和汇编语言中的位操作指令十分类似。中的位操作指令十分类似。位操作指令是单片机的重要特点,所以位运算在位操作指令是单片机的重要特点,所以位运算在C51C51语言控制类程序设语言控制类程序设计中的应用比较普遍。计中的应用比较普遍。例例3-11 3-11 位运算程序示例将位运算程序示例将A A值循环右移值循环右移2 2位位main( )main( ) unsigned char a=0xc3,b,c;unsigned char a=0xc3,b,c;int n=2;int n=2;b=a(8-n);b=an;c=an;a=c|b;a=c|b; 例3-12 位运算程序示例#include void main( ) int a, b,c; a=23; b=217; c=a&b; printf(“a&b=%dn”, c); c=a|b; printf(“a|b=%dn”, c); c=ab ; printf(“ab=%dn”, c); c=a ; printf(“a =%dn”, c); c=a3 ; printf(“a2 ; printf(“b2=%dn”, c);五、赋值运算五、赋值运算变量名变量名= =表达式表达式; ;例如:例如:a=(b=4)+(c=6);a=(b=4)+(c=6);该表达式的值为该表达式的值为1010,变量,变量a a的值为的值为1010。复合赋值运算符:复合赋值运算符: 赋值符号前加上其他运算符构成复合运算符。赋值符号前加上其他运算符构成复合运算符。C51C51语言提供以语言提供以下下1010种复合运算符:种复合运算符:+=+=,-=-=,* *= =,= =,= =,=,= =,=,=例如:例如:a+=b;a+=b; / /等价于等价于a=(a+b)a=(a+b)x*=a+b; /x*=a+b; /等价于等价于x=(x*(a+b)x=(x*(a+b)a&=b;a&=b; / /等价于等价于a=(a&b)a=(a&b)a=4;a=4; / /等价于等价于a=(a4)a=(ay) max=x; min=y; 形式二: IF(表达式)语句1; ELSE 语句2;if(xy) max=x;else min=y;形式三:if(if(表达式表达式1)1)语句语句1;1;else if(else if(表达式表达式2)2)语句语句2;2;else if(else if(表达式表达式3)3)语句语句3;3;else if(else if(表达式表达式m m)语句语句m m;else else 语句语句n n;if(x1000) y=1; else if(x500) y=2;else if(x300) y=3;else if(x100) y=4;else y=5;例3-13 分支编程示例#includemain ( ) int x,y; scanf(%d,&x); if(x0) y=-1; else if (x=0) y=0;else y=1; printf(x=d,y=dn,x,y);例3-14:#includevoid main( ) int a,b; a=200; b=321; if(a=b) a+;b+; printf(a=%d,b=%dn,a,b);例3-15:#includevoid main( ) int a,b; a=12;b=21; if(a=b) a+;b+; a-;b-; printf(a=%d,b=%dn,a,b);例3-16:#includevoid main( ) int score; char grade; score=45; if(score=90) grade=A; else if(score=80) grade=B; else if(score=70) grade=C; else if(score=60) grade=D; else grade=E; printf(score=%d,grade=%cn,score,grade);二、SWITCH语句switchswitch语句是多分支选择语句一般形式如下:语句是多分支选择语句一般形式如下:switch(switch(表达式表达式) ) case case 常量表达式常量表达式1:1:语句语句1; break;1; break;case case 常量表达式常量表达式2:2:语句语句2; break;2; break;.case case 常量表达式常量表达式n n:语句语句n n; break; break;default:default:语句语句n n+1;+1; 例3-173.3.3 3.3.3 循环结构流程控制语句循环结构流程控制语句四种形式:四种形式: if goto if goto while while do-while do-while for for一、基于IF和GOTO构成的循环 1 1、采用、采用ifif和和gotogoto可以构成可以构成“当型当型”循环循环loop: if(表达式表达式) 语句语句;goto loop; 2 2、采用、采用ifif和和gotogoto也可以构成也可以构成“直到型直到型”循环程序循环程序 loop: 语句语句;if(表达式表达式) goto loop; 3 3、gotogoto语句为无条件转向语句语句为无条件转向语句 goto goto 语句标号语句标号; ;二、WHILE while(while(表达式表达式) ) 语句语句; ; 例:#includevoid main( ) int i, s; i=100; s=0; while(i0) s=s+i; i=i-1; printf(“1+2+100=%dn”,s);注意:注意:先判断,后执行;先判断,后执行;如果循环体内只有一个语句,可以不用如果循环体内只有一个语句,可以不用 WhileWhile循环体循环体 后无分号;后无分号;三、DO-WHILEdo 语句语句; while (表达式)(表达式);例:#includevoid main( ) int i, s; i=100;s=0; do s=s+i; i=i-1; while(i0); printf(“1+2+100=%dn”,s);注意:注意:先执行先执行, , 后判断;后判断;如果循环体内只有一个语句,可以不用如果循环体内只有一个语句,可以不用 循环体循环体 后无分号;后无分号;while(while(表达式)后的分号不能省;表达式)后的分号不能省;四、FORfor(for(表达式表达式1;1;表达式表达式2;2;表达式表达式3)3) 语句语句; ; for(y=0;y=99;y=y+3)delay(33); px=px;例:#includevoid main( ) int i, s; s=0; for(i=0;i=100;i+) s=s+i; printf(“1+2+100=%dn”,s);注意:注意:3 3个表达式都是可选项,可以任意省略,但个表达式都是可选项,可以任意省略,但“;”不能省。不能省。省省1 1是不对循环变量赋初值;是不对循环变量赋初值;省省2 2是不判断循环条件的真假;是不判断循环条件的真假;省省3 3是不对循环变量操作。是不对循环变量操作。for( ; ;)for( ; ;)表示无限循环。表示无限循环。无限循环的实现: (1 1)for(; ;)for(; ;) 代码段;代码段; (2 2)while(1)while(1) 代码段;代码段; (3 3)do do 代码段;代码段; while while(1 1););3.3.4 BREAK3.3.4 BREAK语句、语句、CONTINUECONTINUE语句、语句、GOTOGOTO语语句句在循环语句执行过程中,在循环语句执行过程中, 如果需要在满足循环判定条件的情况下跳出代码段,可以使用如果需要在满足循环判定条件的情况下跳出代码段,可以使用breakbreak或或continuecontinue语句;语句; 如果要从任意地方跳转到代码的某个地方,可以使用如果要从任意地方跳转到代码的某个地方,可以使用gotogoto语句。语句。1、BREAKbreakbreak语句用于从循环代码中退出,然后执行循环语句之后的语句,语句用于从循环代码中退出,然后执行循环语句之后的语句,不再进入循环不再进入循环 。形式:。形式: breakbreak;注意:注意:一个一个breakbreak只能跳出一层循环只能跳出一层循环例:#includevoid main( ) int i, s; i=0; s=0; while(1) s=s+iI; i+; if(i100) break; printf(“1+2+100=%dn”,s);2、CONTINUE continue continue语句用于退出当前循环,不再执行本轮循环,程序代码语句用于退出当前循环,不再执行本轮循环,程序代码从下一轮循环开始执行,直到判断条件不满足为止。从下一轮循环开始执行,直到判断条件不满足为止。与与breakbreak的区别是该语句不是退出整个循环。形式:的区别是该语句不是退出整个循环。形式: continue;continue;例:例:#includevoid main( ) char ch =a, B,c,D,e,F; int i=-1; while(i=a& chi=z) continue; printf(“ch%d=%cn”, i, chari ); 3、GOTO goto goto是一个无条件转移语句。当执行是一个无条件转移语句。当执行gotogoto语句时,将程序指针跳转到语句时,将程序指针跳转到gotogoto给出给出的下一条代码,基本格式如下:的下一条代码,基本格式如下: goto goto 标号标号; ;例:例:void main(void)void main(void) unsigned char counter;unsigned char counter;int sum ; sum=0;int sum ; sum=0;sumadd: sum=sum+counter;sumadd: sum=sum+counter; counter+; counter+; if(counter101) if(counter101) goto sumadd;goto sumadd; 3.4 C51的数组与指针 C51C51语言的构造数据类型主要有数组、指针和结构等。在单片机系统语言的构造数据类型主要有数组、指针和结构等。在单片机系统中,数组的应用比较广泛,指针则次之,结构用的相对较少。这里我们中,数组的应用比较广泛,指针则次之,结构用的相对较少。这里我们只讨论数组和指针。只讨论数组和指针。3.4.1 数组 数组是同类型变量的一个有序集合。数组是同类型变量的一个有序集合。 数组用一个名字来标识,称为数组名。数组用一个名字来标识,称为数组名。 数组中的每个变量称为数组元素。数组中的每个变量称为数组元素。 数组有一维、二维、三维和多维数组之分。数组有一维、二维、三维和多维数组之分。C51C51语言中常用的一维、二语言中常用的一维、二维数组和字符数组。维数组和字符数组。 数组中各元素的顺序用下标表示,下标为数组中各元素的顺序用下标表示,下标为N N的元素可以表示为数组名的元素可以表示为数组名 N N 。改变改变 中的下标就可以访问数组中所有的元素。中的下标就可以访问数组中所有的元素。1一维数组 类型说明符类型说明符 数组名数组名 元素个数元素个数; int demo110; int demo110;初始化:初始化: int a5=1,2,3,4,5; int a5=1,2,3,4,5; int b6=1,2,6; int b6=1,2,6; 例3-23:2二维数组或多维数组类型说明符类型说明符 数组名数组名 行数行数列数列数;float demo234;float demo234;/demo2 /demo2 数组有数组有3 3 行行4 4 列共列共12 12 个实型元素个实型元素int a34=int a34=1,2,3,4,5,6,7,8,9,10,11,12;1,2,3,4,5,6,7,8,9,10,11,12;/全部初始化全部初始化3字符数组若一个数组的元素是字符型的,则该数组就是一个字符数组。例如:若一个数组的元素是字符型的,则该数组就是一个字符数组。例如: char a12=Chong Qing; char a12=Chong Qing;/字符数组字符数组 char add36= char add36=weight,height,width;weight,height,width;/字符串数组字符串数组4查表#define uchar unsigned char#define uchar unsigned charuchar code tempt=32,34,36,37,39,41;uchar code tempt=32,34,36,37,39,41;/*/*数组数组, ,设置在设置在EPROMEPROM中中, ,长度为实际输入的数值数长度为实际输入的数值数 */ */uchar ftoc(uchar degc)uchar ftoc(uchar degc) return temptdegc;return temptdegc;void main( )void main( ) uchar x;uchar x;x=ftoc(5);/* x=ftoc(5);/* 得到与得到与55相应的华氏温度值相应的华氏温度值 */ */ 共阴极共阴极LEDLED的显示字符段码表的显示字符段码表 char code char code SEG11=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,SEG11=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;0x6f;3.5 C51函数函数是指能够执行特定功能和任务的程序代码段。函数是指能够执行特定功能和任务的程序代码段。 一个完整的一个完整的C51C51程序是由一个主函数和若干个其他程序是由一个主函数和若干个其他函数组成。函数组成。 主函数是主函数是main( )main( )函数。有且只有一个函数。有且只有一个main( )main( )函数。函数。使用函数时注意: 函数数目不限制;函数数目不限制; main( ) main( )函数是主函数,可以调用其他函数,而不函数是主函数,可以调用其他函数,而不允许被其他函数调用。允许被其他函数调用。 除主函数外,其他函数之间允许互相调用。除主函数外,其他函数之间允许互相调用。一、函数分类可以从不同的角度分类:可以从不同的角度分类:(1 1)有无返回值角度)有无返回值角度(2 2)数据传送角度)数据传送角度(3 3)函数定义角度)函数定义角度(1)有无返回值角度无返回值函数、有返回值函数无返回值函数、有返回值函数无返回值函数无返回值函数:执行完成后不向主调函数返回函数值。类型说明符为:执行完成后不向主调函数返回函数值。类型说明符为:voidvoid有返回值函数有返回值函数:执行完成后向主调函数返回一个执行的结果:执行完成后向主调函数返回一个执行的结果返回值。返回值。(2 2)数据传送角度)数据传送角度有参函数和无参函数。有参函数和无参函数。无参函数:无参函数:主调函数和被调函数之间不进行参数的传递。主调函数和被调函数之间不进行参数的传递。有参函数:有参函数:主调函数和被调函数之间存在参数的传递。主调函数和被调函数之间存在参数的传递。-形式参数形式参数和实际参数和实际参数(3 3)函数定义角度)函数定义角度主函数、自定义函数、库函数主函数、自定义函数、库函数自定义函数:自定义函数:是用户根据自己的需要而编写的函数。从函数定义的是用户根据自己的需要而编写的函数。从函数定义的形式上可以将其划分无参函数、有参函数和空函数。形式上可以将其划分无参函数、有参函数和空函数。 无参函数无参函数 有参函数有参函数 空函数空函数二、函数定义有参函数和无参函数定义。有参函数和无参函数定义。(1 1)无参函数的定义方法)无参函数的定义方法P60P60无参函数的定义形式为:无参函数的定义形式为:返回值类型标识符返回值类型标识符 函数名函数名( )( ) 函数体函数体; ; 无参函数一般不带返回值,因此函数返回值类型标识符可以省略。无参函数一般不带返回值,因此函数返回值类型标识符可以省略。(2 2)有参函数的定义方法)有参函数的定义方法有参函数的定义形式为:有参函数的定义形式为:P61P61返回值类型标识符返回值类型标识符 函数名函数名( (形式参数列表形式参数列表) )形式参数说明;形式参数说明; 函数体函数体; ; 函数定义举例:函数定义举例:#include#includeint max(x1,x2)int max(x1,x2)int x1,x2;int x1,x2; if(x1x2) if(x1x2) return x1; return x1; else else return x2; return x2; void main( )void main( ) int x1=17;x2=9; int x1=17;x2=9; printf( printf(“x1=%d,x2=%dx1=%d,x2=%d”,x1,x2);,x1,x2); printf( printf(“max(x1,x2)=%dnmax(x1,x2)=%dn”,max(x1,x2); ,max(x1,x2); 在程序中定义函数应注意:(1)(1)可将形参类型说明放在形参列表中,如:可将形参类型说明放在形参列表中,如:int max(int x1,int x2)int max(int x1,int x2) .(2)(2)函数位置与声明函数位置与声明3.5.2 3.5.2 中断函数中断函数函数类型函数类型 函数名函数名 interrupt n using n interrupt n using n3.6 C513.6 C51的预处理命令的预处理命令 C51 C51语言中提供了各种预处理命令,其作用类似于语言中提供了各种预处理命令,其作用类似于汇编程序中的伪指令。汇编程序中的伪指令。 预处理命令通常只进行一些符号的处理,并不执行预处理命令通常只进行一些符号的处理,并不执行具体的硬件操作。具体的硬件操作。C51C51的预处理命令包括文件包含命令、的预处理命令包括文件包含命令、宏定义指令条件编译指令。预处理命令前要加一个宏定义指令条件编译指令。预处理命令前要加一个“# #”。3.6.1 3.6.1 文件包含文件包含#include#include 或或 #include #include 文件名文件名“#include #include ”myfile.h myfile.h ” /引用自定义文件引用自定义文件myfilemyfile#include #include /引用库函数文件引用库函数文件stdiostdio#include #include /引用寄存器文件引用寄存器文件#define MATH_FILE #define MATH_FILE ” /*/*宏定义自定义文件宏定义自定义文件MATH_FILE */MATH_FILE */#include MATH_FILE #include MATH_FILE /引用自定义文件引用自定义文件MATH_FILEMATH_FILE例:文件包含指令的程序示例例:文件包含指令的程序示例 #include#include#include”myfile1.h”#include”myfile1.h”void main( )void main( ) int i,sum=0;int i,sum=0;for(i=0;i=20;i+)for(i=0;i=20;i+) sum=sum+fun(i);sum=sum+fun(i);printf(“sum=%dn”,sum);printf(“sum=%dn”,sum);其中其中myfile1.myfile1.件的内容如下:件的内容如下:int fun(int i)int fun(int i) int mu1;int mu1;mu1=i*i;return mu1;mu1=i*i;return mu1; 在使用#INCLUDE命令时,应注意以下几点: #include#include命令出现在程序中的位置,决定了被命令出现在程序中的位置,决定了被包含的文件就从此处引入源文件。包含的文件就从此处引入源文件。 一个一个#include#include命令只能指定一个被包含文件,命令只能指定一个被包含文件,如果程序中需要包含多个文件则需要使用多个如果程序中需要包含多个文件则需要使用多个包含命令。包含命令。 采用采用 格式时,在头文件目录中查找指格式时,在头文件目录中查找指定文件,采用定文件,采用 文件名文件名 格式时,在当前目录中格式时,在当前目录中查找指定文件。查找指定文件。 #include#include命令末尾不需要分号命令末尾不需要分号“;”结束。结束。 #include#include命令只能调入命令只能调入ASCIIASCII文本文件。文本文件。3.6.2 宏定义指令1 1简单的宏定义简单的宏定义简单的宏定义格式为:简单的宏定义格式为:#define #define 宏替换名宏替换名 宏替换体宏替换体3.6.3 3.6.3 条件编译条件编译1 1#if#if型型格式如下:格式如下:#if #if 常量表达式常量表达式代码代码1;1;#else#else代码代码2;2;#endif#endif
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号