《C单片机的C程序设计.pptx》由会员分享,可在线阅读,更多相关《C单片机的C程序设计.pptx(113页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、学习目的(1)理解C语言程序在结构上的特点和书写格式上的要求。(2)掌握数据类型的概念,了解C51语言能够处理的数据类型。(3)了解C51语言基本运算符及其特点,掌握运算符的优先级和结合性。(4)理解算术表达式、关系表达式、逻辑表达式的特点,能熟练计算表达式。(5)掌握if语句swith语句的语法。能编写选择结构的程序。掌握for语句、while语句、do-while语句的使用语法及方法,能进行循环程序设计。(6)理解数组的概念,能定义、初始化一维数组、二维数组及字符数组,进行相关程序设计。(7)理解函数的概念,能根据需要定义一个函数,能正确调用一个函数。理解主调函数和被调用函数参数传递过程,
2、掌握函数形参传递数组元素的方法。(8)理解指针的概念,能区别指针变量和变量的指针。理解指针与数组的关系,熟练使用指针指向一维、二维数组,理解指针表达数组元素的几种表现形式。第1页/共113页(9)理解80C51内部资源(端口、中断、定时/计数器、串行口)的应用;用可编程器件扩展资源;D/A及开关量输出控制的应用;数据采集的应用;人机交互的C51编程的应用。学习重点和难点(1)C51的数据类型、存储类型、C51的运算符和表达式及其规则。(2)表达式语句、复合语句、条件语句、while循环语句、do-while循环语句、for循环语句的语法及常用算法。(3)数组的定义、数组元素的表示方法、数组初始
3、化方法、字符数组和字符串。(4)指针的定义格式、指针的赋值、指针的运算,使用指针表示数组的元素。(5)函数的定义格式、函数说明方法、函数的参数、函数的返回值;函数的调用方式。(6)80C51中断函数的设计、定时/计数器的应用、串行通讯的应用。D/A、A/D,键盘、显示等模块的C语言程序的应用。第2页/共113页单片机应用系统的软件设计大多采用汇编语言程序设计来完成,因为汇编语言直接操作计算机的硬件,作为初学者掌握汇编语言的基本设计方法是必要的,但是汇编语言程序的可读性和可移植性都较差,采用汇编语言开发单片机应用系统程序的周期长,而且调试和排错也比较困难。为了提高编制计算机控制系统程序和应用程序
4、的效率,改善程序的可读性和可移植性,现在多采用高级语言编程。C语言既具有一般高级语言的特点,是一种通用的程序设计语言,其代码率高,数据类型及运算符丰富,并具有良好的程序结构,又能直接对计算机的硬件进行操作,并且程序能够很容易地在不同类型的计算机之间进行移植。因此它是目前使用较广的单片机编程语言。单片机的C语言采用C51编译器(简称C51)。由C51产生的目标代码短、运行速度高、所需存储空间小、符合C语言的ANSI标准,生成的代码遵循Intel目标文件格式,而且可与A51汇编语言或PL/M51语言目标代码混和使用。在众多的C51编译器中,Keil公司的C语言编译/连接器KeiluVison2软件
5、最受欢迎。第3页/共113页8.1单片机的C语言8.1.1C51程序开发概述1、采用C51的优点采用C51进行单片机应用系统的程序设计,编译器能自动完成变量的存储单元的分配,编程者可以专注于应用软件的设计,可以对常用的接口芯片编制通用的驱动函数,对常用的功能模块和算法编制相应的函数,可以方便的进行信号处理算法和程序的移植,从而加快单片机应用系统的开发过程。目前,C51系列单片机的C语言代码长度在未加人工优化的条件下,已经做到最优汇编程序水平的1.21.5倍,已超过中等程序员的水平。51系列单片机中,片上FLASHROM空间做到32K/64K的比比皆是,代码效率所差的10%15%已不是重要问题。
6、至于开发速度、软件质量、结构严谨、程序坚固等方面,C语言的完美绝非是汇编语言所能比拟的。2、C51程序的开发过程C51程序的开发过程如图8-1所示图8-1C51程序开发过程示意图第4页/共113页8.1.2C51程序结构C51程序结构同标准C一样,是由若干个函数构成的,每个函数即是完成某个特殊任务的子程序段。组成一个程序的若干个函数可以保存在一个或几个源文件中,最后再将它们连接在一起。C语言程序的扩展名为“.c”,如my_test.c。C语言程序的组成结构如下(主函数可以放在功能子函数说明之后的任意位置):C语言的语句规则:1、每个变量必须先说明后引用,变量名英文大小写是有差别的。2、C语言程
7、序一行可以书写多条语句,但每个语句必须以“;”结尾,一个语句也可以多行书写。3、C语言的注释用/*/表示。4、“”花括号必须成对,位置随意,可在紧挨函数名后,也可另起一行,多个花括号可以同行书写,也可逐行书写,为层次分明,增加可读性,同一层的“”花括号对齐,采用逐层缩进方式书写。预处理命令include功能子函数1说明功能子函数n说明功能子函数1fun1()函数体功能子函数nfun()函数体main()函数体第5页/共113页8.2C51的数据类型8.2.1C51的标识符、关键字标识符是一种单词,它用来给变量、函数、符号常量、自定义类型等命名。用标识符给C语言程序中各种对象命名时,要用字母、下
8、划线和数字组成的字符序列,并要求首字符是字母或下划线,不能是数字。字母的大小写是有区别的。通常下划线开头的标识符是编译系统专用的,因此在编写C语言源程序时一般不使用以下划线开头的标识符,而将下划线用作分段符。C51编译器规定标识符最长可达255个字符,但只有前32个字符在编译时有效,因此标识符的长度一般不要超过32个字符。关键字是一种已被系统使用过的具有特定含义的标识符。用户不得再用关键字给变量等命名。C语言关键字较少,ANSIC标准一共规定了32个关键字,见表8-1第6页/共113页表8-1ANSIC语言的关键字关键字用途说明auto存储种类说明用以说明局部变量,缺省值为此break程序语句
9、退出最内层循环case程序语句Switch语句中的选择项char数据类型说明单字节整型数或字符型数据const存储种类说明在程序执行过程中不可更改的常量值continue程序语句转向下一次循环default程序语句Switch语句中的失败选择项do程序语句构成 dowhile循环结构double数据类型说明双精度浮点数else程序语句构成 ifelse选择结构enum数据类型说明枚举类型extern存储种类说明在其他程序模块中说明了的全局变量float数据类型说明单精度浮点数for程序语句构成for循环结构goto程序语句构成goto转移结构第7页/共113页if程序语句构成 ifelse选择
10、结构int数据类型说明基本整型数long数据类型说明长整型数register存储种类说明使用CPU内部寄存器的变量return程序语句函数返回short数据类型说明短整型数signed数据类型说明有符号数,二进制数据的最高位为符号位sizeof运算符计算表达式或数据类型的字节数static存储种类说明静态变量struct数据类型说明结构类型数据switch程序语句构成Switch选择结构typedef数据类型说明重新进行数据类型定义union数据类型说明联合类型数据unsigned数据类型说明无符号数数据void数据类型说明无类型数据volatile数据类型说明该变量在程序执行中可被隐含地改变
11、while程序语句构成while和dowhile循环结构第8页/共113页KeilC51编译器除了有ANSIC标准的32个关键字外,还根据51单片机的特点扩展了相应的关键字。在KeilC51开发环境的文本编辑器中编写C程序,系统可以把保留字以不同的颜色显示,缺省颜色为蓝色。表8-2为KeilC51编译器扩展的关键字。表8-2KeilC51编译器扩展关键字关键字用途说明bit位标量声明声明一个位标量或位类型的函数sbit位变量声明声明一个可位寻址变量sfr特殊功能寄存器声明声明一个特殊功能寄存器(8位)sfr16特殊功能寄存器声明声明一个16位的特殊功能寄存器data存储器类型说明直接寻址的80
12、51内部数据存储器bdata存储器类型说明可位寻址的8051内部数据存储器idata存储器类型说明简洁寻址的8051内部数据存储器pdata存储器类型说明“分页”寻址的8051外部数据存储器xdata存储器类型说明8051外部数据存储器code存储器类型说明8051程序存储器interrupt中断函数声明定义一个中断函数reetrant再入函数声明定义一个再入函数using寄存器组定义定义8051的工作寄存器组第9页/共113页8.2.2数据与数据类型数据-具有一定格式的数字或数值。数据是计算机的操作对象。不管使用任何语言,任何算法进行程序设计,最终在计算机中运行的只有数据流。数据类型数据的不
13、同格式叫数据类型。数据结构数据按一定的数据类型进行排列、组合及架构称为数据结构。程序设计中用到的数据都存储在存储单元中,在汇编语言中我们可以用DB或DW伪指令来定义存放数据的存储单元;在C51中,编译系统要根据定义的数据类型来预留存储单元,这就是定义数据类型的意义。C51提供的数据数据结构是以数据类型的形式出现的,C51的数据类型如表8-3所示。使用有符号格式(signed)的数据时,编译器要进行符号位检测并需要调用库函数,生成的程序比无符号格式要长得多,程序运行的速度将减慢,占用的存储空间也会变大,出现错误的几率会大大增加。所以通常情况下尽可能采用无符号格式(unsigned)。编译器默认值
14、为有符号格式。第10页/共113页位型变量与单片机的硬件结构有关,应注意其定义在单片机片内可位寻址的区域。Bit型变量定义在80C51单片机内部RAM20H2FH单元相应的位区域;sbit用于定义可独立访问的位变量,常用于定义80C51单片机中SFR(特殊功能寄存器)中可位寻址的确定的位,也可以定义内部RAM的20H2FH单元中相应位。表8-3C51的数据类型数据类型长度(位)取值范围字符型signed char8-128127unsigned char80255整 型signed int16-3276832767unsigned int16065535长整型signed long32-214
15、7488364821474883647unsigned long3204294967295浮点型float321.75494E-383.402823E+38位 型bit10,1sbit10,1访问SFRsfr80255sfr1616065535第11页/共113页8.2.3C51数据的存储类型C51是面向80C51系列单片机的程序设计语言,应用程序中使用的任何数据(变量和常数)必须以一定的存储类型定位于单片机相应的存储区域中。C51编译器支持的存储类型如表8-4所示。表8-4C51的存储类型与8051存储空间的对应关系存储器类型长度(位)对应单片机存储器bdata1片内RAM,位寻址区,共12
16、8位。(也能字节访问)data8片内RAM,直接址区,共128字节。idata8片内RAM,间接址区,共256字节。pdata8片外RAM,分页间址,共256字节(MOVX Ri)。xdata16片外RAM,间接寻址,共64K字节(MOVX DPTR)。code16ROM区域,间接寻址,共64K字节(MOVC DPTR)第12页/共113页对于80C51系列单片机来说,访问片内的RAM比访问片外的RAM的速度要快得多,所以对于经常使用的变量应该置于片内RAM,即用bdata、data、idata来定义;对于不常使用的变量或规模较大的变量应该置于片外RAM中,即用pdata、xdata来定义。例
17、如:bitbdatamy_flag;/*item1*/chardatavar0;/*item2*/floatidatax,y,z;/*item3*/unsignedintpdatatemp;/*item4*/unsignedcharxdataarray34;/*item5*/item1:位变量my_flag被定义为bdata存储类型,C51编译器将把该变量定义在8051片内数据存储区(RAM)中的位寻址区(地址:20H2FH)。第13页/共113页item2:字符变量var0被定义为data存储类型,C51编译器将把该变量定位在8051片内数据存储区中(地址:00HFFH)。item3:浮点变
18、量x、y、z被定义为idata存储类型,C51编译器将把该变量定位在8051片内数据区,并只能用间接寻址的方式进行访问。item4:无符号整型变量temp被定义为pdata存储类型,C51译器将把该变量定位在8051片外数据存储区(片外RAM),并用操作码movxri进行访问。item5:无符号字符二维数组unsignedchararray34被定义为xdata存储类型,C51编译器将其定位在片外数据存储区(片外RAM),并占据3x4=12字节存储空间,用于存放该数组变量。第14页/共113页如果用户不对变量的存储类型进行定义,C51的编译器采用默认的存储类型。默认的存储类型由编译命令中存储模
19、式指令限制。C51支持的存储模式如表8-5所示。表8-5C51存储模式存储模式默认存储类型特点Smalldata 直接访问片内RAM;堆栈在片内RAM中 Compactpdata 用R0和R1间址片外分页RAM;堆栈在片内RAM中Largexdata 用DPTR间址片外RAM,代码长,效率低例如:Charvar;/*在small模式中,var定位data存储区*/*在compact模式中,var定位pdata存储区*/*在large模式中,var定位xdata存储区*/第15页/共113页在keilC51uVision2平台下,设置存储模式的界面如图8-9所示,步骤:工程建立好后,使用菜单Pr
20、oject|OptionforTargetTarget1,或点击快捷图标即出现图8-9所示工程对话框,点击Target标签,其中的MemoryModel用于设置RAM的使用情况,有3个选项:small是所有的变量都在单片机的内部RAM中;Compact变量存储在外部RAM里,使用8位间接寻址;large变量存储在外部RAM中,使用16位间接寻址,可以使用全部外部的扩展RAM。图8-9KeilC51的存储模式界面第16页/共113页8.2.480C51硬件结构的C51定义C51是适合于80C51单片机的C语言。它对标准C语言(ANSIC)进行扩展,从而具有对80C51单片机硬件结构的良好支持与操
21、作能力。1、特殊功能寄存器的定义80C51单片机内部RAM的80HFFH区域有21个特殊功能寄存器,为了对它们能够直接访问,C51编译器利用扩充的关键字SFR和SFR16对这些特殊功能寄存器进行定义。SFR的定义方法:sfr特殊功能寄存器名=地址常数例如:sfrP0=0 x80;/*定义P0口,地址为0 x80*/sfrTMOD=0 x89;/*定时/计数器方式控制寄存器地址89H*/注意:关键字sfr后面必须跟一个标识符作为特殊功能寄存器名称,名称可以任意选取,但要符合人们的一般习惯。等号后面必须是常数,不允许有带运算符的表达式,常数的地址范围与具体的单片机型号相对应,通常的80C51单片机
22、为0 x800 xFF。第17页/共113页2、特殊功能寄存器中特定位的定义在C51中可以利用关键字sbit定义可独立寻址访问的位变量,如定义80C51单片机SFR中的一些特定位。定义的方法有3种:1)sbit位变量名=特殊功能寄存器名位的位置(07)例如:sfrPSW=0 xD0;/*定义PSW寄存器地址为0 xd0h*/sbitOV=PSW2;/*定义OV位为PSW.2,地址为0 xd2*/sbitCY=PSW7;/*定义Cy位为PSW.7,地址为0 xd7*/2)sbit位变量名=字节地址位的位置例如:sbitOV=0 xd02;/*定义OV位的地址为0 xd2*/sbitCF=0 xd
23、07;/*定义CF位的地址为0 xd7*/注意:字节地址作为基地址,必须位于0 x800 xff之间。3)sbit位变量名=位地址例如:sbitOV=0 xd2;/*定义OV位的地址为0 xd2*/sbitCF=0 xd7;/*定义CF位的地址为0 xd7*/注意:位地址必须位于0 x800 xFF之间。第18页/共113页3、8051并行接口及其C51定义1)对于8051片内I/O口用关键字sfr来定义。例sfrP0=0 x80;/*定义P0口,地址为80h*/sfrP1=0 x90;/*定义P1口,地址为90h*/2)对于片外扩展I/O口,则根据其硬件译码地址,将其视为片外数据存储器的一个
24、单元,使用define语句进行定义。例:#include#definePORTAXBYTE0 x78f0;/*将PORTA定义为外部口,地址为78f0,长度为8位*/一旦在头文件或程序中对这些片内外的I/O口进行定义以后,在程序中就可以就可以自由使用这些口了。定义口地址的目的是为了便于C51编译器按8051实际硬件结构建立I/O口变量名与其实际地址的联系,以便使程序员能用软件模拟8051硬件操作。第19页/共113页4、位变量(bit)及其定义C51编译器支持bit数据类型:1)位变量的C51定义语法及语义如下:bitdir_bit;/*将dir_bit定义为位变量*/bitlock_bit;
25、/*将lock_bit定义为位变量*/2)函数可包含类型为bit的参数,也可以将其作为返回值。bitfunc(bitb0,bitb1)/*.*/return(b1);3)对位定义的限制:位变量不能定义成一个指针。如bit*bit_ptr是非法的。不存在位数组,如不能定义bitarr。在位定义中允许定义存储类型,位变量都放在一个段位中,此段总位于8051片内RAM中,因此存储类型限制为data或idata。如果将位变量的存储类型定义成其他类型,编译时将出错。4)可位寻址对象:可位寻址的对象是指可以字节寻址或位寻址的对象,该对象位于8051片内RAM可位寻址RAM区中,C51编译器允许数据类型为i
26、data的对象放入8051片内可位寻址的区中。先定义变量的数据类型和存储类型:bdataintibase;/*定义ibase为bdata整型变量*/bdatacharbary4;/*定义bary4为bdata字符型数组*/然后可使用“sbit”定义可独立寻址访问的对象位,即:sbitmybit0=ibase0;/*mybit0定义为ibase的第0位*/sbitmybit15=ibase15;/*mybit15定义为ibase的第15位*/sbitary01=bary01;/*ary01定义为bary0的第1位*/sbitary25=bary25;/*ary25定义为bary2的第5位*/第2
27、0页/共113页8.3C51的运算符、表达式及其规则运算符是完成某种运算的符号,C51具有丰富的运算符,对数据具有极强的表达能力。表达式是由运算符及运算对象组成的具有特定含义的式子。在任意表达式的后面加一个分号“;”就构成一个表达式语句。由运算符和表达式可以构成C51程序的各种语句。学习运算符时,应注意:1、运算符功能2、与运算量关系1)要求运算量个数:单个(单目)、两个(双目),三个(三目)2)要求运算量类型3、运算符优先级别4、结合方向5、结果的类型第21页/共113页8.3.1算术运算符和算术表达式1、基本算术运算符加法运算符,或正值符号;减法运算符,或负值符号;乘法运算符;除法运算符;
28、%模(求余)运算符;例11%3=2,结果是11除以3所得余数为2。在上述运算符中,加、减和乘法符合一般的算术运算规则。除法运算时,如果是两个整数相除,其结果为整数;如果是两个浮点数相除,其结果为浮点数。而对于取余运算,则要求两个运算对象均为整型数据。第22页/共113页C语言规定了算术运算符的优先级和结合性。优先级-指当运算对象两侧都有运算符时,执行运算的先后次序。按运算符优先级别的高低顺序执行运算。结合性-指当一个运算对象两侧的运算符优先级别相同时的运算顺序。算术运算符中取负运算的优先级最高,其次是乘法、除法和取余,加法和减法的优先级最低。也可以根据需要,在算术表达式采用括号来改变优先级的顺
29、序。如:a+b/c;该表达式中,除号优先级高于加号,故先运算b/c所得结果,之后再与a相加。(a+b)*(c-d)-e;该表达式中,括号优先级最高,其次是“*”,最后是减号。故先运算(a+b)和(c-d),然后再将二者结果相乘,最后与e相减。第23页/共113页2、自增减运算符自增减运算符的作用是使变量值自动加1或减1。+自增运算符;-自减运算符;+和-运算符只能用于变量,不能用于常量和表达式。如+(a+1)是错误的。如:+i、-i在使用i之前,先使i值加(减)1。i+、i-在使用i之后,再使i值加(减)1。粗略的看,+i和i+的作用都相当于i=i+1,但+i和i+的不同之处在于+i先执行i=
30、i+1,再使用i的值;而i+则是先使用i的值,再执行i=i+1。如:若i值原来为5.则j=+i;j的值为6,i的值也为6;j=i+;j的值为5,i的值为6;第24页/共113页3、类型转换运算符两侧的数据类型不同时,要转换成同种类型。转换的方法有两种,一是自动转换,是编译系统在编译时自动进行的类型转换,顺序是:bitcharintlongfloat,signedunsigned。二是强制类型转换,是通过类型转换运算来实现的。其一般形式:(类型说明符)(表达式)功能:把表达式的运算结果强制转换成类型说明符所表示的类型。如:(double)a将a强制转换成double类型(int)(x+y)将x+
31、y值强制转换成int类型(float)(5%3)将模运算5%3的值强制转换成float类型。第25页/共113页8.3.2关系运算符、关系表达式及优先级1、C51提供六种关系运算符小于;=小于等于;大于;=大于等于=测试等于;=!=测试不等于;2、关系运算符的优先级1)、=的优先级相同,两种=、=相同;前4种优先级高于后两种。2)关系运算符的优先级低于算术运算符。3)关系运算符的优先级高于赋值运算符。如:ca+b等效于c(a+b);ab!=c等效于(ab)!=ca=bc等效于a=(bc)3、关系运算符的结合性为左结合如:a=4,b=3,c=1,则f=abc,则ab的值为1,1c的值为0,故f=
32、0。4、关系表达式用关系运算符和将两个表达式(可以是算术表达式、关系表达式、逻辑表达式、字符表达式)连接起来的式子。5、关系表达式的结果真和假。C51中用0表示假,1表示真。第26页/共113页8.3.3逻辑运算符和逻辑表达式及优先级1、C51提供3种逻辑运算符!逻辑“非”(NOT)&逻辑“与”(AND)|逻辑“或”(OR)“&”和“|”是双目运算符,要求有两个运算对象;而“!”是单目运算符,只要求有一个运算对象。2、逻辑运算符的优先级在逻辑运算中,逻辑非的优先级最高,且高于算术运算符;逻辑或的优先级最低,低于关系运算符,但高于赋值运算符。3、逻辑表达式用逻辑运算符将关系表达式或逻辑量连接起来
33、的式子称为逻辑表达式。其值应为逻辑量真和假,逻辑表达式和关系表达式的值相同,以0代表假,1代表真。4、逻辑运算符的结合性为从左到右。例:如a=4,b=5则:!a为假。因为a=4(非0)为真,所以!a为假(0)。a|b为真。因为a,b为真,所以两者相或为真。a&b为真。!a&b为假(0)。!优先级高于&,先执行!a为假(0),0&b=0,结果为假。第27页/共113页8.3.4C51位操作及其表达式C51提供6种位运算符:&位与;|位或;位异或;位取反;右移;除按位取反运算符“”以外,以上位操作运算符都是双目运算符,及要求运算符两侧各有一个运算对象。1、“按位与”运算符“&”运算规则:参与运算的
34、两个运算对象,若两者相应的位都为1,则该位结果为1,否则为0,即:0&0=0、0&1=0、1&0=0、1&1=0如:a=45h=01000101b,b=0deh=11011110b,则表达式c=a&b=44h按位与的主要用途:1)清零。用0去和需要清零的位按位与运算。2)取指定位。第28页/共113页2、“按位或”运算符“|”运算规则:参与运算的两个运算对象,若两者相应的位中有一位为1,则该位结果为1,否则为0,即:0|0=0、0|1=1、1|0=1、1|1=1如:a=30h=00110000b,b=0fh=00001111b,则表达式c=a|b=3fh按位或的主要用途是将一个数的某些位置1,
35、则需要将这些位和1按位或,其余的位和0进行按位或运算则不变。3、“异或”运算符“”运算规则:参与运算的两个运算对象,若两者相应的位相同,则结果为0;若两则相应的位相异,结果为1,即:00=0、01=1、10=1、11=0如:a=0a5h,b=3dh,则表达式c=ab=98h按位异或的主要用途:1)使特定位翻转(0变1,1变0):需要翻转的位和1按位异或运算,不需要翻转的位和0按位异或运算。原数和自身按位异或后得0。2)不用临时变量而交换两数的值。4、“位取反”运算符“”“”是一个单目运算符,用来对一个二进制数按位取反,即0变1,1变0。5、位左移和位右移运算符()位左移、位右移运算符“”,用来
36、将一个二进制位的全部左移或右移若干位;移位后,空白位补0,而溢出的位舍弃。如:a=15h,则a=a2=05h第29页/共113页6、赋值和复合赋值运算符符号“=”称为赋值运算符,其作用是将一个数据的值赋予一个变量。赋值表达式的值就是被赋值变量的值。在赋值运算符的前面加上其他运算符就可以构成复合赋值运算符。在C51中共有10种复合运算符,这10种赋值运算符均为双目运算符。即:+=,-=,*=,/=,%=,=,&=,|=,=,=。采用这种复合赋值运算的目的,是为了简化程序,提高C程序编译效率。如:a+=b相当于a=a+ba%=b相当于a=a%ba-=b相当于a=a-ba=3相当于a=a=2相当于a
37、=a2a/=b相当于a=a/b等等。7、其他运算符(共有10个):数组的下标。():括号。.:结构/联合变量指针成员。&:取内容。?:三目运算符。,:逗号运算符。Sizeof:sizeof运算符用于在程序中测试某一数据类型占用多少字节。第30页/共113页8.4.1C51的顺序结构顺序结构是一种基本、最简单的编程结构。在这种结构中,程序由低地址向高地址顺序执行指令代码。如图8-10所示,程序先执行A操作,再执行B操作,两者是顺序执行的关系。8.4C51流程控制语句顺序结构、选择结构和循环结构是实现所有程序的三种基本结构,也是C51语言程序的三种基本构造单元。选择结构体现了程序的逻辑判断能力,分
38、支结构分为简单分支(两分支)和多分支两种情况。一般采用if语句实现简单分支结构的程序,用switch-case语句实现多分支结构程序。循环结构解决了重复性的程序段的设计,主要有for语句、while语句以及do-while语句。图8-10顺序结构第31页/共113页8.4.2C51的选择结构计算机功能强大的原因就在于它具有决策能力或者说选择能力。选择语句就是条件判断语句,首先判断给定的条件是否满足,然后根据判断的结果决定执行给出的若干选择之一。在C51中,选择语句有条件语句和开关语句两种。选择结构的流程图参考图3-15。1、条件语句条件语句由关键字if构成。它的基本结构是:if(表达式)语句;
39、如果括号中的表达式成立(为真),则程序执行花括弧中的语句;否则程序将跳过花括弧中的语句部分,执行下面的语句,C语言提供了三种形式的if语句。第32页/共113页1)形式1if(表达式)语句例:if(xy)printf(“%d”,x);2)形式2if(条件表达式)语句1;else语句2例:if(xy)max=x;elsemax=y;3)形式3If(表达式1)语句1;elseif(表达式2)语句2;elseif(条件表达式3)语句3;elseif(条件表达式n)语句n;else语句m例:if(salary1000)index=0.4;elseif(salary800)index=0.3;elsei
40、f(salary600)index=0.2;elseif(salary400)index=0.1;elseindex=0;说明:if语句的嵌套,在if语句中又含一个或多个if语句,这种情况称为if语句的嵌套。第33页/共113页2、开关语句开关语句主要用于多分支的场合。一般形式:Switch(表达式)Case常量表达式1:语句1;break;Case常量表达式2:语句2;break;Case常量表达式n:语句n;break;default:语句n+1;当switch括号中表达式的值与某一个case后面的常量表达式的值相等时,就执行它后面的语句,然后因遇到break而退出switch语句。当所有
41、的case中的常量表达式的值都没有与表达式的值相匹配时,就执行default后面的语句。每一个case的常量表达式必须是互不相同的,否则出现对表达式的同一个值,有两种以上的选择。如果case语句中遗忘了break,则程序在执行了本行case选择之后,不会按规定退出switch语句,而是执行后续的case语句。第34页/共113页8.4.3C51的循环结构程序设计中,常常要求进行有规律的重复操作,如求累加和,数据块的搬移等。计算机的基本特性之一就是具有重复执行一段语句的能力,即循环能力。几乎所有的实用程序都包含有循环结构。循环结构是结构化程序设计的3种基本结构之一,因此掌握循环结构的概念是程序设
42、计,尤其是C程序设计最基本的要求。循环程序结构流程图参考图3-18。在C51语言中,实现循环的语句主要有3种。1、While语句的一般形式While(表达式)语句;/*循环体*/While语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句。使用while语句应注意以下几点:1)While语句中的表达式一般是关系表达式或逻辑表达式,只要表达式的值为真(非0)即可继续循环。2)循环体如包含一个以上的语句,则必须用括起来,组成复合语句。3)While循环体中,应有使循环趋向于结束的语句,如无此种语句,循环将无休止的继续下去。第35页/共113页4)嵌入式平台上编写程序的一个最大特点是程
43、序总是一个无限循环作为结束,无限循环是必要的,这使得嵌入式软件的功能从启动之后,一直运行直至关机。因此,一个嵌入式程序的功能体会被无限循环包含,这使得他们可以一直运行下去。如:while(!RI)这个语句的作用是等待RI=1,如果RI=0,!RI=1,由于循环体无实际操作语句,故继续测试下去(等待);一旦RI=1,则循环终止。2、do-while语句的一般形式do语句;/*循环体*/while(表达式);dowhile循环语句的执行过程如下:首先执行循环体语句,然后执行圆括号中的表达式。如果表达式的值为真(非0值),则重复执行循环体语句,直到表达式的值变为假(0值)时为止。对于这种结构,在任何
44、条件下,循环体语句至少会被执行一次。3、for语句的一般形式for(表达式1;表达式2;表达式3)语句;/*循环体*/有关for循环语句的执行过程和for循环的几种特殊结构,请读者参考C语言教材。第36页/共113页8.5C51的数组在程序设计中,为了处理方便,把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类型数据元素的集合称为数组。在C语言中,数组属于构造数据类型。一个数组可以分解为多个数据元素,这些数据元素可以是基本的数据类型或是构造类型。因此按数组元素的类型不同,数组又可分为数值数组、字符数组、指针数组、结构数组等各种类别。第37页/共113页8.5.1一维数组1、一维数
45、组的定义方式类型说明符数组名整型常量表达式;例如:inta10;它表示数组名为a,此数组有10个元素。说明:1)数组名的命名规则和变量名相同,遵循标识符命名规则。2)数组名后是用方括号括起来的常量表达式,不能用圆括弧。3)常量表达式表示元素的个数,即数组的长度。例如在inta10中,10表示a数组有10个数据元素,下标从0开始,这10个元素是:a0,a1,a2,a3,a4,a5,a6,a7,a8,a9。注意不能使用a10。4)常量表达式中可以包括常量和符号常量,不能包含变量。也就是说,C51不允许对数组的大小作动态定义,即数组大小不依赖于程序运行过程中变量的值。第38页/共113页2、一维数组
46、的初始化对数组元素的初始化可以用以下方法实现:1)在定义数组时对数组元素赋予初值。例如:inta10=0,1,2,3,4,5,6,7,8,9;将数组元素的初值依次放在一对花括弧内。经过上面的定义和初始化之后,a0=0,a1=1,a2=2,a3=3,a4=4,a5=5,a6=6,a7=7,a8=8,a9=9。2)可以只给一部分元素赋值。例如:inta10=0,1,2,3,4;定义a数组有10个元素,但花括弧内只提供五个初值,这表示只给前五个元素赋初值,后面的五个元素值为0。3)在对全部数组元素赋初值时,可以不指定数组的长度。例如:inta5=1,2,3,4,5;也可以写成:inta=1,2,3,
47、4,5;3、一维数组元素的引用数组必须先定义,后使用。C51语言规定只能逐个引用数组元素而不能一次引用整个数组。数组元素的表示形式为:数组名下标下标可以是整型常量或整型表达式。如:a0=a5+a7-a2*3;第39页/共113页8.5.2二维数组1、二维数组定义的一般形式类型说明符数组名常量表达式常量表达式例如inta34,b510;定义a为3x4(3行4列)的数组,b为5x10(5行10列)的数组。数组元素为int型数据。注意不能写成:inta3,4,b5,10;C51语言对二维数组采用这样的定义方式,使我们可以把二维数组看作一种特殊的一维数组:它的元素又是一维数组。例如把a看做一个一维数组
48、,它有3个元素:a0、a1、a2,每一个元素又是一个包含4个元素的一维数组,如图8-17所示。图8-17二维数组第40页/共113页2、二维数组的初始化(1)按行赋初值数据类型数组名行常量表达式列常量表达式=第0行初值表,第1行初值表,最后1行初值表;(2)按二维数组在内存中的排列顺序给各元素赋初值数据类型数组名行常量表达式列常量表达式=初值表;3、二维数组元素的引用数组名行下标表达式列下标表达式(1)“行下标表达式”和“列下标表达式”,都应是整型表达式或符号常量。(2)“行下标表达式”和“列下标表达式”的值,都应在已定义数组大小的范围内。(3)对基本数据类型的变量所能进行的操作,也适合于相同
49、数据类型的二维数组元素。第41页/共113页8.5.3字符数组字符数组就是元素类型为字符型(char)的数组,字符数组是用来存放字符的。在字符数组中,一个元素存放一个字符,可以用字符数组来存储长度不同的字符串。1、字符数组的定义字符数组的定义和数组定义的方法类似。如charstr10,定义str为一个有10个字符的一维数组。2、字符数组置初值最直接的方法是将各字符逐个赋给数组中的各元素。如charstr10=M,I,A,N,Y,A,N,G,0;/*0表示字符串的结束标志。*/C语言还允许用字符串直接给字符数组置初值。其方法有以下两种形式:charstr10=ChengDu;charstr10=
50、BeiJing第42页/共113页8.5.4查表在C51编程中,数组的一个非常有用的功能之一就是查表。在实际单片机应用系统中,希望单片机能进行高精度的数学运算,但这并非单片机的特长,也不是完全必要的。许多嵌入式控制系统的应用中,人们更愿意用表格而不是数学公式,特别是在A/D转换中对模拟量的标定,使用表格查找法避免数值计算。在LED数码显示、LCD的汉字显示系统中,一般将字符或汉字的点阵信息存放在表格中,表格可事先计算好装入EPROM中。如:一个摄氏温度转换成华氏温度的例子。#defineucharunsignedcharucharcodetempt=32,34,36,37,39,41;/*数组