单片机技术及应用第九章 c51程序设计及应用_第1页
单片机技术及应用第九章 c51程序设计及应用_第2页
单片机技术及应用第九章 c51程序设计及应用_第3页
单片机技术及应用第九章 c51程序设计及应用_第4页
单片机技术及应用第九章 c51程序设计及应用_第5页
已阅读5页,还剩82页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、单 片 机 技 术 与 应 用 实 践第9章 C51程序设计及应用 单片机技术与应用实践教学提示 本章主要介绍了C51程序设计基础知识,包括C语言的数据类型、运算符、各种语句、数组与函数等知识,使大家具有单片机C语言程序设计的能力。教学目标了解C51与ASM51的区别。掌握C51程序设计基础知识。掌握C51的函数与数组的使用方法。学会用C语言编写简单单片机程序。单片机技术与应用实践9.1 C51程序设计基础知识 9.2 C51的函数与数组 9.3 实践训练单片机技术与应用实践9.1 C51程序设计基础知识 9.1.1 C51特点9.1.2 C51编程的例子9.1.3 C51的标识符和保留字 9

2、.1.4 C51的数据类型9.1.5 C51的常量9.1.6 变量9.1.7 C51的常用运算符9.1.8 C51的输入输出9.1.9 C51的基本语句单片机技术与应用实践9.1 C51程序设计基础知识 9.1.1 C51特点(1)对单片机的指令系统不要求了解,仅要求对51系列单片机的存贮器结构有初步了解;(2)寄存器分配、不同存贮器的寻址及数据类型等细节可由编译器管理;(3)程序有规范的结构,可分成不同的函数,这种方式可使程序结构化;(4)提供的库包含许多标准子程序,具有较强的数据处理能力;(5)由于具有方便的模块化编程技术,使已编好程序可容易地移植;(6)生成的目标代码的效率略低于汇编语言

3、程序。C51与ASM51相比,主要具有如下特点:单片机技术与应用实践9.1.2 C51编程的例子【例9-1】 编程使接在引脚上的LED发光。#include reg51.hsbit P1_0=P10;void main() P1_0=0; /* P1.0 灯亮*/ 这个程序的作用是让接在引脚上的LED点亮单片机技术与应用实践1. 编译预处理部分 程序的第一行是一个“文件包含”处理。程序中包含文件的目的是为了要使用P1这个符号,即通知C编译器,程序中所写的P1是指80C51单片机的P1端口而不是其他变量。 可根据不同的编程需要选择不同的头文件,一般情况下若只用简单控制,只需要下面3个头文件:#i

4、nclude reg51.h/*寄存器说明头文件*/#include /*输入/输出说明头文件*/#include /*部分特殊指令说明头文件*/ 在C语言里,如果直接写,C编译器并不能识别,而且也不是一个合法的C语言变量名,所以需给它另起一个名字,这里使用了Keil C的关键字sbit来定义。2. 说明与定义部分单片机技术与应用实践 函数是C51程序的基本单位,一个C51程序至少有一个主函数main(),也可以由一个主函数main()和若干个其他函数构成。函数由函数说明部分和函数体两部分构成。 (1) 函数说明部分由函数名、函数类型、函数属性、函数参数(形参)名和形式参数类型组成。 一个函数

5、名后面必须跟一对圆括号,即便没有任何参数也是如此。 (2) 函数体,即函数说明部分下面的大括号“”内的部分。函数体一般包括: 声明部分:在这部分中定义所用到的变量. 执行部分:由若干个语句组成。说明: void Delay() /*这是一个空函数,什么也不做,但它是合法的*/ 3. 函数单片机技术与应用实践(1)每个变量必须先定义后使用。(2)变量名由英文字母、数字和下划线构成,具体使用细则见小节。(3)C语言书写的格式自由,可以在一行写多个语句,也可以把一个语句写在多行。没有行号(但可以有标号),对书写的缩进没有要求。但是建议读者自己按一定的规范来写,可以给自己带来方便。(4)每个语句的最后

6、必须有一个分号“;”,分号是C语句的必要组成部分,此点尤其要注意与汇编语言区分。空语句可以只用一个分号表示,在分号前什么也不写,最好用花括号把分号括起来,即;,表示什么也不做但要耗费一定的时间,作用类似于汇编语言中的空操作指令NOP。4. 语句组成规则单片机技术与应用实践 可以用/*.*/的形式为C程序的任何一部分做注释,在“/*”开始后,一直到“*/”为止的中间的任何内容都被认为是注释。注意:Keil C也支持C+风格的注释,就是用“/”引导的后面的语句是注释.例:P1_0=!P1_0; /取反 这种风格的注释只对本行有效,而且书写比较方便,所以在只需要一行注释时,往往采用这种格式。的注释单

