《51系列单片机程序设计》由会员分享,可在线阅读,更多相关《51系列单片机程序设计(87页珍藏版)》请在金锄头文库上搜索。
1、2010/5/18单片机原理与接口技术第四章第四章 MCS-51系列单片机程序设计系列单片机程序设计4.1 汇编语言程序设计概述n计算机是仿照人的思维方式顺序执行一条条指令来完成特定计算机是仿照人的思维方式顺序执行一条条指令来完成特定任务的机器,计算机程序因此被定义为指令或语句的任务的机器,计算机程序因此被定义为指令或语句的“有序有序集合集合”,程序设计是指编写计算机程序的过程程序设计是指编写计算机程序的过程。n汇编语言是用指令助记符等表示的计算机指令,汇编语言是用指令助记符等表示的计算机指令,采用汇编语采用汇编语言编写的程序被称为汇编语言程序言编写的程序被称为汇编语言程序。汇编语言程序具有代
2、码。汇编语言程序具有代码效率高(编译后的指令代码占用存储空间小)和执行时间短效率高(编译后的指令代码占用存储空间小)和执行时间短等优势和特点。等优势和特点。n由于单片机的存储器等资源有限,单片机应用程序中经常需由于单片机的存储器等资源有限,单片机应用程序中经常需要面对硬件操作,且对程序执行的时间有较为严格的要求或要面对硬件操作,且对程序执行的时间有较为严格的要求或限制。因此,限制。因此,汇编语言程序设计汇编语言程序设计是单片机应用系统设计的重是单片机应用系统设计的重要基础之一。要基础之一。 4.1 汇编语言程序设计概述1、汇编语言的特点、汇编语言的特点: 汇编语言的特点归纳如下:汇编语言的特点
3、归纳如下: 助记符指令与机器指令一一对应;助记符指令与机器指令一一对应; 程序代码效率高,占用存储空间小,运行速度快,程序代码效率高,占用存储空间小,运行速度快,汇编语言程序往往是最优化的程序;汇编语言程序往往是最优化的程序; 助记符指令(汇编指令)与计算机硬件联系紧密,助记符指令(汇编指令)与计算机硬件联系紧密,要求编程人员对计算机硬件较为熟悉;要求编程人员对计算机硬件较为熟悉; 汇编语言程序缺乏通用性,移植性较差。汇编语言程序缺乏通用性,移植性较差。 4.1.1 汇编语言的特点及语句格式汇编语言的特点及语句格式4.1 汇编语言程序设计概述2、汇编语言的语句格式、汇编语言的语句格式MCS-5
4、1系列单片机汇编语言的语句格式如下:系列单片机汇编语言的语句格式如下: : ; 标号是汇编语句地址的符号表示。标号是汇编语句地址的符号表示。 用于规定该语句所执行的操作。用于规定该语句所执行的操作。 操作数为汇编指令的操作提供数据或地址操作数为汇编指令的操作提供数据或地址 注释是指对一条汇编语句或一段汇编语言程序注释是指对一条汇编语句或一段汇编语言程序的说明,以增加汇编语言程序的可读性。的说明,以增加汇编语言程序的可读性。 4.1.1 汇编语言的特点及语句格式汇编语言的特点及语句格式4.1 汇编语言程序设计概述 1、起始地址定位伪指令、起始地址定位伪指令ORG 格式:格式:标号标号:ORG 操
5、作数操作数 说明:其功能是指出紧接其后的指令的目标代码的说明:其功能是指出紧接其后的指令的目标代码的第一个字节在程序存储器中的绝对地址。例如:第一个字节在程序存储器中的绝对地址。例如: ORG 0030H START:MOV A,#33H .n即定义标号即定义标号START表示的起始地址值为表示的起始地址值为0030H,该,该段程序的指令代码从该地址开始顺序存放。段程序的指令代码从该地址开始顺序存放。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述 2、赋值伪指令、赋值伪指令EQU 格式:字符名称格式:字符名称 EQU 操作数操作数 说明:该指令用于说明:该指令用于字符
6、名称赋值字符名称赋值。在同一个源。在同一个源程序中,任何一个字符名称只能赋值一次。且程序中,任何一个字符名称只能赋值一次。且一旦赋值之后,整个源程序中该字符的值就固一旦赋值之后,整个源程序中该字符的值就固定不变了。例如:定不变了。例如: ADPORT EQU 1001Hn即给字符名称即给字符名称ADPORT 赋值赋值16进制数进制数1001H。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述 3、数据地址赋值伪指令、数据地址赋值伪指令DATA格式:字符名称格式:字符名称 DATA 操作数操作数说明:说明:DATA伪指令的功能与伪指令的功能与EQU伪指令相似,不同之伪指令
7、相似,不同之处在于处在于DATA伪指令所定义的字符名称伪指令所定义的字符名称可先使用后定可先使用后定义(赋值),也可先定义(赋值)后使用义(赋值),也可先定义(赋值)后使用。在程序。在程序中它常用来定义(赋值)中它常用来定义(赋值)数据地址数据地址。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述 4、字节数据赋值伪指令、字节数据赋值伪指令DB格式:格式:标号:标号: DB数据表(字节)数据表(字节)说明:该伪指令用于定义(赋值)若干说明:该伪指令用于定义(赋值)若干字节数据表字节数据表(固定常数),并存放在指定地址单元开始的程序(固定常数),并存放在指定地址单元开始的
8、程序存储器中。存储器中。例如:例如: ORG 0050HTABLE:DB 99H,88H 即表示在地址即表示在地址0050H(标号(标号TABLE)开始定义(赋)开始定义(赋值)两个字节数据(值)两个字节数据(99H,88H)。)。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述 5、双字节数据赋值伪指令、双字节数据赋值伪指令DW格式:格式:标号:标号: DW数据表(双字节)数据表(双字节)说明:该伪指令与说明:该伪指令与DB伪指令的不同之处在于伪指令的不同之处在于DW定义(赋值)定义(赋值)的是双字节数据,而的是双字节数据,而DB定义(赋值)的是单字节数据。定义(赋值
9、)的是单字节数据。高高8位数据安排在低地址单元,低位数据安排在低地址单元,低8位数据安排在高地址单元位数据安排在高地址单元。6、预留空间定义伪指令、预留空间定义伪指令DS格式:格式:标号:标号: DS 操作数操作数说明:该伪指令的作用是通知汇编程序,从指定的地址单元开说明:该伪指令的作用是通知汇编程序,从指定的地址单元开始(通常由标号指定首地址),保留由操作数(常数或表达始(通常由标号指定首地址),保留由操作数(常数或表达式)规定的字节空间。式)规定的字节空间。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述 7、位地址赋值伪指令、位地址赋值伪指令BIT格式:字符名称格
10、式:字符名称 BIT 位地址位地址说明:该伪指令给字符名称说明:该伪指令给字符名称赋予位地址赋予位地址(片内(片内RAM和和SFR中的中的位地址),常用于位操作程序中。例如:位地址),常用于位操作程序中。例如: FLAG BIT 20H 即将位地址即将位地址20H赋予字符名称赋予字符名称FLAG。8、定义汇编结束伪指令、定义汇编结束伪指令END格式:格式:标号:标号:END说明:汇编结束伪指令说明:汇编结束伪指令END的作用是的作用是通知汇编程序,汇编源程通知汇编程序,汇编源程序到此结束序到此结束。在一个汇编程序中,只允许出现一条。在一个汇编程序中,只允许出现一条END伪指伪指令,且必须安排在
11、整个源程序的末尾处。令,且必须安排在整个源程序的末尾处。 4.1.2 汇编语言伪指令汇编语言伪指令 4.1 汇编语言程序设计概述4. 2 基本程序结构基本程序结构1、顺序结构程序2、分支结构程序3、循环结构程序4、子程序5、中断程序基本程序结构4. 2 基本程序结构基本程序结构 顺序结构是各类程序中最简单的,也是最基本的顺序结构是各类程序中最简单的,也是最基本的程序结构。顺序结构程序的特征是程序结构。顺序结构程序的特征是整个程序段没有整个程序段没有任何转移指令任何转移指令。主要由数据传递类指令和数据运算。主要由数据传递类指令和数据运算类指令组成,通常用于执行数据传送和较为简单的类指令组成,通常
12、用于执行数据传送和较为简单的算术或逻辑运算任务。算术或逻辑运算任务。 4.2.1 顺序结构顺序结构4. 2 基本程序结构基本程序结构例例4-1,将内部,将内部 RAM 中中 20H 单元和单元和 30H 单元的无符号数单元的无符号数相加,存入相加,存入R0(高位)和(高位)和R1(低位)中。源程序如下:(低位)中。源程序如下:MOV A,20H ;取出被加数;取出被加数ADD A,30H ;两数相加;两数相加MOV R1,A ;低位存入;低位存入R1CLR A ;ADDC A,#00H ;取进位标志;取进位标志MOV R0,A ;高位存入;高位存入R0RET 4.2.1 顺序结构顺序结构4.
13、2 基本程序结构基本程序结构 分支结构程序利用分支结构程序利用条件转移指令条件转移指令,使程序在执行,使程序在执行某一指令后(产生测试条件),根据所规定的条件某一指令后(产生测试条件),根据所规定的条件满足与否改变其后程序执行的顺序(产生分叉),满足与否改变其后程序执行的顺序(产生分叉),即即根据判断条件的成立与否来确定程序的走向根据判断条件的成立与否来确定程序的走向。分。分支结构程序的特征是程序段中有控制转移类指令支结构程序的特征是程序段中有控制转移类指令(条件转移指令)。(条件转移指令)。依据程序分叉的数目,可将分支结构程序细分为依据程序分叉的数目,可将分支结构程序细分为单分支选择结构单分
14、支选择结构和和多分支选择结构多分支选择结构两类。两类。 4.2.2 分支结构分支结构4. 2 基本程序结构基本程序结构1、单分支选择结构、单分支选择结构 当程序的判断仅有两个出口(分叉),即两者选一时,称为当程序的判断仅有两个出口(分叉),即两者选一时,称为单分支结构。通常用条件判断指令来选择并确定程序的出口。单分支结构。通常用条件判断指令来选择并确定程序的出口。例例4-3.设内部设内部RAM 40H和和41H单元中存放单元中存放2个个8位无符号二进制位无符号二进制数,试编程找出其中的大数存人数,试编程找出其中的大数存人30H单元中。源程序如下:单元中。源程序如下: MOV A,40H CJN
15、E A,41H,LOOP ;取取2个数进行比较个数进行比较 LOOP: JNC LOOP1 ;根据根据CY值,判断单分支出值,判断单分支出 MOV A,41H ;41H单元中是大数单元中是大数 LOOP1: MOV 30H,A ;40H单元中是大数单元中是大数 RET 4.2.2 分支结构分支结构4. 2 基本程序结构基本程序结构2、多分支选择结构、多分支选择结构 当程序的判别部分有两个以上的出口(分叉)时,当程序的判别部分有两个以上的出口(分叉)时,称为多分支选择结构。称为多分支选择结构。例例4-4,设变量,设变量X的值存放在内部的值存放在内部RAM的的30H单元中,单元中,编程求解下列函数
16、式,将求得的函数值编程求解下列函数式,将求得的函数值Y存人存人40H单单元。元。 X1 (X100) Y 0 (10X100) X一一1 (X10) 4.2.2 分支结构分支结构4. 2 基本程序结构基本程序结构 MOV A,30H ;取自变量取自变量X值值 CJNE A,#10,LOOP ;与与10比较,比较,A中值不改变中值不改变LOOP: JC LOOP2 ;若;若X100,转,转LOOP3 MOV 40H,00H ;因;因10X100,故,故Y=0 SJMP EXITLOOP2: DEC A ;因;因X100,故,故Y=X1 MOV 40H, AEXIT: RET4. 2 基本程序结构
17、基本程序结构 在程序设计中,遇到一段程序需要多次重复执行的情况,在程序设计中,遇到一段程序需要多次重复执行的情况,通常应该采用循环结构程序。通常应该采用循环结构程序。n1、循环结构程序组成、循环结构程序组成 循环结构程序由初始化、循环处理、循环控制和循环结束循环结构程序由初始化、循环处理、循环控制和循环结束4部分组成。部分组成。 (1)初始化部分初始化部分 初始化部分设置循环处理之前的初始状态,如初始化部分设置循环处理之前的初始状态,如循环次数、循环次数、变量初值、地址指针初值变量初值、地址指针初值等。等。 (2)循环处理部分循环处理部分 循环处理部分又称循环处理部分又称循环体循环体,是,是重
18、复执行的数据处理程序段重复执行的数据处理程序段,它是循环程序的它是循环程序的核心部分核心部分(功能主体)。(功能主体)。 4.2.3 循环结构循环结构4. 2 基本程序结构基本程序结构 (3)循环控制部分循环控制部分控制部分控制部分控制循环继续与否控制循环继续与否。(4)结束部分结束部分结束部分对循环程序全部执行结束后的结果进行结束部分对循环程序全部执行结束后的结果进行分析、处理和保存。分析、处理和保存。循环结构程序一般分为循环结构程序一般分为“单重循环单重循环”和和“多重循多重循环环”两类,循环次数的控制有多种方式,当循环次两类,循环次数的控制有多种方式,当循环次数已知时,可采用循环次数计数
19、器控制循环;若循数已知时,可采用循环次数计数器控制循环;若循环次数未知时,可按条件满足与否控制循环。环次数未知时,可按条件满足与否控制循环。 4.2.3 循环结构循环结构4. 2 基本程序结构基本程序结构n 2循环程序设计循环程序设计在一个循环程序的循环体中不包含另外的循环结构称为单重在一个循环程序的循环体中不包含另外的循环结构称为单重循环。循环。例例4-5,设某字符串以回车符(,设某字符串以回车符(0DH)为结束标志,并存放在)为结束标志,并存放在内部内部RAM40H单元开始的连续存储单元之中,编写测试字符单元开始的连续存储单元之中,编写测试字符串长度的汇编语言程序。串长度的汇编语言程序。
20、编程思路编程思路 为测试字符串(为测试字符串(0DH)的长度,应使用逐个)的长度,应使用逐个字符依次与回车符字符依次与回车符(ODH)比较的方法。为此需要设一个字符比较的方法。为此需要设一个字符串指针和一个长度计数器,字符串指针用于指定字符,长度串指针和一个长度计数器,字符串指针用于指定字符,长度计数器用于累加字符串的长度。如比较不相等,则长度计数计数器用于累加字符串的长度。如比较不相等,则长度计数器和字符串指针都加器和字符串指针都加1,以继续往下比较;如果比较相等,则,以继续往下比较;如果比较相等,则表示该字符为回车符,字符串结束,长度计数器的值就是字表示该字符为回车符,字符串结束,长度计数
21、器的值就是字符串的长度。符串的长度。 4.2.3 循环结构循环结构4. 2 基本程序结构基本程序结构n 2循环程序设计循环程序设计 程序如下:程序如下: MOV R7,0FFH ;设长度计数器初值设长度计数器初值 MOV R0,3FH ;字符串指针字符串指针 初值初值LOOP:INC R7 INC R0 CJNE R0,ODH,LOOP RET 4.2.3 循环结构循环结构4. 2 基本程序结构基本程序结构 4.2.4 子程序结构子程序结构 在在编编写写程程序序过过程程中中,如如果果遇遇到到在在几几个个程程序序段段中中都都需需要要执执行行某某段段相相同同程程序序的的情情况况(功功能能独独立立)
22、,为为减减少少编编程程工工作作量量和和节节省省程程序序存存储储空空间间,就就应应该该采采用用子子程程序序结结构构,将将重重复复执执行行的的相相同同程程序序段段编编写写成成为一个子程序为一个子程序(功能子程序)。(功能子程序)。返回返回调用调用断点断点子程序子程序主程序主程序4. 2 基本程序结构基本程序结构MAIN: ;进入主程序;进入主程序MOV R0,#03H ;设置入口参数(延时;设置入口参数(延时1)ACALL SUBPRO ;调用子程序;调用子程序 ;子程序返回,继续执行主程序;子程序返回,继续执行主程序;#;子程序入口地址(子程序名称);子程序入口地址(子程序名称):SUBPRO;
23、功能:延时子程序(延时时间由;功能:延时子程序(延时时间由R0初值设置)初值设置);入口参数:;入口参数:R0内存放延时计数初值内存放延时计数初值 ;出口参数:无;出口参数:无;使用寄存器:;使用寄存器:R0、R1;#SUBPRO:MOV R1,#03HDJNZ R1,$ DJNZ R0,SUBPRORET ;子程序返回;子程序返回 END 4.2.3 子程序结构子程序结构4. 2 基本程序结构基本程序结构单片机中断程序设计主要有以下三个方面:单片机中断程序设计主要有以下三个方面:1、中断向量设置、中断向量设置2、中断初始化、中断初始化3、中断服务程序、中断服务程序 4.2.5 中断程序结构中
24、断程序结构4. 2 基本程序结构基本程序结构例例4-7,设,设89C51单片机外中断单片机外中断0(EX0)下降沿有效,每次进入)下降沿有效,每次进入中断服务程序,要求将中断服务程序,要求将89C51单片机的单片机的P1.7P1.0取反。取反。主程序如下:主程序如下:ORG 0000H STAR:AJMP MAIN ;主程序原始入口;主程序原始入口 ORG 0003H ;外部中断;外部中断0中断向量中断向量 AJMP EXTR ;跳转到;跳转到EX0中断服务子程序实际入中断服务子程序实际入口地址口地址 ORG 0030H MAIN: SETB IT0 ;主程序实际入口,边沿触发设置;主程序实际
25、入口,边沿触发设置 SETB EX0 ;外部中断;外部中断0允许允许 SETB EA ;总中断允许;总中断允许HERE: AJMP HERE ;等待再次进入中断服务程序;等待再次进入中断服务程序 4.2.5 中断程序结构中断程序结构4. 2 基本程序结构基本程序结构中断服务子程序:中断服务子程序: ORG 1200H EXTR:PUSH PSW ;保护现场;保护现场 CPL A ;累加器;累加器A数据取反数据取反 MOV P1,A ;数据输出至;数据输出至P1端口端口 POP PSW ;恢复现场;恢复现场 RETI ;中断返回;中断返回 4.2.5 中断程序结构中断程序结构4.3 汇编语言程序
26、设计实践汇编语言程序设计实践汇编语言程序设计的一般步骤如下:汇编语言程序设计的一般步骤如下: 建立数学模型建立数学模型 用适用的数学方法描述所需要解决的问题;用适用的数学方法描述所需要解决的问题; 确定算法确定算法 将数学模型转化为适合单片机处理(顺序执行)将数学模型转化为适合单片机处理(顺序执行)的形式,采用绘制程序流程图等方法表示程序设计的思路和的形式,采用绘制程序流程图等方法表示程序设计的思路和依据。依据。 编写源程序编写源程序 采用模块化设计方法,合理划分功能模块,采用模块化设计方法,合理划分功能模块,分配存储器和分配存储器和I/O端口(依据硬件电路)等资源,确定各模块端口(依据硬件电
27、路)等资源,确定各模块内各程序段的结构,编写源程序文件。内各程序段的结构,编写源程序文件。 汇编及调试汇编及调试 在集成开发环境的支持下,汇编语言源程序在集成开发环境的支持下,汇编语言源程序经汇编生成目标程序文件,并通过调试以及对运行结果的分经汇编生成目标程序文件,并通过调试以及对运行结果的分析,修正源程序中的错误,达到预期的设计目标。析,修正源程序中的错误,达到预期的设计目标。 所所谓谓查查表表,就就是是根根据据变变量量x在在表表格格中中查查找找y,使使yf(x)。函函数数值值y事事先先根根据据变变量量x的的取取值值范范围围计计算算出出,并并按按一一定定规规律律编编成成表表格格存存放放在在计
28、计算算机机的的程程序序存存储储器器中中。当当用用户户程程序序中中需需要要用用这这些些数数据据时时,直直接接按按编编排排的的索索引引值值(或或程程序序号号)寻寻找找答答案案。这这样样编编写写的的程程序序称称为为查查表表程程序序。查查表表程程序序是是一一种种常常用用程程序序,广广泛泛应应用用于于LED显显示示器器控控制制、智智能能化化仪仪表表控控制制、打打印印机机打打印印以以及及数数据据转转换换等等功功能能程程序序中中,具具有有程程序序简简单单、执执行行速速度度快快等等优优点点。查查表表程程序序有有多多种种结结构构形形式式,下下面面举举例例介介绍绍一一种种常常用用的的查查表程序。表程序。4.3.1
29、 查表程序查表程序4.3 汇编语言程序设计实践汇编语言程序设计实践4.3.1 查表程序查表程序 例例4-8,将,将16进制数转换成进制数转换成ASCII码的子程序。假设码的子程序。假设16进制数存放在进制数存放在R0中低中低4位,要求将转换后的位,要求将转换后的ASCII码送回到码送回到R0中。中。 设计思路:己知设计思路:己知0-9的的ASCII码为码为30H一一39H,AF的的ASCII码为码为41H一一46H。对十六进制数而言,。对十六进制数而言,0-F是连续的,是连续的,而对应的而对应的ASCII码不连续,查表方法对解决此类问题十分有码不连续,查表方法对解决此类问题十分有效。根据题意,
30、子程序的入口参数和出口参数均通过效。根据题意,子程序的入口参数和出口参数均通过R0传传递,表中所有的值都是单字节,表格长度为递,表中所有的值都是单字节,表格长度为16字节。字节。4.3 汇编语言程序设计实践汇编语言程序设计实践查表子程序:查表子程序:MOV A,R0 ;读取主程序通过;读取主程序通过R0传送的十六进制数传送的十六进制数ANL A,0FH ;屏蔽高;屏蔽高4位,取出低位,取出低4位位ADD A,#02H ;设置变址值(依据表首地址与查表指;设置变址值(依据表首地址与查表指 令所处位置)令所处位置)MOVC A,A+PC ;查表指令(获得对应的;查表指令(获得对应的ASCII码)码
31、)MOV R0,A :通过:通过R0将查表结果传递给主程序将查表结果传递给主程序RETTAB:DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H 程序中因为程序中因为“MOVC A,A+PC”指令与表格首址相隔两个字节,指令与表格首址相隔两个字节,故变址调整值为故变址调整值为2,程序中对应变量,程序中对应变量x的函数值的函数值y为单字节。为单字节。4.3.1 查表程序4.3 汇编语言程序设计实践汇编语言程序设计实践 在在51系列单片机指令集中有单字节的算术运算(加、系列单片机指令集中有单字节的算术运算(加、
32、减、乘、除)指令,但在实际程序设计中经常会遇到减、乘、除)指令,但在实际程序设计中经常会遇到多多字节算术运算问题字节算术运算问题,需要通过编制专门的功能子程序解,需要通过编制专门的功能子程序解决此类问题。决此类问题。例例4-9,多字节无符号数加法运算。假设,多字节无符号数加法运算。假设R0中存放被中存放被加数低位字节地址指针,加数低位字节地址指针,R1中存放加数低位字节地址指中存放加数低位字节地址指针,针,R2中存放字节数,多字节算术运算一般从低字节中存放字节数,多字节算术运算一般从低字节(低位)到高字节(高位)的顺序依次进行。(低位)到高字节(高位)的顺序依次进行。 4.3.2 算术运算程序
33、4.3 汇编语言程序设计实践汇编语言程序设计实践汇编源程序如下:汇编源程序如下:ADDBIN:CLR C LOOP1: MOV A,R0;取被加数取被加数 ADDC A,R1;两数相加,带进位两数相加,带进位 MOV R0,A INC R0 INC R1 DJNZ R2,LOOP1;未加完转未加完转LOOP1 JNC LOOP2;无进位转无进位转LOOP2 MOV R0,#0lH RET LOOP2: DEC R0 RET 4.3.2 算术运算程序4.3 汇编语言程序设计实践汇编语言程序设计实践例例4-10,BCD码多字节加法运算。假设码多字节加法运算。假设R0中存放被加数中存放被加数低位字节
34、地址指针,低位字节地址指针,R1中存放加数低位字节地址指针,中存放加数低位字节地址指针,R2中存放字节数。中存放字节数。 BCDADD: MOV 20H,R0 MOV 23H,R2 CLR C LP0: MOV A,R0 ;取被加数;取被加数 ADDC A,R1 ;两数相加;两数相加 DA A ;十进制调整;十进制调整 MOV RO,A INC R0 ;指针加;指针加1 DJN2 R2,LP0 ;做完加法否;做完加法否4.3.2 算术运算程序 MOV R2,23H JNC RETURN ;有无进位;有无进位 MOV R0,#01H INC R3 RETURN: MOV R0,#20H RET
35、4.3 汇编语言程序设计实践汇编语言程序设计实践例例4-11,如如图图4-2所所示示,MCS-51单单片片机机的的P1作作为为输输出出端端口口,连连接接8只只发发光光二二极极管管。按按该该电电路路工工作作原原理理,P1口口各各位位输输出出“0”时时,将将发发光光二二极极管管点点亮亮;P1口口各各位位输输出出“1”使使发发光光二二极极管管灭灭。分分析析下下述述汇汇编编程程序序运运行行后后,8个个发发光光二二极极管管点点亮的规律。亮的规律。4.3.3 I/O接口控制程序图图4-2 P14-2 P1口口驱动驱动LEDLED示意示意图图4.3 汇编语言程序设计实践汇编语言程序设计实践主程序:主程序:
36、LP:MOV P1,7EH LCALL DELAY MOV P1,0BDH LCALL DELAY MOV P1,#0DBH LCALL DELAY MOV P1,0E7H LCALL DELAY MOV P1,0DBH LCALL DELAY MOV P1,0BDH LCALL DELAY SJMP LP子程序:子程序: DELAY:MOV R2,0FAH L1:MOV R3,# 0FAH L2:DJNZ R3,L2 DJNZ R2,L1 RET4.3.3 I/O接口控制程序接口控制程序 例例4-12: 按照图按照图4-2所示的电路,试编写控制发光二极管指所示的电路,试编写控制发光二极管指示
37、灯移位的程序,要求示灯移位的程序,要求8个发光二极管依次亮一个,循环左个发光二极管依次亮一个,循环左移,一个一个地亮,直至循环。相关源程序如下移,一个一个地亮,直至循环。相关源程序如下: MOV A,7FH L1:MOV P1,A RL A LCALL DELAY;与例;与例4-11的延时程序相同的延时程序相同 SJMP Ll 4.3.3 I/O接口控制程序4.3 汇编语言程序设计实践汇编语言程序设计实践一个函数的定义由类型、函数名、参数表和函数体四部分一个函数的定义由类型、函数名、参数表和函数体四部分组合而成。一个函数在程序中可以三种形态出现:函数定组合而成。一个函数在程序中可以三种形态出现
38、:函数定义、函数调用、函数说明。义、函数调用、函数说明。 C51函数的一般格式为:函数的一般格式为:类型类型 函数名(参数表)函数名(参数表)参数说明;参数说明; 数据说明部分;数据说明部分;/注释注释 执行语句部分;执行语句部分; 4.4.1 C51程序结构程序结构4.4 面向面向51单片机的单片机的C语言程序语言程序4.4.2 C51数据类型数据类型数据类型数据类型位型(位型(bit)字符型(字符型(char)整型(整型(int)长整型(长整型(long)浮点型(浮点型(float)双精度浮点型(双精度浮点型(double)数组类型(数组类型(array)结构体类型(结构体类型(struc
39、t)共用体(共用体(union)枚举(枚举(enum)基本类型基本类型构造类型构造类型指针类型指针类型空类型空类型1. 数据类型数据类型KEIL C51编译器支持的数据类型、长度和值域如表编译器支持的数据类型、长度和值域如表4-1所列。所列。数据类型数据类型长度长度/Byte值域值域BitUnsigned charSigned charUnsigned intSigned intUnsigned longSigned longFloatDouble11224440,10255-128127065 535-32 76832 76704 294 967 295-2 147 483 6482 147
40、 483 6471.176E-383.40E+38(6位数字)1.176E-383.40E+38(10位数字)表表4-1 KEIL C51 数据类型数据类型4.4.2 C51数据类型数据类型1. 数据类型数据类型 C语言的数据有语言的数据有常量常量、变量变量之分。之分。常量是在程序运行的常量是在程序运行的过程中,其值不能改变的量过程中,其值不能改变的量;变量是在程序运行中,其值可变量是在程序运行中,其值可以改变的量以改变的量。一个变量由两部分构成:变量名和变量值,每。一个变量由两部分构成:变量名和变量值,每一个变量都有一个变量名,在内存中占据一定的存储单元一个变量都有一个变量名,在内存中占据一
41、定的存储单元(地址),并在该内存单元中存放该变量的值。(地址),并在该内存单元中存放该变量的值。 常量定义:常量定义:#define CONST 44 /定义常量符号定义常量符号CONST,值为,值为44 变量定义:变量定义:char t; /定义字符型变量,变量名为定义字符型变量,变量名为t C语言中习惯上以小写字母定义变量,以大写字母定义语言中习惯上以小写字母定义变量,以大写字母定义常量。另外由于常量。另外由于51单片机的寄存器及数据总线为单片机的寄存器及数据总线为8位所以在位所以在定义变量时,定义变量时,应尽可能使用无符号字符型应尽可能使用无符号字符型。 4.4.2 C51数据类型数据类
42、型1. 数据类型数据类型-常量和变量常量和变量 2C51数据存储类型数据存储类型 51系列单片机的程序存储器与数据存储器是分开的,系列单片机的程序存储器与数据存储器是分开的,并独立寻址。并独立寻址。51系列单片机共有如下四个存储空间:系列单片机共有如下四个存储空间: 片内程序存储空间;片内程序存储空间; 片外程序存储空间;片外程序存储空间; 片内数据存储空间;片内数据存储空间; 片外数据存储空间。片外数据存储空间。 C语言编程时在对常量、变量的定义时,要注意不语言编程时在对常量、变量的定义时,要注意不同功能的常量、变量应存储在不同的存储区,在定义变同功能的常量、变量应存储在不同的存储区,在定义
43、变量或常量时要定义成不同的存储类型(量或常量时要定义成不同的存储类型(data, bdata, idata, pdata, xdata, code)。)。 4.4.2 C51数据类型数据类型存储类型存储类型存储空间存储空间databdataidatapdataxdatacode内部内部RAM低低128单元,可直接寻址单元,可直接寻址片内片内RAM位寻址区位寻址区内部内部RAM,间接寻址,间接寻址片外片外RAM,256字节字节片外片外RAM,64KB代码存储区,代码存储区,64KB表表4-2 C51存储类型与单片机存储空间对应关系存储类型与单片机存储空间对应关系4.4.2 C51数据类型数据类型
44、2C51数据存储类型数据存储类型 3特殊功能寄存器的定义特殊功能寄存器的定义 在在51单片机内部单片机内部RAM的高的高128字节,分散着字节,分散着21个特殊个特殊功能寄存器(功能寄存器(SFR),为了能直接访问这些特殊功能寄),为了能直接访问这些特殊功能寄存器,存器,KEIL C51提供一种自主形式的定义方法,此种提供一种自主形式的定义方法,此种方法与标准方法与标准C语言不兼容,只适用于对语言不兼容,只适用于对8051系列单片机系列单片机进行定义。这种定义的方法引入关键字进行定义。这种定义的方法引入关键字“sfr”,如:,如: sfr TMOD=0x89;/*定时定时/计数器方式控制寄存器
45、地址计数器方式控制寄存器地址为为89H*/。sbit:特殊功能位声明特殊功能位声明,sbit led1=P10;4.4.2 C51数据类型数据类型将其视为将其视为片外数据存储器片外数据存储器的一个单元,利用的一个单元,利用#define语句进行语句进行定义:定义:#define PORTA XBYTE0x0020 /*将将PORTA定义为外部定义为外部I/O口,地址为口,地址为0x0020*/例例: 要通过地址要通过地址0x0020向外部写数据向外部写数据0x01,下面分别用汇编语下面分别用汇编语言和言和C语言编程实现:语言编程实现:汇编语言实现:汇编语言实现:MOV DPTR,#0020HM
46、OV A,#01HMOVX DPTR,AC语言实现:语言实现: #define PORTA XBYTE0x0020PORTA=0x01;4.4.2 C51数据类型数据类型4片外扩展片外扩展I/O口口 C51的运算符主要包括算术运算、关系运算、逻的运算符主要包括算术运算、关系运算、逻辑运算、位操作运算、自增减运算及复合运算等。其辑运算、位操作运算、自增减运算及复合运算等。其运算符与表达式与运算符与表达式与C语言要求基本一致。语言要求基本一致。4.4.3 C51运算符和表达式运算符和表达式4.4.2 C51数据类型数据类型4.4.3 C51运算符和表达式运算符分类运算符表达式示例优先关系(高低)算
47、术运算符* 乘法/ 除法% 求余+ 加法或正值- 减法或负值a+b;(a+b)*c;!算术运算符关系运算符逻辑运算符赋值运算符关系运算符 大于= 大于或等于= 测试等于!= 测试不等于c(a+b)a=bc逻辑运算符& 逻辑与| 逻辑或! 逻辑非c=a&bb=!a位操作运算符& 按位与| 按位或 按位异或 按位取反 位右移c=a&ba=b1自增减运算符+ 自加1- 自减1+ii+复合运算符算术运算符及位操作运算符复合使用i+=3 C语言程序主要有顺序、选择和循环三种结构。顺序结语言程序主要有顺序、选择和循环三种结构。顺序结构即语句逐条执行,是最基本、最简单的程序结构。选择构即语句逐条执行,是最基
48、本、最简单的程序结构。选择结构和循环结构的相关控制语句分别介绍如下:结构和循环结构的相关控制语句分别介绍如下: 1选择结构语句及流程图选择结构语句及流程图 在选择结构中常见的控制语句有:在选择结构中常见的控制语句有:if, else if, switch-case。其中。其中if、else if主要应用在串行多分支结构程序控主要应用在串行多分支结构程序控制中,而制中,而switch-case主要用于并行从分去结构程序的控主要用于并行从分去结构程序的控制中。图制中。图4-3所示为串行多分支结构流程图。所示为串行多分支结构流程图。 4.4.4 C51流程控制语句流程控制语句4.4 面向面向51单片
49、机的单片机的C语言程序语言程序图图4-3 串行多分支结构流程图串行多分支结构流程图串行多分支结构串行多分支结构语句的基本形式:语句的基本形式:1) if(表达式表达式)语句;语句;/当括号内的表达式为真,则执行当括号内的表达式为真,则执行内的语句;内的语句;2) if(表达式表达式)语句语句1;else语句语句2;/当括号内的表达式为真,则执行当括号内的表达式为真,则执行内内的语句,否则执行语句的语句,否则执行语句2;3) if(表达式表达式1)语句语句1; else if(表达式表达式2)语句语句2; else语句语句n;/哪一个表达式条件为真,则执行对应哪一个表达式条件为真,则执行对应中的
50、语句,但判断时表达式中的语句,但判断时表达式1的优先的优先级最高,只有条件不满足时,才继续向下判断。级最高,只有条件不满足时,才继续向下判断。4) if(表达式表达式1) if(表达式表达式2) 语句语句1; else 语句语句2; /if的嵌套使用,只有当表达式的嵌套使用,只有当表达式1为真时,才进行下一级判断。为真时,才进行下一级判断。1选择结构语句及流程图选择结构语句及流程图 并行多分支结构图图4-4并行多分支结构流程图并行多分支结构流程图switch-case语句表达形式:语句表达形式:switch(表达式表达式1) case 值值1:语句:语句1;break; case 值值2:语句
51、:语句2;break; case 值值N:语句:语句N;break; default: 语句语句N+1; 1选择结构语句及流程图选择结构语句及流程图4.4.4 C51流程控制语句流程控制语句2 2循环结构语句及流程图循环结构语句及流程图 循环结构中常见的控制语句主要有循环结构中常见的控制语句主要有while, do while, for等。等。 While语句的一般形式为:语句的一般形式为:while(条件条件)语句;语句;,图图4-5 while结构流程图结构流程图4.4.4 C51流程控制语句流程控制语句 与与while相比,相比,do while的区别就是行执行循环语句后的区别就是行执行
52、循环语句后判断循环条件。语句的形式为:判断循环条件。语句的形式为:do语句;语句;while(条件条件) 。流程图如图流程图如图4-6所示。所示。 图图4-6 do while结构流程图结构流程图 4.4.4 C51流程控制语句流程控制语句2循环结构语句及流程图循环结构语句及流程图for(表达式表达式1;表达式;表达式2;表达式;表达式3) 语句;语句;,for语句在执语句在执行时共有行时共有5个过程,具体执行过程如下:个过程,具体执行过程如下: 对表达式进行赋值初始化对表达式进行赋值初始化 判断表达式判断表达式2是否为真,若为真则进行循环,若为假则是否为真,若为真则进行循环,若为假则退出循环
53、退出循环 若表达式若表达式2为真,则执行循环体内的语句,并求解表达为真,则执行循环体内的语句,并求解表达式式3 回到第二步,再判断表达式回到第二步,再判断表达式2 退出退出for 循环循环4.4.4 C51流程控制语句流程控制语句2循环结构语句及流程图循环结构语句及流程图 51单片机内部资源主要是特殊功能寄存器或单片机内部资源主要是特殊功能寄存器或SFR寻址,寻址,在在KEIL C51中提供了定义这些寄存器的头文件中提供了定义这些寄存器的头文件,在进行,在进行C语言编程,应在源程序的开始处包含头文件,语言编程,应在源程序的开始处包含头文件,#include 。内部资源的。内部资源的C语言编程主
54、要介绍外中语言编程主要介绍外中断、定时器和串行口编程。断、定时器和串行口编程。 C51编译器支持在编译器支持在C源程序中直接开发中断程序,采用源程序中直接开发中断程序,采用特殊语法定义中断函数,定义方法如下:特殊语法定义中断函数,定义方法如下: 返回值返回值 函数名函数名 interrupt n using m n代表单片机的中断编号,代表单片机的中断编号, n的范围(的范围(04)依次为外部)依次为外部中断中断0、定时、定时/计数器计数器0、外部中断、外部中断1、定时、定时/计数器计数器1、串行口、串行口中断。中断。m表示通用寄存器组的的选择,范围(表示通用寄存器组的的选择,范围(0-3)。
55、)。4.4.5 单片机资源与C语言编程 4.4.6 C语言程序实例语言程序实例 在进行单片机的在进行单片机的C语言编程时,其步骤与汇编语言编语言编程时,其步骤与汇编语言编程没有区别,首先要了解单片机系统硬件电路的设计,尤程没有区别,首先要了解单片机系统硬件电路的设计,尤其单片机的外部资源的地址编码,当了解了单片机系统的其单片机的外部资源的地址编码,当了解了单片机系统的硬件电路后,就可以根据要求画出流程图,合理分配内部硬件电路后,就可以根据要求画出流程图,合理分配内部资源进行编程,下面以一个数据采集的实例进行说明。资源进行编程,下面以一个数据采集的实例进行说明。 图4-7为ADC0809与51系
56、列单片机(89S51)的接口电路原理图,要求顺序采集ADC0809的8个通道的模拟量,并存放在数组ADCON中 图4-7 单片机数据采集原理图 由电路原理图可以看到,ADC0809的启动信号START由译码器Y1与单片机RD信号经或非门产生,输出使能信号OE由Y1与单片机WR信号经或非门产生,3/8译码器的输入接到P2.5至P2.7,ADC0809的通道选择 信 号 接 到 单 片 机 的 地 址 线 A0至 A2, 因 此 得 到ADC0809的8个输入通道的地址为2000H2007H,ADC0809转换结束标志EOC经非门后接到单片机的P3.2口。 C51源程序如下:#include /包
57、含头文件#include#define uchar unsigned char#define IN0 XBYTE0x2000 /设置ADC0809通道0的地址sbit ad_over=P32;/转换结束标志定义void ad0809(uchar idata *x) /采集函数uchar i;uchar xdata *ad_adr;ad_adr=&IN0;for(i=0;i8;i+)/循环采集8个通道*ad_adr=0;/启动ADwhile(ad_over=0);/查询转换结束标志xi=*ad_adr;/存储结果ad_adr+;/下一通道 void main(void)/主函数static uc
58、har ad10;ad0809(ad);#include#define uchar unsigned char#define uint unsigned intsbit D0=P10;uint a;void main() D0=0;a=59000;while(a-);D0=1;a=50000;while(a-);#includedelay_10ms(unsigned t) unsigned int i,j; for(i=0;it;i+)for(j=0;j1880;j+);void main() while(1) delay_10ms(100);P0=0xfe;delay_10ms(100);P
59、0=0xfd;delay_10ms(100);P0=0xfb;Delay_10ms(100);P0=0xf7;delay_10ms(100);P0=0xef;delay_10ms(100);P0=0xdf;delay_10ms(100);P0=0xbf;delay_10ms(100);P0=0x7f; #include /52系列单片机头文件系列单片机头文件#define uint unsigned int /宏定义宏定义#define uchar unsigned charvoid delayms(uint); /声明子函数声明子函数uchar x; /声明无符号数原变量声明无符号数原变量x
60、(占(占1B)void main() /主函数主函数P1=0xfe;/赋初值赋初值11111110 while(1) /大循环大循环for(x=0;x8;x+)/左移左移8次次 delayms(500); /延时延时500毫秒毫秒 P1=P11; /左移左移1位位 /左移结束,灯全部亮左移结束,灯全部亮for(x=0;x1|0x80 ; /右移右移1位,并设定最高位为位,并设定最高位为1 /右移结束,灯全部灭右移结束,灯全部灭 无论是单片机汇编语言还是C语言编程,都需要借助一个软件工具,一般也称为开发环境,目前有很多专业的单片机软件开发工具,下面为读者介绍一种单片机的集成开发环境,Keil u
61、Vision2集成开发环境。 Keil Vision2集成开发环境是德国Keil公司针对51系列单片机应用系统开发而推出的基于32位 windows环境下,以51单片机为开发目标,以高效率C语言为基础的集成开发平台。本节主要介绍Keil C51 V7.20版,它主要包括C51交叉编译器和A51宏汇编等工具,还内嵌了单片机仿真调试软件,可以让用户采用模拟仿真和实时在线仿真两种方式对目标系统进行开发。软件仿真时,它可以查看程序变量,内部存储单元。以及模拟和查看单片机I/O口,定时器及中断的工作方式和设置,甚至可以仿真单片机的串行通信。4.5 Keil Vsion2 集成开发环境集成开发环境双击安装
62、程序setup,进入安装模式。它与一般软件安装过程类似。值得注意的是,当出现提示“Install Support.全新安装”和“Update Current Installation升级安装”时,选择“Install Support.全新安装”。并且在出现提示“Full version”和“Eval version”时,选择“Full version”。随后依次点击“Next-Yes-选择安装目录-Next-”输入序列号、姓名、公司”等。安装完成后在Windows桌面上会出现一个Keil Vision2的图标 。 4.5.1 Keil uVsion2安装 在Keil uVsion2支持下开发单
63、片机应用系统软件,一般需要经过以下的几个过程:创建工程工程选项卡设置新建源文件添加源文件到工程编译仿真调试下载。4.5.2 Keil Vsion2的使用(1) Keil C51 Vision2界面与工程创建(如图4-8)图图4-8 Keil C51 Vision2 的工作界面的工作界面 创建一个新工程,首先须在菜单栏“Project”菜单中选择“New Project”选项(补充图1),此时会弹出“创建新工程”对话框(补充图2),可填入工程名,随后单击保存。 创建新工程创建新工程 补充图补充图1 保存工程项目(保存工程项目(Test) 补充图补充图2 接着出现选择单片机芯片型号对话框(补充图3
64、)。本例选择单片机,随后点击“确定”,新工程创建即告完成。 选择芯片型号选择芯片型号 补充图补充图3 建立源程序文档建立源程序文档 补充图补充图4 点击保存按钮点击保存按钮 补充图补充图5 图4-9 源程序文档加入所建工程项目中图4-10 工程文件设置 Target选项卡设置选项卡设置补充图补充图6 Output选项卡的设置选项卡的设置 补充图补充图7 保存文件格式保存文件格式 补充图补充图8(练习(练习.A)添加源程序添加源程序 补充图补充图9设定完成后单击“确定”返回主界面,工程文件设置完毕。当工程建立并设置完成之后,接下来就可以对工程进行编辑(源程序文本)。以下面简单的汇编源程序为例:
65、ORG 0000H ;P1口输出实验 LJMP STARTORG 0100HSTART: MOV A,#0FEHLOOP: RL A MOV P1,A LCALL DELAY ;延时 0.1秒 JMP LOOPDELAY: MOV R1,#127 ;延时0.1秒DEL1: MOV R2,#200DEL2: DJNZ R2,DEL2 DJNZ R1,DEL1 RET END 当源程序文件编辑输入完成之后,单击工具栏保存文件,随后单击工具栏的编译按钮“ ”对文件进行编译。如果源程序没有语言错误,将会在文件存储目录生成,OBJ文件,同时如果设置正确,会生成.HEX文件,并且在工程主界面下方会出现无语
66、法错误的提示,如图4-19。但源程序没有语法错误并不能保证就是正确可行的,还需要对程序进行调试。程序通过编译程序通过编译 补充图补充图10 图4-11 进入调试仿真环境 此外Keil软件在程序调试时可随时观察寄存器及端口、存储器的变化图4-22中,左面窗口显示了系统内部寄存器。点击任务栏“Peripherals” 选项,可以选择打开中断,I/O口,定时器等状态窗口。另外点击调试工具栏的“观察窗口”可以查看程序中所设变量的变化情况如图4-23所示,便于程序的调试。另外我们也注意到,在调试工具栏中,还有其它调试工具的按钮,此处不再一一列举,读者可在调试的过程加强对其的理解。灵活掌握调试工具,有助于
67、高效率地进行程序的调试。调试工具栏调试工具栏 补充图补充图11图图4-22 查看端口状态窗口查看端口状态窗口 变量观察窗口变量观察窗口 补充图补充图12 图4-13 SLISP编程界面 4.5.3 程序代码下载(1)根据实际连接方式选择通讯端口,如LPT1表示利用并口连接。(2)选择速率,默认为FAST。(3)选择单片机型号,如AT89S52。(4)选择目标文件,单击文件按钮,选择编译后的.HEX或.BIN文件。(5)在编程选项中如图选中重载文件,擦除,FLASH,校验芯片ID码前面的复选框。(6)点击编程按钮,即可将程序下载到单片机中。程序下载到单片机后,即可观察硬件的运行情况,并根据实际运
68、行再次修改程序。需要提出注意的是,由于AT89S52单片机的ISP接口是与P1口共用的,所以在运行P1口的程序时应将下载线取下否则可能会影响程序的运行。4.5.3 程序代码下载思考练习题思考练习题1. 什么是伪指令?伪指令有何作用?什么是伪指令?伪指令有何作用? 伪指令与指令集中的指令有何区别伪指令与指令集中的指令有何区别2. 计算机可以执行的指令是什么指令?汇编语言程序和计算机可以执行的指令是什么指令?汇编语言程序和C语言程序如何变换成为语言程序如何变换成为由可执行的指令构成的文件?由可执行的指令构成的文件?3. 编写一段完整规范的编写一段完整规范的51汇编语言程序,将某汇编语言程序,将某5
69、1单片机片内单片机片内35H一一55H单元的数单元的数据传送到外部据传送到外部RAM以以3000H为首址的存储区中。为首址的存储区中。4. 试编写一段汇编语言程序,使某试编写一段汇编语言程序,使某51单片机片内单片机片内30H单元的内容与外部单元的内容与外部RAM2200H单元的内容交换。单元的内容交换。5. 设某设某51单片机片内单片机片内5AH单元有一变量单元有一变量x,请编写计算以下分段函数式的汇编语,请编写计算以下分段函数式的汇编语言程序,并将计算结果存入片内言程序,并将计算结果存入片内5BH单元中。单元中。 2X1 (X100) Y 0 (10X100) X一一2 (X10)6. 编
70、写汇编语言程序,实现某编写汇编语言程序,实现某51单片机单片机P1口外接的口外接的8个发光二极管的流水(跑马)个发光二极管的流水(跑马)灯控制(时间间隔自行定义并采用调用延时子程序方式实现)。灯控制(时间间隔自行定义并采用调用延时子程序方式实现)。7. 假设有假设有5个双字节压缩码,顺序存放在外部个双字节压缩码,顺序存放在外部RAM从从BARF(2000H)开)开始的单元中(高位存放在高地址字节)。编写汇编语言程序,实现上述数据求始的单元中(高位存放在高地址字节)。编写汇编语言程序,实现上述数据求和并将结果存放到和并将结果存放到SUM(51单片机片内单片机片内RAM)开始的单元中(未给出的条件)开始的单元中(未给出的条件可自行定义并加以注释)。可自行定义并加以注释)。8. 编写汇编语言程序和编写汇编语言程序和C51程序,将存放在表首地址以标号程序,将存放在表首地址以标号TAB表示的数据表中表示的数据表中存放的存放的8个单字节数逐个取出并求其平均值(未给出的条件可自行定义并加以个单字节数逐个取出并求其平均值(未给出的条件可自行定义并加以注释)。注释)。