单片机原理与接口技术(第3版)[李晓林]-第4章PPT课件_第1页
单片机原理与接口技术(第3版)[李晓林]-第4章PPT课件_第2页
单片机原理与接口技术(第3版)[李晓林]-第4章PPT课件_第3页
单片机原理与接口技术(第3版)[李晓林]-第4章PPT课件_第4页
单片机原理与接口技术(第3版)[李晓林]-第4章PPT课件_第5页
已阅读5页,还剩121页未读 继续免费阅读

下载本文档

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

文档简介

1,23.05.2020,单片机原理与接口技术,第4章MCS-51C程序设计,2,23.05.2020,(1)熟悉C51语法基础和程序结构。(2)掌握C51结构化程序设计。(3)掌握C51对单片机硬件的访问方法。(4)掌握C51函数定义与调用。(5)了解汇编语言和C51的混合编程。,本章教学要求,3,23.05.2020,4.1C51概述4.2C51语法基础4.2.1标识符和关键字4.2.2数据类型4.2.3运算符和表达式4.2.4程序结构,本章目录,4.3C51对MCS-51单片机的访问4.3.1存储类型4.3.2存储模式4.3.3对特殊功能寄存器的访问4.3.4对存储器和并行口的访问4.3.5位地址访问4.3.6中断函数,4,23.05.2020,4.4C51结构化程序设计4.4.1顺序结构程序4.4.2选择结构程序4.4.3循环结构程序,4.5C51程序设计实例4.5.1查表程序4.5.2单片机内/外部资源应用程序设计4.5.3C51语言和MCS-51汇编语言混合编程4.5.4编程优化的概念习题与思考题,本章目录,5,23.05.2020,4.1C51概述,C语言是一种通用的程序设计语言,其代码率高,数据类型及运算符丰富,位操作能力强,适用于各种应用的程序设计。使用C语言进行单片机应用系统开发,具有编程灵活、调试方便、目标代码编译效率高的特点。C语言也是目前使用最广的单片机应用系统编程语言。由C语言编程的单片机应用程序,称为单片机C语言程序。MCS-51系列单片机开发系统的编译软件可以对51单片机C语言源程序进行编译,称为C51编译器。在C51编译软件中可进行51单片机C语言程序的调试。,6,23.05.2020,1)扩展了专门访问MCS-51单片机硬件的数据类型;2)存储类型按MCS-51单片机存储空间分类;3)存储模式遵循存储空间选定编译器模式;4)指针分为通用指针和存储器指针;5)函数增加了中断函数和再入函数。,4.1C51概述,C51编译器针对MCS-51单片机硬件在下列几方面对ANSIC进行了扩展。,7,23.05.2020,使用具有C51编译扩展功能的C语言进行MCS-51单片机应用系统的开发编程,简称C51编程。C51编程具有以下特点。1)可管理内部寄存器和存储器的分配,编程时,无需考虑不同存储器的寻址和数据类型等细节问题;2)程序由若干函数组成,具有良好的模块化结构、可移植性好、便于项目维护管理;3)有丰富的子程序库可直接引用,从而大大减少用户编程工作量,提高编程效率;4)与汇编语言交叉编程。用汇编语言编写与硬件有关的程序,用C51编写与硬件无关的运算程序,充分发挥两种语言的长处,提高开发效率。,4.1C51概述,8,23.05.2020,C51编程和汇编语言编程过程一样。单片机C语言源程序经过编辑、编译、连接后生成目标程序(.BIN和.HEX)文件,然后运行即可。调试51单片机C语言程序可用KeilC51编译器。注意,使用C51编程可以取代繁琐的汇编语言编程,但仍需要了解MCS-51单片机的硬件结构。所以对于单片机系统的开发应采用汇编语言与C51混合编程的方法更为有效。,4.1C51概述,9,23.05.2020,4.2C51语法基础,标识符用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等。标识符由字符串、数字和下划线等组成,应该注意的是第一个字符必须是字母或下划线,不能用数字开头,如“1_a”是错误的,编译时会有错误提示。在C51编译器中,只支持标识符的前32位为有效标识。C51语言是区分大小写的一种高级语言,如“a_1”和“A_1”是两个完全不同的标识符。,4.2.1标识符和关键字,-标识符,10,23.05.2020,C51中有些库函数的标识符是以下划线开头的,所以一般不要以下划线开头命名用户自定义标识符。标识符在命名时应当简单,含义清晰,这样有助于阅读理解程序。关键字则是编程语言保留的特殊标识符,它们具有固定的名称和含义,在程序编写中不允许将关键字另做他用。C51中的关键字除了有ANSIC标准的32个关键字外,还根据MCS-51单片机的特点扩展了相关的关键字。C51关键字如表5-1所示。在C51的文本编辑器中编写C程序,系统可以把保留关键字以不同颜色显示,如int关键字的默认颜色为天蓝色。,4.2.1标识符和关键字,-关键字,11,23.05.2020,4.2.1标识符和关键字,-关键字列表,12,23.05.2020,4.2.1标识符和关键字,-关键字列表,13,23.05.2020,4.2.1标识符和关键字,-关键字列表,14,23.05.2020,4.2.2数据类型,C51具有ANSIC的所有标准数据类型。其基本数据类型包括:char、int、short、long、float和double。对C51编译器来说,short类型和int类型相同,double类型和float类型相同。,-C51的数据类型,15,23.05.2020,除此之外,为了更加有利地利用MCS-51的结构,C51还增加了一些特殊的数据类型,包括bit、sbit、sfr、sfr16。数据类型如表4-2所示。,4.2.2数据类型,-C51的数据类型,16,23.05.2020,char类型的长度是1B,通常用于定义处理字符数据的变量或常量。unsignedchar类型用字节中所有的位表示数值,可以表达的数值范围是0255。signedchar类型用字节中最高位表示数据的符号,0表示正数,1表示负数,负数用补码表示,能表示的数值范围是-128+127。unsignedchar常用于处理ASCII字符或用于处理小于或等于255的整型数。,1char字符类型,4.2.2数据类型,-char字符类型,17,23.05.2020,2int整型,int整型长度为2B,用于存放一个双字节数据。signedint表示的数值范围是-32768+32767,字节中最高位表示数据的符号,0表示正数,1表示负数。unsignedint表示的数值范围是065535。,4.2.2数据类型,-int整型,18,23.05.2020,long长整型长度为4B,用于存放一个四字节数据。分有符号long长整型signedlong和无符号long长整型unsignedlong,默认值为signedlong类型。signedint表示的数值范围是-2147483648+2147483647,字节中最高位表示数据的符号,0表示正数,1表示负数。unsignedlong表示的数值范围是04294967295。,3long长整型,4.2.2数据类型,-long长整型,19,23.05.2020,4float浮点型,float浮点型在十进制中具有7位有效数字,是符合IEEE-754标准(32)的单精度浮点型数据,占用4B。具有24位精度。,4.2.2数据类型,-float浮点型,20,23.05.2020,5*指针型,指针型本身就是一个变量,在这个变量中存放着指向另一个数据的地址。这个指针变量要占据一定的内存单元,对不同的处理器长度也不尽相同,在C51中它的长度一般为13个字节。,4.2.2数据类型,-*指针型,21,23.05.2020,bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量。它的值是一个二进制位,不是0,就是1,类似一些高级语言中的boolean型数据的True和False。,6bit位标量,4.2.2数据类型,-bit位标量,22,23.05.2020,7sfr特殊功能寄存器,sfr是一种C51扩充数据类型,占用一个内存单元,值域为0255。利用它可以访问MCS-51单片机内部的所有特殊功能寄存器。如用sfrP1=0 x90定义一个特殊功能寄存器变量“P1”,0 x90是指51单片机的P1端口地址90H,变量P1即指51单片机的P1端口。在后面的语句中可以用P1=255(对P1端口的所有引脚置高电平)之类的语句操作特殊功能寄存器。,4.2.2数据类型,-sfr特殊功能寄存器,23,23.05.2020,8.sfr1616位特殊功能寄存器,sfr16也是一种C51扩充数据类型,用于定义存在于MCS-51单片机内部RAM的16位特殊功能寄存器,如定时器T0和T1。sfr16型数据占用2个内存单元,取值范围为065535。,4.2.2数据类型,-16位特殊功能寄存器,24,23.05.2020,sbit也是一种C51扩充数据类型,利用它可以访问芯片内部RAM中的可寻址位或特殊功能寄存器中的可寻址位。定义方法有如下三种:(1)sbit位变量名=位地址将位的绝对地址赋给位变量,位地址必须位于80HFFH(特殊功能寄存器的位地址)之间。(2)sbit位变量名=特殊功能寄存器名位位置当可寻址位位于特殊功能寄存器中时,可采用这种方法。位位置是一个07之间的常数。(3)sbit位变量名=字节地址位位置这种方法是以一个常数(字节地址)作为基地址,该常数必须在80HFFH(特殊功能寄存器的字节地址)之间。位位置是一个07之间的常数。,9sbit可寻址位,4.2.2数据类型,-sbit可寻址位,25,23.05.2020,MCS-51单片机中的特殊功能寄存器及其可寻址位,已被预先定义放在文件reg51.h中,在程序的开头只需加上#include或#include即可。另外,bit还可访问MCS-51单片机片内20H2FH范围内的位对象。C51编译器提供了一个bdata存储器类型,允许将具有bdata类型的对象放入MCS-51单片机片内可位寻址区。,4.2.2数据类型,-reg51.h,26,23.05.2020,sbit和bit的区别:sbit定义特殊功能寄存器中的可寻址位;而bit则定义了一个普通的位变量,一个函数中可包含bit类型的参数,函数返回值也可为bit类型。,4.2.2数据类型,-sbit和bit,27,23.05.2020,4.2.3运算符和表达式,C51算术运算符有五种:+加法运算符或正号-减法运算符或负号*乘法运算符/除法运算符%模(求余)运算符优先级:先乘除,后加减,先括号内,再括号外。结合性:自左至右方向。模运算即求余数,如,7%3,结果是7除以3所得余数1,1C51的算术运算符,-算术运算符,28,23.05.2020,C51关系运算符有六种:大于=大于等于=相等!=不相等优先级:前四个高,后两个“=”和“!=”级别低。结合性:自左至右方向。关系表达式的结果是逻辑值“真”或“假”,C51中以“1”代表真,“0”代表假。,2C51关系运算符,4.2.3运算符和表达式,-关系运算符,29,23.05.2020,C51逻辑运算符有三种:/*在MCS-51片内直接寻址RAM中定义了3个变量,默认为自动变量*/chari,j,k;/*未指明存储类型,由#pragmasmall决定,与前一句完全等价*/intxdatam,n;/*在MCS-51片外RAM中定义了两个自动变量*/staticcharm,n;/*在MCS-51片内直接寻址RAM中定义了两个静态变量*/,-存储模式举例,45,23.05.2020,unsignedcharxdataram10;/*在MCS-51片外RAM中定义了大小为10B的数组变量*/intfunc1(inti,intj)large/*指定函数中变量是LARGE模式*/return(i+j);intfunc2(inti,intj)/*未指明存储模式,按默认的SMALL模式*/return(i-j);,4.3.2存储模式,-存储模式举例,46,23.05.2020,4.3.3特殊功能寄存器的访问,MCS-51系列单片机片内有21个特殊功能寄存器(SFR),分散在片内RAM区的0 x800 xFF地址范围内。对SFR的操作只能用直接寻址方式。为了能直接访问这些特殊功能寄存器,C51提供了定义SFR的方法。这与ANSIC不兼容,只适用于MCS-51系列单片机。,-定义SFR的方法,47,23.05.2020,-sfr数据类型,用sfr定义特殊功能寄存器名的语法如下:Sfr特殊功能寄存器名=整型常量;例如:sfrPSW=0 xD0;/*定义程序状态字PSW,因MCS-51单片机的PSW地址为D0H*/sfrTMOD=0 x89;/*定义定时/计数器方式控制寄存器TMOD,因MCS-51单片机的TMOD地址为89H*/sfrP1=0 x90;/*定义P1口,因MCS-51单片机的P1口地址为90H*/sfrSCON=0 x98;/*定义串口控制寄存器SCON,因MCS-51单片机的SCON地址为8H*/,4.3.3特殊功能寄存器的访问,1用sfr数据类型访问特殊功能寄存器,48,23.05.2020,2用sbit数据类型访问可位寻址的特殊功能寄存器中的位,MCS-51系列单片机片内21个特殊功能寄存器(SFR)中有11个特殊功能寄存器是可位寻址的。访问这些可位寻址的特殊功能寄存器中的位的方法可由关键字sbit定义特殊功能寄存器位寻址数据类型来实现。定义特殊功能寄存器位名的语法有下列三种:,4.3.3特殊功能寄存器的访问,-sbit数据类型,49,23.05.2020,sbit特殊功能寄存器位名=特殊功能寄存器名整型常量其中,特殊功能寄存器名是已由sfr定义了的特殊功能寄存器名,整型常量是位可寻址特殊功能寄存器中的位(是一个07之间的常数)。sbit特殊功能寄存器位名=整型常量1整型常量2其中,整型常量1是指可位寻址特殊功能寄存器的字节地址(在80HFFH之间),整型常量2是指该寄存器中的位(是一个07之间的常数)。sbit特殊功能寄存器位名=整型常量其中,整型常量是可位寻址特殊功能寄存器的绝对位地址(位于80HFFH之间)。,4.3.3特殊功能寄存器的访问,-定义方法,50,23.05.2020,4.3.3特殊功能寄存器的访问,sfrPSW=0 xD0;/*首先定义程序状态字PSW,因MCS-51单片机的PSW地址为D0H*/sbitOV=PSW2;/*在前面定义了PSW后,OV位于PSW的第2位*/sbitAC=0 xD06;/*D0H是程序状态字PSW的字节地址,辅助进位标志位AC位于PSW的第6位*/sbitRS0=0 xD03;/*工作寄存器组控制位RS0位于PSW的第3位*/sbitCY=0 xD7;/*进位标志位Cy的绝对位地址为D7H*/标准SFR在reg51.h、reg52.h等头文件中已经被定义,只要用文件包含做出申明即可使用。,-实例,51,23.05.2020,例4-2特殊功能寄存器的访问。#include”reg51.h”sbitP10=P10;/*定义P10为P1口第0位,即P1.0口*/sbitP12=P12;/*定义P12为P1口第2位,即P1.2口*/voidmain()P10=1;/*置位P1.0口*/P12=0;/*复位P1.2口*/PSW=0 x08;/*程序状态字置0 x08*/,4.3.3特殊功能寄存器的访问,-应用实例,52,23.05.2020,4.3.4存储器和并行口的访问,MCS-51单片机片内有128个字节的RAM区(00H7FH),可扩展片外64KB的ROM和RAM,有P0、P1、P2、P3四个8位双向并行I/O口,每个端口可以按字节输入或输出,也可以按位进行输入或输出,四个口共32根口线。使用C51编程时,片内/外存储器、片内I/O口与片外扩展I/O口可以统一在头文件中定义,也可以在程序中进行定义(一般在程序开始的位置)。C51定义存储器、并行口方法如下。,-在头文件中定义,53,23.05.2020,1对存储器使用绝对地址访问,C51编译器提供了一组宏定义用来对MCS-51系列单片机的CODE、DATA、PDATA和XDATA空间进行绝对地址访问。函数原型如下:#defineCBYTE(unsignedcharvolatile*)0 x50000L)#defineDBYTE(unsignedcharvolatile*)0 x40000L)#definePBYTE(unsignedcharvolatile*)0 x30000L)#defineXBYTE(unsignedcharvolatile*)0 x20000L)#defineCWORD(unsignedintvolatile*)0 x50000L)#defineDWORD(unsignedintvolatile*)0 x40000L)#definePWORD(unsignedintvolatile*)0 x30000L)#defineXWORD(unsignedintvolatile*)0 x20000L)这些函数原型放在absacc.h文件中,4.3.4存储器和并行口的访问,-绝对地址访问,54,23.05.2020,CBYTE以字节形式对CODE区寻址,DBYTE以字节形式对DATA区寻址,PBYTE以字节形式对PDATA区寻址,XBYTE以字节形式对XDATA区寻址,CWORD以字形式对CODE区寻址,DWORD以字形式对DATA区寻址,PWORD以字形式对PDATA区寻址,XWORD以字形式对XDATA区寻址。,4.3.4存储器和并行口的访问,-绝对地址访问,55,23.05.2020,例4-3使用绝对地址访问存储器,#include#include#defineuintunsignedint#defineucharunsignedcharvoidmain(void)uintui_var1;ucharuc_var1;ui_var1=XWORD0 x0000;/*访问外部RAM的0000H0001H地址的内容*/uc_var1=XBYTE0 x0002;/*访问外部RAM的0002H地址的内容*/XWORD0 x0000=0 xAABB;/*将0 xAABB送入外部RAM的0000H0001H地址中*/XBYTE0 x0002=0 xAA;/*将0 xAA送入外部RAM的0002H地址中*/for(;);,4.3.4存储器和并行口的访问,-绝对地址访问,56,23.05.2020,2对存储器使用指针访问,采用指针的方法,可实现在C51程序中对任意指定的存储器地址进行操作。例4-4使用指针访问存储器。#defineucharunsignedchar#defineuintunsignedintvoidtest_memory(void)ucharidataivar1;/*定义一个指向idata存储空间的变量*/ucharxdata*xdp;/*定义一个指向XDATA存储器空间的指针*/chardata*dp;/*定义一个指向DATA存储器空间的指针*/,4.3.4存储器和并行口的访问,-指针访问,57,23.05.2020,ucharidata*idp;/*定义一个指向IDATA存储器空间的指针*/xdp=0 x1000;/*XDATA指针赋值,指向XDATA存储器地址1000H处*/*xdp=0 x5A;/*将数据5AH送到XDATA区的1000H单元*/dp=0 x61;/*DATA指针赋值,指向DATA存储器地址61H处*/*dp=0 x23;/*将数据23H送到DATA区的61H单元*/idp=/*数据16H送到IDATA区的变量ivar1所在的地址单元中,等价于ivar1=0 x16*/,4.3.4存储器和并行口的访问,-指针访问,58,23.05.2020,3C51定义片内I/O口,单片机内部并行口可用关键字sfr定义,I/O口定义格式举例:sfrP0=0 x80;/*定义P0口,地址80H*/sfrP1=0 x90;/*定义P1口,地址90H*/,4.3.4存储器和并行口的访问,-sfr定义片内I/O,59,23.05.2020,操作片内I/O口,例4-5操作片内I/O口sfrP1=0 x90;/*定义P1口,地址90H*/sfrP3=0 xB0;/*定义P3口,地址B0H*/sbitDIPswitch=P14;/*P1口第4位(P1.4口)为DIP开关的输入*/sbitLEDgreen=P35;/*P3口第5位(P3.5口)为LED的输出*/voidmain()unsignedcharinval=0;for(;)if(DIPswitch=1)/*检查P1.4口输入是否为高*/inval=P1/*P1口03位输出与P3口的03位相或输出*/,4.3.4存储器和并行口的访问,60,23.05.2020,4C51定义外部并行口,对片外扩展的I/O口,则根据其硬件译码地址,将其看作片外数据存储器的一个单元,使用#define语句进行定义。用指针定义,指针的定义在absacc.h头文件中。,4.3.4存储器和并行口的访问,-#define语句定义片外I/O,61,23.05.2020,操作片外I/O口,例4-6操作片外I/O口#include“absacc.h”#definePAXBYTE0 xffec/*将PA定义为外部I/O口,地址为0 xffec*/voidmain()PA=0 x5A;/*将数据5AH写入地址为0 xffec的存储单元或I/O端口*/在头文件或程序中对片内/外I/O口进行定义以后,在程序中就可以使用这些口了。定义口地址的目的是为了便于C51编译器按MCS-51单片机系统的实际硬件结构建立I/O口变量名与其实际地址的联系,以便程序员能用软件模拟MCS-51单片机系统的硬件操作。,4.3.4存储器和并行口的访问,62,23.05.2020,4.3.5位地址访问,C51编译器支持bit数据类型,在C51程序中可以使用bit数据类型对位地址进行操作。C51对位变量的定义有3种方法:1用bit关键字定义C51位变量2通过指定函数中参数为bit类变量3定义位寻址存储区的位变量,-位变量定义,63,23.05.2020,4.3.5位地址访问,1用bit关键字定义C51位变量例如:bitlock;/*将lock定义为位变量*/bitdirention;/*将direction定义为位变量*/bitdisplay;/*将display定义为位变量*/注意:不能定义位变量指针;也不能定义位变量数组。,-用bit定义位变量,64,23.05.2020,例如:bitfun(bita1,bita2)return(a1);,4.3.5位地址访问,2通过指定函数中参数为bit类变量,-函数参数为位变量,65,23.05.2020,-位寻址存储区的位变量定义,3定义位寻址存储区的位变量C51编译器允许数据类型为bdata的变量放入片内RAM可位寻址区中。例如:先定义变量的数据类型和存储类型,然后使用sbit定义位变量。bdataintibdata;/*ibdata定义为bdata整型变量*/bdatacharcarry5;/*carry定义为bdata字符数组*/sbitmybit0=ibdata0;/*mybit0定义为ibdata的第0位*/sbitmybit15=ibdata15;/*mybit15定义为ibdata的第15位*/,4.3.5位地址访问,66,23.05.2020,-位寻址存储区的位变量定义,sbitarrybit07=carry07;/*arrybit07定义为carry0的第7位*/sbitarrybit37=carry37;/*arrybit37定义为carry3的第7位*/arrybit37=0;/*carry3的第7位赋值为0(位寻址)*/carry0=A;/*carry0赋值为A(字节寻址)*/位置(操作符)后的最大值取决于指定的基本数据类型。对于char而言是07;对于int而言是015;对于long而言是031。,4.3.5位地址访问,67,23.05.2020,4.3.6中断函数,中断服务程序在C51程序中是以中断函数的形式出现的,中断函数的格式为:void函数名()interruptnusingm函数体语句interrupt是中断函数的关键字,n是中断号,MCS-51的中断号与中断源的对应关系如表5-5所示。using是指定中断函数中选用工作寄存器组的关键字,m是03范围的常数,若不用该选项,编译器会自动选择默认工作寄存器组(0组寄存器)。,-中断函数的格式,68,23.05.2020,表4-6MCS-51中断源和中断的关系,void函数名()interruptnusingm,4.3.6中断函数,-中断函数的中断号,69,23.05.2020,例:voidT0_srv(void)interrupt1using1/*定时/计数器0中断函数*/*定时/计数器0中断服务程序*/,4.3.6中断函数,-中断函数举例,70,23.05.2020,编写中断函数要点:1)中断函数不能进行参数传递。2)中断函数没有返回值,应定义为void型。3)禁止对中断函数的直接调用。4)如果中断函数调用了其他函数,被调函数与中断函数使用相同的寄存器组。5)中断函数最好写在程序尾部。,void函数名()interruptnusingm,4.3.6中断函数,-编写中断函数要点,71,23.05.2020,4.4C51结构化程序设计,C51程序是一种结构化程序,由若干模块组成,每个模块中包含若干个基本结构,而每个基本结构中可以有若干条语句。基本结构有三种:顺序结构选择结构循环结构,-三种结构程序,72,23.05.2020,顺序结构是一种最基本、最简单的程序结构。在这种结构中,语句被依次逐条地顺序执行。例4-7一乘法程序,乘积放在外部RAM的0000H单元。voidmain()unsignedlongxdata*p;/*设定p是指向外部RAM区的unsignedlong指针*/unsignedlongx=12345,y=67890,mum;mum=x*y;p=0;/*p指向外部RAM区0000H单元*/*p=mum;/*乘积存入外部RAM区0000H单元*/,4.4.1顺序结构程序,-顺序结构,73,23.05.2020,4.4.2选择结构程序,用if语句可以构成选择结构。它根据给定的条件进行判断,以决定执行某个分支程序段。语言的if语句有三种基本形式。1单分支语句if(条件表达式)语句组;,其语义是:如果条件表达式的值为真,则执行其后的语句组,否则不执行其后的语句组。单分支语句执行过程可表示为图4-1所示。,-单分支结构,74,23.05.2020,-单分支结构举例,例4-8寻找两个数中的大数输出voidmain()unsignedxdata*p;unsigneda=35,b=78,max;max=a;if(maxb)max=a;elsemax=b;p=0;/*p指向外部RAM区0000H单元*/*p=max;/*最大值存入外部RAM区0000H单元*/,4.4.2选择结构程序,-双分支结构举例,77,23.05.2020,3多分支语句当有多个分支选择时,可采用if-else-if语句结构,其一般形式为:if(条件表达式1)语句组1;elseif(条件表达式2)语句组2;elseif(条件表达式3)语句组3;elseif(条件表达式n)语句组n;else语句m;,4.4.2选择结构程序,-多分支结构,其语义是:依次判断条件表达式的值,当出现某个条件表达式的值为真(非0)时,则执行其对应的语句组。然后跳到整个if语句之外继续执行程序。如果所有的表达式的值均为假(0),则执行语句组m。然后继续执行后续程序。,78,23.05.2020,例4-10如图4-3所示,单片机P1口的P1.0和P1.1各接一个开关K1、K2,P1.4、P1.5、P1.6和P1.7各接一只发光二极管。由K1和K2的不同状态来确定哪个发光二极管被点亮。程序如下:,4.4.2选择结构程序,-多分支结构举例,79,23.05.2020,#include“reg51.h”voidmain()chara;a=P1;a=a,4.4.2选择结构程序,-多分支结构举例,80,23.05.2020,4开关选择switch语句,switch语句结构的一般形式为:switch(表达式)case常量表达式1:语句组1;case常量表达式2:语句组2;case常量表达式n:语句组n;default:语句组n+1;,4.4.2选择结构程序,-多分支结构,其语义是:计算表达式的值,并逐个与其后的常量表达式值相比较,当表达式的值与某个常量表达式的值相等时,即执行其后的语句组,然后继续执行后面所有的case语句,但不再进行判断;如表达式的值与所有case后的常量表达式的值均不相等时,则执行default后的语句。,81,23.05.2020,例4-11用switch语句完成例4-10任务。程序如下:#includevoidmain()chara;a=P1;a=a,4.4.2选择结构程序,-多分支结构举例,82,23.05.2020,在使用switch语句时还应注意以下几点:(1)在case后的各常量表达式的值不能相同,否则会出现错误。(2)在case后,允许有多条语句,可以不用括起来。(3)各case和default子句的先后顺序可以变动,而不会影响程序执行结果。(4)default子句可以省略不用。(5)在每一case语句之后增加break语句,使每一次执行之后均可跳出switch语句,这样才能实现多分支结构。,4.4.2选择结构程序,-使用switch语句,83,23.05.2020,4.4.3循环结构程序,循环结构程序的其特点是,在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。语言提供了多种循环语句,可以组成各种不同形式的循环结构。语言提供的循环语句有:1)用while语句;2)用do-while语句;3)用for语句。,-语言的循环语句,84,23.05.2020,1while循环语句,while循环语句的一般形式为:while(表达式)语句组其中表达式是循环条件,语句组为循环体。,while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句组。,4.4.3循环结构程序,-while循环语句,85,23.05.2020,例4-12前面的例4-11程序只能执行一遍,用while语句使其无穷循环执行。程序如下:#includevoidmain()chara;while(1)/*循环条件表达式的值始终为1,无穷循环*/a=P1;a=a,4.4.3循环结构程序,-while循环语句,86,23.05.2020,2do-while循环语句do-while循环语句的一般形式为:do语句组while(表达式);,4.4.3循环结构程序,-do-while循环语句,这个循环与while循环的不同在于:先执行循环体中的语句组,然后再判断表达式的值是否为真,如果为真(非0)则继续循环;如果为假(0),则终止循环。因此,do-while循环至少要执行一次循环体内的语句组。do-while循环语句流程图如图4-5所示。,87,23.05.2020,例4-13用do-while语句实现例4-12。程序如下:#includevoidmain()chara;doa=P1;a=a/*循环条件表达式的值始终为1,无穷循环*/,4.4.3循环结构程序,-do-while循环语句,88,23.05.2020,-for循环语句,3for循环语句for语句使用最为灵活,它完全可以取代while语句。for循环语句的一般形式为:for(表达式1;表达式2;表达式3)语句组for循环语句的执行过程如下:(1)先求解表达式1。(2)求解表达式2,若其值为真(非0),则执行for语句中指定的语句组,然后执行下面第3步;若其值为假(0),则转到第5步,结束循环。(3)求解表达式3。(4)转回上面第2步继续执行。(5)循环结束,执行for语句的下一个语句。,4.4.3循环结构程序,89,23.05.2020,-for循环语句,关于for循环语句的说明:for(表达式1;表达式2;表达式3)语句组(1)for循环中的“表达式1(循环变量初值)”,“表达式2(循环条件)”和“表达式3(循环变量增量)”都是选择项(可缺省),但“;”不能缺省(2)省略了“表达式1(循环变量初值)”,则不对循环控制变量赋初值(3)省略了“表达式2(循环条件)”,则不作其他处理时便成为死循环(4)省略了“表达式3(循环变量增量)”,则不对循环控制变量进行操作,这时可在语句组中加入修改循环控制变量的语句(5)“表达式1(循环变量初值)”和“表达式3(循环变量增量)”可同时省略,结果如同前面第2,4两种情况(6)3个表达式可同时省略,结果如前面第2,3,4三种情况的综合效果(7)表达式2一般是关系表达式或逻辑表达式,但也可是数值表达式或字符表达式,只要其值非零,就执行循环体语句组,4.4.3循环结构程序,90,23.05.2020,例4-14用for语句实现例4-12。,#include“reg51.h”voidmain()chara;for(;)/*无循环条件,无穷循环*/a=P1;/*读P1口的值*/a=a,4.4.3循环结构程序,-for循环语句举例,91,23.05.2020,4break语句,break语句通常用在循环语句和开关语句中。当break用于开关语句switch中时,可使程序跳出switch而执行switch以后的语句。当break语句用于do-while、for、while循环语句中时,可使程序终止循环而执行循环结构后面的语句。通常break语句总是与if语句联在一起,即满足条件时便跳出循环。,4.4.3循环结构程序,-break语句,92,23.05.2020,-continue语句,continue语句的作用是跳过循环体中剩余的语句而强行开始执行下一次循环。continue语句只用在for、while、do-while等循环体中。continue语句常与if条件语句一起使用,用来加速循环。,4.4.3循环结构程序,5continue语句,93,23.05.2020,4.5C51程序设计实例,在许多单片机嵌入式应用系统中,经常采用查表法代替数学公式的计算。特别是对传感器的非线性补偿的场合,使用查表法比采用复杂的曲线拟合效果更好。可以将预先计算好的数据随程序装入到EPROM的一块指定区间,形成数据表。查表程序可以用数组实现。,4.5.1查表程序,94,23.05.2020,例4-15编写一个将摄氏温度转换为华氏温度的查表程序,已知摄氏温度0,1,2,3,4,5对应的华氏温度为32,34,36,37,39,41。,4.5.1查表程序,-查表程序举例,程序如下:#defineUCHunsigenedcharUCHcodetem=32,34,36,37,39,41;UCHf_to_c(UCHdeg)returntemdeg;voidmain()UCHx;x=f_to_c(3);,95,23.05.2020,例4-16片内RAM的20H单元存放着一个005H的数,用查表法求出该数的平方值放入内部RAM的21H单元中。,4.5.1查表程序,-查表程序举例,main()charx,*p;charcodetab6=0,1,4,9,16,25;p=0 x20;x=tab*p;p+;*p=x;,96,23.05.2020,4.5.2单片机内/外部资源应用程序设计,本节介绍一些使用MCS-51单片机内部资源(中断、定时/计数器、I/O)和扩展资源(并口、A/D、D/A、键盘、显示器)的C51实用程序。在程序中用到了一些后续章节的内容(如中断、定时/计数器等)。,97,23.05.2020,4.5.2单片机内/外部资源应用程序设计,例4-17外部中断0引脚(P3.2口)接一个开关,P1.0口接一只发光二极管。开关闭合一次,发光二极管改变一次状态。,程序如下:#include#includesbitP1_0=P10;voiddelay(void)/*延时函数*/inta=5000;while(a-)_nop_();voidint_srv(void)interrupt0using1/*外中断函数*/delay();,if(INT0=0)/*测试INT0=0后P1.0取反*/P1_0=!P1_0;while(INT0=0);voidmain()P1_0=0;EA=1;/*开中断*/EX0=1;while(1);,-例4-17,98,23.05.2020,4.5.2单片机内/外部资源应用程序设计,例4-18用定时器0实现从P1.0口输出方波信号,周期为50ms。设单片机的fOCS=6MHz。,程序如下:#includesbitP1_0=P10;voidmain()/*主函数*/TMOD=0 x01;/*设置T0工作于定时方式1*/TH0=-12500/256;/*写定时器中加1计数器的计数初值*/TL0=-12500256;ET0=1;/*允许定时器0中断*/EA=1;/*全部中断允许*/,TR0=1;/*启动定时器0工作*/while(1);/*等待中断*/voidT0_srv(void)interrupt1using1/*中断函数*/TH0=-12500/256;/*重写计数初值*/TL0=-12500256;P1_0=!P1_0;/*P1.0取反*/,-例4-18,99,23.05.2020,4.5.2单片机内/外部资源应用程序设计,例4-19如图4-7所示,单片机扩展可编程接口芯片8155,8155的PA口控制8只发光二极管,形成走马灯,每位点亮的时间为0.1秒。,8155的端口地址如下:命令口地址(COM8155):FEF8HPA口地址(PA8155):FEF9HPB口地址(PB8155):FEFAHPC口地址(PC8155):FEFBH,-例4-19,100,23.05.2020,#include“reg51.h”#include“absacc.h”#defineCOM8155XBYTE0 xfef8#definePA8155XBYTE0 xfef9voiddelay(void)/*延时1ms函数*/TH0=-500/256;TL0=-500%256;TR0=1;While(!TF0);/*循环等待定时器0定时时间到*/TF0=0;TR0=0;,4.5.2单片机内/外部资源应用程序设计,-例4-19,101,23.05.2020,voidmain()chari;chardisp_word=0 x01;/*从第1位开始点亮*/COM8155=0 x01;/*初始化8155*/doPA8155=disp_word;/*输出点亮一位*/for(i=0;i100;i+)delay();/*点亮0.1秒*/disp_word=disp_word1;/*左移控制字,准备点亮下一位*/if(disp_word=0)disp_word=0 x01;while(1);,4.5.2单片机内/外部资源应用程序设计,-例4-19,102,23.05.2020,例4-20如图4-8所示为扩展独立键盘电路。编写程序实现键盘管理。,4.5.2单片机内/外部资源应用程序设计,-例4-20,103,23.05.2020,程序如下:#include“reg51.h”#include“absacc.h”voiddelay(void)/*延时1ms*/TH0=-500/256;TL0=-500%256;TR0=1;while(!TF0);/*循环等待定时器0定时时间到*/TF0=0;TR0=0;,4.5.2单片机内/外部资源应用程序设计,-例4-20,104,23.05.2020,voidmain()charx,i;for(;)x=P1;x=x,4.5.2单片机内/外部资源应用程序设计,-例4-20,105,23.05.2020,switch(x)case0 x01:PBYTE0 x20=PBYTE0 x20+1;break;/*20单元加1*/case0 x02:PBYTE0 x20=PBYTE0 x20-1;break;/*20单元减1*/case0 x04:PBYTE0 x20=0 x00;break;/*20单元清零*/case0 x08:PBYTE0 x20=0 xff;/*20单元置全1*/,4.5.2单片机内/外部资源应用程序设计,-例4-20,106,23.05.2020,例4-21如图4-9所示为扩展4位动态显示电路。编写控制4位显示器动态显示的程序。,位选码输出,段选码输出,4.5.2单片机内/外部资源应用程序设计,-例4-21,107,23.05.2020,#include“reg51.h”#include“intrins.h”charcodedispdata=0 x3F,0 x06,0 x5B,0 x4F,0 x66,0 x6D,0 x7D,0 x07,0 x7F,0 x6F;/*数字0-9对应的段选码*/chardis_data4;voiddelay(void)/*延时1ms*/TH0=-500/256;TL0=-500%256;TR0=1;while(!TF0);TF0=0;TR0=0;,4.5.2单片机内/外部资源应用程序设计,-例4-21,108,23.05.2020,voiddisp(charch1)/*显示函数*/staticcharch=0 x01;P2=ch;P1=dis_datach1;ch=ch1;if(ch=0 x10)ch=0 x01;main()charch1;TMOD=0 x01;/*T0为16位定时工作方式*/while(1)for(ch1=0;ch14;ch1+)/*对4位LED扫描一遍*/disp(ch1);delay();delay();delay();,4.5.2单片机内/外部资源应用程序设计,-例4-21,109,23.05.2020,例4-22

温馨提示

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

评论

0/150

提交评论