7、片机技术与应用实践C51程序结构如下:译预处理部分#include #define 标识符 字符串说明与定义部分sbit P1_0=P10; /*变量定义*/void delay(void); /*函数声明*/void main() /*主函数说明*/ 声明部分 执行部分void delay(int a) /*子函数说明*/ 声明部分 执行部分译预处理部分说明与定义部分主函数定义函数体子函数定义函数体单片机技术与应用实践9.1.3 C51的标识符和保留字 标识符用于标识语句、数据类型、函数、变量、数组、存储方式等对象,也就是这些对象的名字。在C语言中,标识符严格区分大小写。在C51编译器中,支

8、持标识符的前32位为有效标识,如果超长,则超长部分被舍弃。注意:变量名只能由字母、数字、下划线组成,且只能由字母和下划线开头。变量不能是C语言的保留字(或称关键字),即不能使用C语言系统已经有固定含义的单词。单片机技术与应用实践表9-1 C语言32个保留字表9-2 C51扩展13个保留字autobreakcasecharconstcontinuedefaultdodoubleelseenumexternfloatforgotoifintlongregisterreturnshortsignedstaticsizofstructswitchtypedefunionunsignedvoidvola

9、tilewhilebitsbitsfrsfr16databdataxdatacodeinterrupt reentran usingidatapdata单片机技术与应用实践9.1.4 C51的数据类型 数据在计算机内存中的存放情况由数据结构决定。C语言的数据结构是由数据类型决定的,C51的数据类型分为基本数据类型和组合数据类型,组合数据类型是由基本数据类型构造而成的。情况与标准C中的数据类型基本相同,标准C语言中基本的数据类型为char、int、short、long、float和double。组合数据类型有数组类型、结构体类型、共同体类型、枚举类型、指针类型和空类型。注意:在C51编译器中in

10、t和short相同,float和double相同。另外,C51中还有专门针对MCS-51单片机的特殊功能寄存器类型和位类型。单片机技术与应用实践表9-3 C51基本数据类型基本数据类型长 度取值范围unsigned char1B0255signed char1B-128+127unsigned int2B065535signed int2B-32768+32767unsigned long4B04294967295signed long4B-2147483648+2147483647float4B1.175494E-383.402823E+38bit1b0或1sbit1b0或1sfr1B025

11、5sfr162B065535单片机技术与应用实践1字符型char 长度为一个字节,用于存放一个单字节的数据。可以分为以下两种:(1) signed char:用于定义带符号字节数据,其字节的最高位为符号位,“0”表示正数,“1”表示负数,用补码表示,所能表示的数值范围是-128+127。(2) unsigned char:用于定义无符号字节数据或字符,可以存放一个字节的无符号数,其取值范围为0255。可以用来存放无符号数,也可以存放西文字符,一个西文字符占一个字节,在计算机内部用ASCII码存放。 默认为signed char。 单片机技术与应用实践2int整型 长度均为两个字节,用于存放一个

12、双字节数据。可分两种:(1) signed int:用于存放两字节带符号数,用补码表示,数的范围为-32768+32767。(2) unsigned int:用于存放两字节无符号数,数的范围为065535。 默认为signed int。 3long长整型 长度均为4字节,用于存放一个4字节数据。可分以下两种:(1) signed long:用于存放4字节带符号数,用补码表示,数的范围为-2147483648 +2147483647。(2) unsigned long:用于存放4字节无符号数,数的范围为04294967295。 默认为signed long。单片机技术与应用实践4 float浮点

13、型 float型数据的长度为4字节,格式符合IEEE754标准的单精度浮点型数据,包含指数和尾数两部分,最高位为符号位,“1”表示负数,“0”表示正数,其次的8位为阶码,最后的23位为尾数的有效数位,由于尾数的整数部分隐含为“1”,所以尾数的精度为24位。 5* 指针型 指针变量本身也是一个变量,在这个变量中存放的是指向另一个数据的地址。这个指针变量要占用一定的内存单元,对不同的处理器其长度不一样,在C51中它的长度一般为13个字节。单片机技术与应用实践6特殊功能寄存器型 C51提供的一种扩展数据类型,用于访问MCS-51单片机中的特殊功能寄存器数据,在C51中对特殊功能寄存器的访问必须先用s

14、fr或sfr16进行声明。可以分为以下两种:(1) sfr:sfr为字节型特殊功能寄存器类型,占一个内存单元,利用它可以访问MCS-51内部的所有特殊功能寄存器。(2) sfr16:sfr16为双字节型特殊功能寄存器类型,占用两个字节单元,利用它可以访问MCS-51内部的所有两个字节的特殊功能寄存器。单片机技术与应用实践7位类型 位类型也是C51提供的扩展数据类型,用于访问MCS-51单片机中的可寻址的位单元,但不能定义位指针也不能定义位数组。它们在内存中都只占一个二进制位,其值可以是“1”或“0”。支持以下两种位类型:(1) bit型:定义的位变量在C51编译器编译时,在不同时间位地址是可以

15、变化的。使用它可以定义一个位变量,但不能定义位指针,也不能定义位数组。(2) sbit型:定义的位变量必须与MCS-51单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位(C51内部的RAM及特殊功能寄存器中可位寻址空间)联系在一起,在C51编译器编译时,其对应的位地址是不可变化的。单片机技术与应用实践说明:在C51语言程序中,有可能会出现在运算中数据类型不一致的情况。C51允许任何标准数据类型的自动转换,除自动转换外,还可以通过强制类型转换符“()”对数据类型进行人为的强制转换,例:1/2=0,而,此知识点在编程时尤其需要注意。以上所述的数据类型中只有bit与unsigned char

16、两种数据类型可以直接转换成机器指令。所以C语言中使用的其他数据类型,虽然语句上很简单,但都要C51编译器用一系列机器指令处理这些数据类型。特别是对浮点数,处理起来更加复杂,将明显增加程序的长度与执行时间。因此应该避免使用复杂的数据类型。在编制C51程序时,应该尽可能使用无符号字符变量和位变量。单片机技术与应用实践9.1.5 C51的常量 整型常量也就是整型常数,根据其值范围在计算机中分配不同的字节数来存放。在C51中它可以表示成以下几种形式:(1) 十进制数。如123、-45、0等。(2) 十六进制数。以0 x开头表示,如0 x12、-0 x3B等。(3) 长整型。在C51中当一个整数的值达到

17、长整型的范围,则该数按长整型存放,在存储器中占4字节。另外,如一个整数后面加一个字母L,这个数在存储器中也按长整型存放,如12L在存储器中占4个字节。 常量是指在程序执行过程中其值不能改变的量。在C51中支持整型常量、浮点型常量、字符型常量和字符串型常量。1整型常量单片机技术与应用实践2浮点型常量 字符型常量是用单引号括起的字符,如2、A、n等。可以是可显示的ASCII字符,也可以是不可显示的控制字符。对不可显示的控制字符须在前面加上反斜杠“”组成转义字符。利用它可以完成一些特殊功能和输出时的格式控制。 浮点型常量也就是实型常数。有十进制表示形式和指数表示形式。 十进制表示形式又称定点表示形式

18、,由数字和小数点组成,如、。 指数表示又称科学记数法,常用于表示较大、较小的实型常量,指数形式为: 数字 .数字 e 整数如:6.021023,可表示成:6.02e+23或。-1.610-19,可表示成:。3字符型常量单片机技术与应用实践表9-4 C51转义字符及其含义转义字符含 义转义字符含 义n换行反斜杠线r回车单引号符f换页双引号符t水平制表(Tab)ddd13位八进制数所代表的字符v垂直制表xhh12位十六进制数所代表的字符b退格符(backspace)0空字符单片机技术与应用实践 4字符串型常量 字符串型常量由一对双引号括起来的零个或多个字符组成,双引号仅起定界作用,本身并不是字符串

19、中的内容。如“0123”、“Hello!”、“I am a student. ”、“”等。 注意:字符串常量与字符常量是不一样的,一个字符常量在计算机内只用一个字节存放,而一个字符串常量在内存中存放时不仅双引号内的每个字符占一个字节,而且系统会自动的在后面加一个转义字符“0”作为字符串结束符。“0”代表空操作字符,它不引起任何操作,也不会显示到屏幕上。 如字符串student在内存中的存储形式如下:student0 字符串student存储单元长度为8字节,字符串长度为7字节,需要注意的是,不能将字符串常量赋给一个字符变量,要用一个字符数组来存放 。单片机技术与应用实践9.1.6 变量 变量是

20、在程序运行过程中其值可以改变的量。一个变量由两部分组成:变量名和变量值。 在C51中,变量在使用前必须对变量进行定义,指出变量的数据类型和存储模式。以便编译系统为它分配相应的存储单元。定义的格式如下:存储种类 数据类型说明符 存储器类型 变量名1=初值,变量名2=初值; 在定义格式中除了数据类型和变量名是必要的,其他都是可选项。单片机技术与应用实践 在定义变量时,必须通过数据类型说明符指明变量的数据类型,指明变量在存储器中占用的字节数。可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是用typedef定义的类型别名。格式如下: typedefC51固有的数据类型说明符别名; 定义别

21、名后,就可以用别名代替数据类型说明符对变量进行定义,但不能作为变量使用,如: 正确用法:typedefintInteger;Integera=2;错误用法:typedefintInteger;Integer =2; 1数据类型说明符单片机技术与应用实践 变量名是C51区分不同变量,为不同变量取的名称。变量名命名符合变量名命名规则。 变量名有两种:普通变量名和指针变量名。它们的区别是指针变量名前面要带“*”号。2变量名(1)auto(2)extern(3)static (4)register3存储种类存储种类是指变量在程序执行过程中的作用范围。单片机技术与应用实践 存储器类型是用于指明变量所处的

22、单片机的存储器区域情况。存储器类型与存储种类完全无关。4存储器类型存储器类型描 述data直接寻址的片内RAM低128B(00H7FH),访问速度快bdata片内RAM的可位寻址区(20H2FH),允许字节和位混合访问idata间接寻址访问的片内RAM,允许访问全部片内RAM(00HFFH)pdata用MOVX Ri间接访问的片外RAM的低256B(00HFFH)表9-5 C51存储器类型【例9-2】变量定义存储种类和存储器类型相关情况。char datavarl;intidatavar2;bitbdatavar3;externfloatxdatavar4; 单片机技术与应用实践 在C51中,

23、用户对特殊功能寄存器进行访问时须通过sfr或sfr16类型说明符进行定义,定义时须指明它们所对应的片内RAM单元的地址。格式如下:sfr或sfr16特殊功能寄存器名=特殊功能寄存器地址常数; 5特殊功能寄存器变量【例9-3】特殊功能寄存器的定义。sfrPSW=0 xD0;sfrP1=0 x90;sfrSCON=0 x98;sfrIE=0 xA8;sfr16DPTR=0 x82;/DPL=82H,DPH=83Hsfr16T2=0 xCC;/定义8052定时器2,地址为T2L=CCH,T2H=CDH单片机技术与应用实践位类型符有:bit和sbit。 bit位类型符用于定义一般的可位处理位变量。它的

24、格式如下: bit 位变量名; 在格式中可以加上各种修饰符,但注意存储器类型只能是bdata、data、idata,而且只能是片内RAM的可位寻址区,严格来说只能是bdata。6位变量【例9-4】bit型变量的定义。bitdataa1;/*正确*/bitbdataa2;/*正确*/bitpdataa3;/*错误*/bitxdataa4;/*错误*/单片机技术与应用实践 sbit位类型符用于定义在可位寻址字节或特殊功能寄存器中的位,定义时须指明其位地址,可以是位直接地址,可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号。格式如下: sbit位变量名=位地址;6位变量【例9-5】sbit型

25、变量的定义。unsigned char bdata ib; sbit ib7=ib7 ; sbit OV=0 xd2;sfr P1=0 x90;sbit P1_0=P10; 单片机技术与应用实践 1运算符1) 赋值运算符 格式:变量=表达式; 执行时先计算出右边表达式的值,然后赋给左边的变量。 9.1.7 C51的常用运算符 学习C51运算符要注意3点:优先级、结合方向、与数学运算符的区别。例如:a = 0 xFF;/将常数十六进制数FF赋予变量ab = c = 33;/将33同时赋值给变量b、cd = e; /将变量e的值赋予变量df = a+b;/将变量a+b的值赋予变量f单片机技术与应用

26、实践2)算术运算符格式:表达式1算术运算符表达式2;+加或取正值运算符 -减或取负值运算符*乘运算符/除运算符%取余运算符+ 自增运算符- 自减运算符单片机技术与应用实践【例9-6】设有定义:int a = 1, b = 2, c; 则有:+i:i自增1后再参与其他运算(先增后用)。-i:i自减1后再参与其他运算(先减后用)。i+:i参与运算后,i的值再自增1(先用后增)。i-:i参与运算后,i的值再自减1(先用后减)。被执行的表达式表达式执行后a、c值acc= +a + b24c= a+ + b23c= - -a + b02c= a- - + b03单片机技术与应用实践3) 关系运算符 大于

27、=大于等于=小于等于6种关系运算符有不同优先级,左边优先级大于右边。关系表达式的一般形式如下:表达式1 关系运算符表达式2关系运算的结果为逻辑量,成立为真(1),不成立为假(0)。 关系运算用于比较两个数的大小,用关系运算符将两个表达式连接起来形成的式子,称为关系表达式。= =等于!=不等于单片机技术与应用实践 4)逻辑运算符 逻辑与:当条件式1与条件式2都为真时,结果为真(非0值),否则结果 为假(0值)。逻辑或:当条件式1与条件式2都为假时,结果为假(0值),否则结果为真(非0值)。逻辑非:当条件式为真(非0值),逻辑非后结果为假(0值);当条件式为假(0值),逻辑非后结果为真(非0值)。

28、 逻辑运算符则用于求条件式的逻辑值,用逻辑运算符将关系表达式或逻辑量连接起来的式子就是逻辑表达式。|逻辑或 条件式1 | 条件式2&逻辑与 条件式1 & 条件式2!逻辑非 !条件式单片机技术与应用实践5)位运算符【例9-7】用“右移”8位分离出16位数的高8位,用“与”0 x00FF分离出16位数的低8位。程序清单如下:#include#include#includevoid main (void) unsigned int data x=0 x238A; unsigned char data a,b; /*定义在内部RAM中的无符号8位字符*/ a=x8;/*取x的高8位*/ b=x&0 x

29、00FF;/*取x的低8位*/ &按位与|按位或按位异或按位取反右移单片机技术与应用实践6)复合赋值运算符复合赋值运算的一般格式如下:变量 复合运算赋值符表达式+=加法赋值+减法赋值*=乘法赋值/=除法赋值%=取模赋值&=逻辑与赋值|=逻辑或赋值=逻辑异或赋值=逻辑非赋值=右移位赋值 3| a = = 1; 整个条件表达式值为1,执行后a=1, b=7。 ( b = b + 5 ) &!(b 3|a = = 1); 整个条件表达式值为0,执行后 a=1,b=7。 104&!(10099)&31自左向右单目! + - + - type & * sizeof2自右向左算术* / %3自左向右+ -

30、4移位 5自左向右关系 =6自左向右= = !=7位逻辑&8自左向右9|10逻辑&11自左向右|12条件?:13自右向左赋值= += -= *= /= %= |= = &= = =14自右向左逗号,15自左向右单片机技术与应用实践 9.1.8 C51的输入与输出 在C51语言本身不提供输入和输出语句,输入和输出操作是由函数来实现的。当使用输入和输出函数时,须先用预处理命令#include 将该函数库包含到文件中。 在C51的一般I/O函数库中定义的I/O函数都是通过串行接口实现的,在使用I/O函数之前,应先对MCS-51单片机的串行接口进行初始化。选择串行口工作于方式2(8位自动重载方式),波

31、特率由定时器/计数器1溢出率决定。例如,设系统时钟为12MHz,波特率为2400,则初始化程序如下:SCON=0 x52;TMOD=0X20;TH1=0 xF3;TR1=1;单片机技术与应用实践 printf()函数的作用是通过串行接口输出若干任意类型的数据。 格式: printf(格式控制符,输出参数表); 格式控制符可由格式字符串和非格式字符串两种组成。格式字符串是以%开头的字符串,在%后面跟有各种格式字符,以说明输出数据的类型、形式、长度、小数位数等。 输出参数表为待输出的一系列数据项,其个数必须与格式化字符串所说明的输出参数个数一样多,各参数之间用“,”分开,且顺序一一对应。1格式输出

32、函数printf()单片机技术与应用实践表9-9 printf()格式控制符说明 说 明 符 功 能 %d 输出十进制有符号整数%ld 输出十进制有符号长整数%x或%X 以十六进制形式输出无符号的整数%u 输出十进制无符号整数%f 输出浮点数%s 输出字符串%c 输出单个字符%p 输出指针值%e或%E 输出指数形式的浮点数%0 以八进制形式输出无符号的整数单片机技术与应用实践scanf()函数的作用是通过串行接口实现数据输入。格式:scanf(格式控制符,地址列表);2格式输入函数scanf()注意点: (1)scanf()函数中没有精度控制,如scanf(%5.2f, &a);是非法的。(2

33、)scanf()中要求给出变量地址,如给出变量名则会出错。(3)在输入多个数值数据时,若“格式控制符”中没有非格式字符作输入数据之间的间隔,则可用空格、TAB或回车作间隔。(4)在输入字符数据时,若“格式控制符”中无非格式字符,则认为所有输入的字符均为有效字符。单片机技术与应用实践【例9-9】使用格式输入和输出函数的例子。源程序清单如下:#include /包含特殊功能寄存器库#include /包含I/O函数库void main(void) /主函数int x;float y;SCON=0 x52; /串口初始化TMOD=0 x20;TH1=0XF3;TR1=1;printf(input x

34、,y:n); /输出提示信息scanf(%d,%f,&x,&y); /输入x和y的值printf(n); /输出换行printf(%d+%f=%f,x,y,x+y); /按十进制形式输出while(1); /结束单片机技术与应用实践 在表达式的后边加一个分号“;”就构成了表达式语句。注意不能丢掉或输入为全角符号。9.1.9 C51的基本语句1表达式语句空语句通常用于以下两种情况:(1)在程序中为有关语句提供标号,用以标记程序执行的位置。例:loop:;gotoloop;(2)在用while、for语句构成的循环语句后面加一个分号,形成一个不执行其他操作的空循环体,常用它来写等待事件发生的程序。

35、这种结构通常用于对某位进行判断,当不满足条件则等待,满足条件则执行。 仅由一个分号“;”占一行形成一个表达式语句,这种语句称为空语句。 单片机技术与应用实践 复合语句是由若干条语句组合而成的一种语句,在C51中,用一个大括号“”将若干条语句括在一起就形成了一个复合语句,复合语句最后不需要以分号“;”结束,但它内部的各条语句仍需以分号“;”结束。复合语句的一般格式为:局部变量定义;语句l;语句2; 2复合语句 复合语句是允许嵌套的,在执行时,其中的各条单语句按顺序依次执行,整个复合语句在语法上等价于一条单语句。在复合语句内部语句所定义的变量,称为该复合语句中的局部变量,它仅在当前这个复合语句中有

36、效。单片机技术与应用实践if语句是C51中的一个基本条件选择语句,它有两种格式:(1)不带else的if语句,格式如下:if (表达式) 语句;如果if括号内的条件成立,则执行语句块,否则跳过该if语句,直接执行下一条语句。(2)带else的if语句,格式如下:if (表达式) 语句1;else语句2;当条件表达式成立时,就执行语句1,否则就执行语句2。3分支语句1)if语句单片机技术与应用实践if语句是C51中的一个基本条件选择语句,它有两种格式:(1)不带else的if语句,格式如下:if (表达式) 语句;如果if括号内的条件成立,则执行语句块,否则跳过该if语句,直接执行下一条语句。(

37、2)带else的if语句,格式如下:if (表达式) 语句1;else语句2;当条件表达式成立时,就执行语句1,否则就执行语句2。3分支语句1)if语句 注意:if- else语句允许嵌套,用来实现多方向条件分支,使用时应注意if和else的配对使用,else不能离开if单独出现,else总是与最近的且尚未配对的if配对。单片机技术与应用实践3分支语句1)if语句图9-2 不带else的if语句结构流程图9-3 带else的if语句结构流程单片机技术与应用实践【例9-10】 if语句的用法。 对学生成绩划分为AD,对应不同的百分制分数,要求根据不同的等级打印出它的对应百分数。if(grade=

38、 =A)printf(90100n);else if(grade= =B ) printf(8090n);else if(grade= =C ) printf(7080n);else if(grade= =D ) printf(6070n);else if(grade= =E) printf(60n);else printf(errorn);单片机技术与应用实践switch是C51中提供的专门处理多分支结构的多分支选择语句。格式如下:switch (表达式)case常量表达式1:语句1;break;case常量表达式2:语句2;break;case常量表达式n:语句n;break;defaul

39、t:语句n+1; 2)switch/case语句单片机技术与应用实践说明:(1)switch后面括号内的表达式,可以是整型或字符型常量表达式。(2)将switch后条件表达式的值与case后的各常量比较,转到值相等的那个case标号后的语句块执行,执行过程中一旦遇到break语句,则跳出switch语句;如果无一值相等,则执行default后的语句n+1;如果既无一值相等又没有default,则不执行switch中的任何语句。(3)每一个case常量表达式的值必须不同,否则会出现自相矛盾的现象。(4)case语句和default语句的出现次序对执行过程没有影响。(5)每个case语句后面可以有

40、break,也可以没有。有break语句,执行到break则退出switch结构;若没有,则会顺次执行后面的语句,直至遇到break或结束。(6)每一个case语句后面可以带一个语句,也可以带多个语句,还可以不带。语句可以用花括号括起,也可以不括。(7)多个case可以共用一组执行语句。单片机技术与应用实践【例9-11】switch/case语句的用法。 对学生成绩划分为AD,对应不同的百分制分数,要求根据不同的等级打印出它的对应百分数。switch(grade)case A: printf(90100n);break;case B: printf(8090n);break;case C: p

41、rintf(7080n);break;case D: printf(6070n);break;case E: printf(60n);break;default: printf(errorn); 单片机技术与应用实践1)goto语句 它是一个无条件的转向语句,只要执行到这个语句,程序指针就会跳转到goto后的标号所在的程序段。 格式: goto 语句标号; 其中的语句标号为一个带冒号的标识符。例如: void main(void)unsigned char a;start: a+;if (a= =10) goto end;goto start;end:; 4循环语句单片机技术与应用实践 whi

42、le语句在C51中用于实现当型循环结构。 格式: while(表达式) 语句;/*循环体*/ while语句后面的表达式是能否循环的条件,后面的语句是循环体。当表达式为非0(真)时,就重复执行循环体内的语句;当表达式为0(假),则中止while循环,程序将执行循环结构之外的下一条语句。 2) while语句特点:先判断条件,后执行循环体。在循环体中对条件进行改变,然后再判断条件,如条件成立,则再执行循环体,如条件不成立,则退出循环。如条件第一次就不成立,则循环体一次也不执行。 单片机技术与应用实践【例9-12】使用while语句实现计算并输出110的累加和。程序清单如下:#include #i

43、nclude void main(void)unsigned int i = 1;unsigned int sum= 0;/设初值SCON = 0 x50;/串行口方式 1,允许接收TMOD = 0 x20;/定时器 1 定时方式 2TCON = 0 x40;/设定时器 1 开始计数TH1 = 0 xE8; TL1 = 0 xE8; /11.0592MHz 1200 波特率TI = 1;TR1 = 1;/启动定时器while(i=10)sum += i;/累加printf (“%d sum=%dn”,i,sum); /输出结果,最后运行结果是 SUM=55 i+;while(1);/最后运行结

44、果是 SUM=55单片机技术与应用实践do - while语句在C51中用于实现直到型循环结构。格式: do 语句;/*循环体*/ while(表达式);3)do - while语句特点:先执行循环体中的语句,后判断表达式。如表达式成立(真),则再执行循环体,然后又判断,直到有表达式不成立(假)时退出循环,执行do-while结构的下一条语句。任何do-while的循环体至少会被执行一次。单片机技术与应用实践【例9-13】通过do-while语句实现计算并输出110的累加和。程序清单如下:#include #include void main(void)unsigned int i = 1;u

45、nsigned int sum= 0;/设初值SCON = 0 x50;/串行口方式 1,允许接收TMOD = 0 x20;/定时器 1 定时方式 2TCON = 0 x40;/设定时器 1 开始计数TH1 = 0 xE8; TL1 = 0 xE8; /11.0592MHz 1200 波特率TI = 1;TR1 = 1;/启动定时器dosum += i;/累加printf (“%d sum=%dn”,i,sum); /输出结果,最后运行结果是 SUM=55i+; while(i=10);while(1);单片机技术与应用实践格式: for(表达式1;表达式2;表达式3) 语句;/*循环体*/f

46、or语句后面带3个表达式,它的执行过程如下:(1)先求解表达式1的值。(2)求解表达式2的值,如表达式2的值为真,则执行循环体中的语句,然后执行下一步(3)的操作,如表达式2的值为假,则结束for循环,转到最后一步。(3)若表达式2的值为真,则执行完循环体中的语句后,求解表达式3,然后继续执行第下一步。(4)转到(2)继续执行。(5)退出for循环,执行下面的一条语句。 4)for语句 在for循环中,一般表达式1为初值表达式,用于给循环变量赋初值;表达式2为条件表达式,对循环变量进行判断;表达式3为循环变量更新表达式,用于对循环变量的值进行更新,使循环变量能不满足条件而退出循环。单片机技术与

47、应用实践【例9-14】用for语句实现计算并输出110的累加和。程序清单如下:#include #include void main(void)unsigned int i = 1;unsigned int sum= 0;/设初值SCON = 0 x50;/串行口方式1,允许接收TMOD = 0 x20;/定时器1定时方式 2TCON = 0 x40;/设定时器1开始计数TH1 = 0 xE8; TL1 = 0 xE8; /11.0592MHz 1200波特率TI = 1;TR1 = 1; /启动定时器for (i=1;i=10;i+) sum += i;/累加printf (“sum=%dn

48、”, sum);/输出结果,最后运行结果是 SUM=55while(1);单片机技术与应用实践 在一个循环的循环体中允许又包含一个完整的循环结构,这种结构称为循环的嵌套。外面的循环称为外循环,里面的循环称为内循环,如果在内循环的循环体内又包含循环结构,就构成了多重循环。在C51中,允许3种循环结构相互嵌套。5)循环的嵌套【例9-15】用嵌套结构构造一个延时程序。void Delay1Unit( void ) /用软件产生1s延时unsigned int i, j;for( i=0; i1000; i+ ) for( j0; j1000; j+ ); /通过实测,调整j循环次数,产生1s延时单片

49、机技术与应用实践 break和continue语句通常用于循环结构中,用来跳出循环结构。1)break语句 使用break语句还可以从循环体中跳出循环,提前结束循环而接着执行循环结构下面的语句。通常break语句总是与if语句连在一起,即满足条件时便跳出循环。它不能用在除了循环语句和switch语句之外的任何其他语句中。在多层循环中,break语句的作用是跳出本层循环。【例9-16】break语句的作用。While(1) c=getch(); printf(%cn, c); if(c= =27) break;/*判断若按Esc键则跳出循环*/ i+;printf(The No. is %dn,

50、 i);5break和continue语句单片机技术与应用实践 continue语句用在循环结构中,用于结束本次循环,跳过循环体中continue下面尚未执行的语句,直接进行下一次是否执行循环的判定。 continue语句和break语句的区别在于:continue语句只是结束本次循环而不是终止整个循环;break语句则是结束本层循环,不再进行条件判断。【例9-17】continue语句的作用。while(c!=0X0D)/*不是回车符则循环*/ c=getch(); if(c= =0 x1B) continue; /*若按Esc键,不输出便进行下次循环*/ printf(%cn, c);2)

51、continue语句单片机技术与应用实践 return语句一般放在函数的最后位置,用于终止函数的执行,并控制程序返回调用该函数时所处的位置。返回时还可以通过return语句带回返回值。return语句格式有两种:格式1:return;格式2:return (表达式); 如果return语句后面带有表达式,则要计算表达式的值,并将表达式的值作为函数的返回值。若不带表达式,则函数返回时将返回一个不确定的值。通常用return语句把调用函数取得的值返回给主调用函数。 6return语句单片机技术与应用实践 9.2 C51的函数与数组9.2.1 函数的定义9.2.2 函数的调用与声明9.2.3 数组单

52、片机技术与应用实践9.2.1 函数的定义函数定义的一般格式如下:函数类型 函数名(形式参数表) reentrant interrupt m using n形式参数说明局部变量定义函数体 9.2 C51的函数与数组 格式说明:函数类型是说明函数返回值的类型。函数体中能包含有局部变量的定义和程序语句,如函数要返回运算值则要使用return语句进行返回。在函数的号中也可以什么也不写,这就成了空函数。单片机技术与应用实践1函数类型 函数类型说明了所定义函数返回值的类型。如函数不需要返回值函数类型可写作“void” 。注意:函数体返回值的类型一定要和函数类型一致,否则会造成错误。2函数名 函数名是用户为

53、自定义函数取的名字,以便调用函数时使用。函数名的定义在遵循 C 语言变量名命名规则的同时,不能在同一程序中定义同名的函数,这将造成编译错误(同一程序中是允许有同名变量的,因为变量有全局变量和局部变量之分)。3形式参数表 形式参数是指调用函数时要传入到函数体内参与运算的变量,形参可以有一个、几个或没有,当不需要形式参数也就是无参函数,括号内可以为空或写入“void”表示,但括号不能少。单片机技术与应用实践 用于把函数定义为可重入函数,所谓可重入函数就是允许被递归调用的函数。函数的递归调用是指当一个函数正被调用尚未返回时,又直接或间接调用函数本身,只有重入函数才允许递归调用。4reentrant修

54、饰符注意:(1)用reentrant修饰的重入函数被调用时,实参表内不允许使用bit类型的参数。函数体内也不允许存在任何关于位变量的操作,更不能返回bit类型的值。(2)编译时,系统为重入函数在内部或外部存储器中建立一个模拟堆栈区,称为重入栈。重入函数的局部变量及参数被放在重入栈中,使重入函数可以实现递归调用。(3)在参数的传递上,实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数,但是可以使用定义的全局变量来进行参数传递。单片机技术与应用实践 单片机C语言扩展了函数的定义,使它能直接编写中断服务函数,不必考虑出、入堆栈的问题,从而提高了工作效率。在该修饰符中,m的

55、取值为031,对应的中断情况如表9-10所示。 5interrupt m修饰符中 断 号中 断 源中断向量0外部中断 00003H1定时器/计数器 0000BH2外部中断 10013H3定时器/计数器 1001BH4串行口0023H5定时器/计数器 2002BH表9-10 51系列芯片中断号和中断向量单片机技术与应用实践注意:(1)中断函数不能进行参数传递。(2) 中断函数没有返回值。在任何情况下都不能直接调用中断函数,否则会产生编译错误。如果在中断函数中调用了其他函数,则被调用函数所使用的寄存器必须与中断函数相同;否则会产生不正确的结果。(5)C51编译器对中断函数编译时会自动在程序开始和结

56、束处加上相应的内容,具体如下:在程序开始处对ACC、B、DPH、DPL和PSW入栈,结束时出栈。中断函数未加using n修饰符的,开始时还要将R0R1入栈,结束时出栈。如中断函数加using n修饰符,则在开始将PSW入栈后还要修改PSW中的工作寄存器组选择位。(6)C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量包含一个到中断函数入口地址的绝对跳转。(7)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其他程序调用。单片机技术与应用实践 修饰符using n用于指定本函数内部使用的工作寄存器组,其中n的取值为0

57、3,表示寄存器组号。 对于using n修饰符的使用,应注意以下两点:(1)加入using n后,C51在编译时自动在函数的开始处和结束处加入以下指令。PUSHPSW;标志寄存器入栈MOVPSW,#与寄存器组号相关的常量POPPSW;标志寄存器出栈(2)using n修饰符不能用于有返回值的函数。【例9-18】编写一个用于统计外中断0的中断次数的中断服务程序。extern intx;void int0( ) interrupt 0 using 1 x+; 6using n修饰符单片机技术与应用实践9.2.2 函数的调用与声明 函数定义好以后,要被其他函数调用才能被执行。C 语言的函数是能相互调

58、用的, 但在调用函数前,必须对函数的类型进行说明,就算是标准库函数也不例外。标准库函数的说明会被按功能分别写在不一样的头文件中,使用时只要在文件最前面用#include预处理语句引入相应的头文件即可。调用就是指一个函数体中引用另一个已定义的函数来实现所需要的功能,这时函数体称为主调用函数,函数体中所引用的函数称为被调用函数。 一个函数体中能调用数个其他的函数,这些被调用的函数同样也能调用其他函数,即函数允许嵌套调用,需要注意的是函数不允许嵌套定义。在C51中有一个函数是不能被其他函数所调用的,它就是主函数main( )。单片机技术与应用实践格式: 函数名(实参列表); “函数名”就是指被调用的

59、函数。实际参数表能为零或多个参数,多个参数时要用逗号隔开,每个参数的类型、位置应与函数定义时的形式参数一一对应,它的作用就是把实际参数传到被调用函数中的形式参数,如果类型不对应就会产生错误。调用的函数是无参函数时不写参数,但不能省略后面的括号。 按照函数调用在主调函数中出现的位置,函数调用方式有3种:(1)函数语句。把被调用函数作为主调用函数的一个语句。如printf (“Hello Keil C51!n”); (2)函数表达式。函数被放在一个表达式中,以一个运算对象的方式出现。这时的被调用函数要求带有返回语句,以返回一个明确的数值参数表达式的运算。如temp = Count( ); (3)函

60、数参数。被调用函数作为另一个函数的参数。如x=fun2(fun1(5);1函数的调用单片机技术与应用实践 调用函数前要对被调用的函数进行声明。如果在函数调用之前没有对函数进行声明,则编译系统会把第一次遇到的该函数形式(函数定义或函数调用)作为函数的声明,并将函数类型默认为int型。标准库函数只要用#include引入已写好说明的头文件,在程序中就能直接调用函数了。格式:extern函数类型函数名(形式参数表); 函数的声明是把函数的名字、函数类型以及形参的类型、个数和顺序通知编译系统,以便调用函数时系统进行对照检查。函数的声明后面要加分号。也可以把这些写到“文件名.h”的文件中用#includ

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论