任务二单片机控制流水灯.ppt

上传人:牧羊曲112 文档编号:6547715 上传时间:2023-11-11 格式:PPT 页数:146 大小:1.46MB
返回 下载 相关 举报
任务二单片机控制流水灯.ppt_第1页
第1页 / 共146页
任务二单片机控制流水灯.ppt_第2页
第2页 / 共146页
任务二单片机控制流水灯.ppt_第3页
第3页 / 共146页
任务二单片机控制流水灯.ppt_第4页
第4页 / 共146页
任务二单片机控制流水灯.ppt_第5页
第5页 / 共146页
点击查看更多>>
资源描述

《任务二单片机控制流水灯.ppt》由会员分享,可在线阅读,更多相关《任务二单片机控制流水灯.ppt(146页珍藏版)》请在三一办公上搜索。

1、任务二 单片机控制流水灯,教学导航任务单任务准备案例示范知识梳理与总结任务作业,教学导航,任务单,任务二电路图,任务二 单片机控制流水灯,2.1 C51基础2.2 C51语句2.3 C51函数与预处理2.4 单片机时钟电路及时钟周期案例3 单片机控制模拟广告流水灯,2.1 C51基础,C51语言是针对8051系列及其扩展系列单片机的语言,支持符合ANSI标准的c语言程序设计,同时针对8051系列单片机的一些特点进行了扩展。,2.1.1 C51的标识符和关键字,1、标识符 程序设计者为自定义的变量、函数、类型所起的名字只能由字母、数字、下划线组成,且第一个字母必须是字母或下划线不能与关键字同名,

2、尽量“见名知义”,2.1.1 C51的标识符和关键字,【例2.1】指出下面哪些是非法的标识符?a f-2 f6 m+n x4b 4af as_d a.ss total main month int 关键字:mainint 非法字符:f-2m+n a.ss 开头非法:4af,2.1.1 C51的标识符和关键字,2、关键字 又称保留字,是程序设计语言中规定的、有固定含义的单词符号。(32个),C51扩展的关键字,数据类型,C数据类型,基本类型,构造类型,指针类型,空类型void,定义类型typedef,字符类型 char,枚举类型 enum,整 型,实 型,单精度型 float,双精度型 doub

3、le,数组,结构体 struct,共用体 union,长整型 long,整型 int,数据类型决定:1.数据占内存字节数2.数据取值范围3.其上可进行的操作,2.1.2 C51的数据类型,位 型 bit,短整型 short,2.1.3 C51的数据类型,1.字符型(char),(1)字符型常量字符常量是用单引号括起来的一个字符,如a,1,A等都是字符常量。注意,字符型常量区分大小写,因此a和A是不同的字符常量。不可以显示的控制字符,可以在该字符前面加一个“”组成转义字符,也就是把“”后面的字符转变成另外的意义。,转义字符,(2)字符型变量,字符型变量的长度为一个字节(即8位),而8051单片机

4、每次可以处理8位数据,因此字符型变量非常适合于8051单片机。字符型变量分为无符号和有符号两种。如果没有显式地指明是无符号还是有符号,则默认为有符号字符型变量。,(2)字符型变量,对字符型变量赋值有两种方法:既可以将用单引号括起来的一个字符赋给字符型变量,也可以将一个在其取值范围内的正整数赋给字符型变量。对于有符号的变量,最具有重要意义的是其最高位((8位中最左一位)。在此位上,1代表“负”,0代表“正”,剩余的低7位代表变量的绝对值,因此有符号字符型变量所能表示的数值范围是从-128十127。而无符号的变量的最高位不作为符号位,这与人们的习惯比较一致,不易出错。,(3)字符串常量,字符串常量

5、是用一对双引号括起来的字符序列不要把字符常量与字符串常量混淆。这是因为在C51中,系统在每一个字符串的结尾加一个被称为“字符串结束标志”字符0以判断字符串是否结束。因此“A”表示一个字符串,它包含了A和0两个字节,因此,无法存储到只有一个字节的存储空间的字符型变量中。同样地,China占用了6个字节而不是5个字节。注意:0是系统自动加上的,在写字符串时不必加0。,2.整型(int),(1)整型常量整型常量按进制有以下3种表示形式:1)十进制整数:如134、5、-5、0等。2)八进制整数:以0开头的数,例如034表示八进制数(34)8,等于十进数28。3)十六进制数:以0 x或0X开头的数是十六

6、进制数,例如0 x3a代表十六进制数(3a)16,等于十进制数58;-0 x56代表十六进制数(56)16,等于十进制-88。,(2)整型变量,1)基本型:以int表示,长度为两个字节。2)短整型:以short int表示,长度为两个字节。3)长整型:以long int表示,长度为四个字节。以unsigned表示,这种类型与前3种类型匹配而构成无符号整型、无符号短整型和无符号长整型。注意:int,short int,long int的缺省类型为有符号型。,(2)整型变量,说明整型变量的一般形式为:类型说明符 变量名,变量名,;同类型的整型变量之间和不同类型的整型变量之间都可以进行算术运算。整型

7、变量和字符型变量之间也可以进行算术运算。,3.浮点型(float),(1)浮点型常量浮点常量只有十进制这一种进制,并且都被默认为double型。对于绝对值小于1的浮点数可省略小数点前面的零,如.654就是0.654的缩略形式。科学计数法:-3.3E9由尾数和阶两部分构成的,-3.3E9表示:-3.3109。,3.浮点型(float),(2)浮点型变量浮点型变量分为单精度型(float)和双精度型(double),长度都是4个字节浮点型变量定义方法:float a;double b;,4.指针型,指针型是一种特殊的数据类型,其本身就是一个变量,但在其中存放的是另一个数据的地址。在C51中,指针的

8、长度一般是3个字节。根据所指向的变量类型的不同指针变量也有不同的类型,指针变量的类型也就表示了该指针指向的地址中的数据的类型。,4.指针型,指针类型的表示方法是在指针符号“*”前面冠以数据类型符号例如:char*pa;/定义pa为字符型指针unsigned int*pb;/定义pb为无符号整形指针float*pf;/定义pf为浮点型指针,5.位变量(bit),位变量的长度是1位(bit),位变量和前面介绍的字符型变量是可以直接被8051单片机处理的。位变量的值可以取0(false)或1(true)。对位变量进行定义的语法如下:bit flag1;bit send_en=1;注意:不能定义一个位

9、变量指针,如不能定义bit*flagl;也不能定义一个位变量数组,如不能定义bit flags3。,5.位变量(bit),与8051单片机硬件特性操作有关的位变量必须定位在8051单片机片内RAM的可位寻址空间中,也就是字节地址为20H-2FH的16个节单元。,6.特殊功能寄存器(sfr),定义:单片机内的各种控制寄存器、状态寄存器以及I/O端口锁存器、定时器、串行端口数据缓冲器是内部数据存储器的一部分,离散地分布在80HFFH的地址空间范围内,这些寄存器统称特殊功能寄存器(SFR,Special Function Registers)。,数据存储器,内部RAM,特殊功能寄存器,(2)说明:5

10、1子系列离散分布有21个特殊功能寄存器SFR、52子系列为26个。凡地址能被8整除的寄存器(共11个)都是可位寻址的寄存器。,特殊功能寄存器变量定义方法,sfr类型的长度为一个字节,其定义方式如下:sfr 特殊功能寄存器名=地址常量;说明“地址常量”就是所定义的特殊功能寄存器的地址,例如:sfr P1=0 x90;sfr SCON=0 x98;注意:在关键字sfr后面必须是一个名字,名字可以任意选取,但应符合一般的习惯。等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H0FFH)在头文件reg51.h中对所有的特殊功能寄存器都进行了定义。,7.1

11、6位特殊功能寄存器(sfr16),在新一代的8051单片机中,特殊功能寄存器在功能上经常组合成16位来使用。为了有效地访问这种16位的特殊功能寄存器,可采用关键字sfrl6。sfrl6类型的长度为两个字节,其定义语法与8位SFR相同,但16位SFR的低端地址必须作为sfr16的定义地址。例如sfr16 T2=0CCH;/定义TIMER2,其地址为T2L=0CCH、T2H=0CDH注意:这种定义方法适用于所有新一代的8051单片机中新增加的特殊功能寄存器,但不能用于定时器/计数器TIMER0和TIMER1的定义。,8.可寻址位(sbit),(1)sbit 位变量名=位地址这种方法将位的绝对地址赋

12、给位变量,位地址必须位于80H0FFH之间。(2)sbit 位变量名=特殊功能寄存器名位位置当可寻址位位于特殊功能寄存器种时可采用这种方法,“位位置”是一个07之间的常数。(3)sbit 位变量名=字节地址位位置这种方法以一个常数(字节地址)作为基础,该常数必须在80H0FH之间。“位位置”是一个0-7之间的常数。,sbit是一个独立的关键字,不要与关键字bit相混淆。,2.1.3 C51的运算量,1、常量程序运行期间其值不能被改变的量,即常数。数值型常量:3、3.5、-9字符常量:a、n字符串常量:”Input Information-1”,2.1.3 C51的运算量,2、变量程序运行过程中

13、其值可以改变的量。变量名:标识符 x变量值:变量存储单元中的数据 8变量类型:值的大小由其类型来决定变量要“先定义、后使用”,2.1.3 C51的运算量,变量的定义变量的名字变量的数据类型系统根据数据类型为变量分配内存空间变量的取值范围变量可以进行的操作,存储种类 数据类型 存储器类型 变量名表;,完整的变量定义格式:,(1)存储种类,1)自动变量函数体内部或者复合语句中定义的变量,如果省略存储种类说明或者在变量名前面加上存储种类说明符“auto”,即可将该变量定义为自动变量。通常采用缺省形式,即省略存储种类说明。自动变量的作用域在定义其的函数体或复合语句内部。自动变量始终是相对于函数或复合语

14、句的局部变量。,(1)存储种类,2)外部变量在所有函数外部定义的变量或者使用存储种类说明符“extern”定义的变量称为外部变量,一个外部变量被定义后,就被分配了固定的内存空间,并且可以被一个程序中的所有函数使用外部变量属于全局变量,其作用域是整个程序,在程序的任何地方均可以对这种变量进行访问如果外部变量与自动变量有同名变量,则只有自动变量起作用。,(1)存储种类,3)静态变量静态变量的定义方法是在类型定义语句之前加关键字static。内部静态变量是在函数内部定义的,与自动变量相比,其作用域同样限于定义内部静态变量的函数内部,但内部静态变量始终都是存在的,其初值只是在进入时赋值一次,退出函数之

15、后变量的值仍然保存但不能访问。外部静态变量是在函数外部被定义的,与外部变量相比,其作用域同样是从定义点开始,一直到程序结束,但外部静态变量只能在被定义的模块文件中访问,其数据值可以为该文件内所有的函数所共享,退出该文件后,虽然变量的值仍然保存着,但不能被其他模块文件访问。,内部静态变量的用法示例,#include#includevoid main()char i;SCON=0 x52;TMOD=0 x20;TH1=0XE8;TR1=1;,for(i=1;i=3;i+)static int s_int=1;int a_int=1;printf(n);printf(s_int=%d,s_int);

16、printf(s_int=%d,a_int);s_int=s_int+1;a_int=a_int+1;while(1),(1)存储种类,(4)寄存器变量定义一个变量时在变量名前加上存储种类符号“register”即可将该变量定义为寄存器变量,例如:register int i;register unsigned char ch1,ch2;使用寄存器变量的目的在于将一些使用频率最高的变量定义为能够直接使用硬件寄存器。寄存器变量可以认为是自动变量的一种,其作用域与自动变量相同。将变量定义为寄存器变量只是给编译器一个建议,该变量能否真正成为寄存器变量还有由编译器根据实际情况决定;另一方面,编译器可以

17、自行识别使用频率最高的变量,在可能的情况下,即使程序中并未将变量定义为寄存器变量,编译器也会自动将其作为寄存器变量处理。,目前已不推荐寄存器变量这种方式!,(2)存储器类型,1)DATA区,DATA区声明中的存储类型标识符为data,通常指低128字节的内部存储区存储的变量,可直接寻址。DATA区是存放临时性传递变量或使用频率较高的变量的理想场所。声明举例如下:unsigned int data sum;extern char data ch1;,2)BDATA区,BDATA区声明中的存储类型标识符为bdata,指内部可位寻址的16字节存储区。BDATA区其实就是DATA区中的位寻址区,在这个

18、区声明变量就可以进行位寻址。在BDATA区声明和使用位变量举例:unsigned int bdata status;sbit status_1=status1;注意:不允许在BDATA区声明float和double型的变量。,3)IDATA区,8051系列的一些单片机如8052有附加的128字节的内部RAM,位于从80H开始的128字节地址空间中,被称为IDATA。因为IDATA区的地址和SFR的地址重叠,所以通过寻址方式来区分二者,IDATA区只能通过间接寻址来访问。IDATA区也可存放使用比较频繁的变量,使用寄存器作为指针进行寻址。IDATA区声明中的存储类型标识符为idata,声明举例如

19、下:unsigned char idata sum;int idata i;float idata f_value;,4)PDATA区和XDATA区,PDATA区和XDATA区属于片外数据存储空间。外部存储空间是可以读写的存储区,最多可以有64KB。PDATA区和XDATA区声明中的存储类型标识符分别为pdata和xdata,xdata存储类型标识符可以指定片外数据区64KB空间内的任何地址,而pdata存储类型标识符仅能指定256字节的片外数据区。声明举例如下:unsigned char xdata sum;int pdata i;float pdata f-value;,5)CODE区,C

20、ODE区也称代码段,是只读的,用来存放可执行代码,16位寻址空间可达64KB。除了可执行代码,还可在CODE区中存放其他非易失信息,例如查询表。CODE区中对象要在编译的时候进行初始化,否则就会产生错误。CODE区声明中的存储类型标识符分别为code。,(3)存储模式,存储模式决定了默认的存储器类型,此存储器类型将应用于函数参数、局部变量和定义时没有显式地包含存储类型的变量。在命令行中使用SMALL、COMPACT、LARGE控制命令指定存储器类型。定义变量时,使用存储器类型显式定义将屏蔽由存储模式决定的默认存储器类。,1)小(SMALL)模式,在该模式下所有变量都默认位于片内数据存储器和使用

21、data指定存储器类型的作用一样。对变量访问的效率很高,但所有的数据对象和堆栈的总大小不能超过内部RAM的大小。当连接器/定位器将变量都配置在片内数据存储器时,SMALL模式是最佳选择。,2)紧凑(COMPACT)模式,在该模式下所有变量都默认位于片外数据存储器的一页(256字节)内,但堆栈位于片内数据存储区中和使用pdata指定存储器类型的作用一样,该存储模式适用于变量不超过256字节的情况。地址的高字节往往通过端口P2输出,其值必须在启动代码中设置。这种模式不如SMALL模式高效,对变量访问的速度要慢一些。,3)大(LARGE)模式,在该模式下所有变量都默认位于片外数据存储器内和使用xda

22、ta指定存储器类型的作用一样。使用数据指针DPTR进行寻址,通过DPTR访问片外数据存储器的效率较低,特别是当变量为两个字节或更多字节时,该模式的数据访问要比前两种模式产生更多代码。,2.1.5 C51运算符和表达式,1.算术运算符和算术表达式十:加法运算符或取正值运算符。一:减法运算符或取负值运算符。:乘法运算符。/:除法运算符。:模(取余)运算符。,2.赋值运算符和赋值表达式,功能是将数据赋给变量。用赋值运算符将一个变量与一个表达式连接起来的式子为赋值表达式。其一般形式为:变量=表达式如果赋值号两侧的类型不一致,系统会自动将右侧表达式求得的数据按赋值号左边的变量类型进行转换。,3.增量、减

23、量运算,4.关系运算符与关系表达式,关系运算实际上就是“比较运算”,将两个表达式进行比较以判断是否和给定的条件相符。关系运算符包括:“”(小于)、“”(小于等于)、“”(大于)、“”(大于等于)、“(等于)、“!=”(不等于)。关系表达式的结果只有两种:1(true)或0(false)。,5.逻辑运算符与逻辑表达式,逻辑“与”和逻辑“或”的真值表,注 意:,如果使用“”来连接两个表达式,若第一个表达式的值为假,则不再求解第二个表达式,因为使用“”连接的两个表达式都为真时,整个逻辑表达式的值才为真,所以若第一个表达式的值为假就没有必要再求解第二个表达式。同理,如果使用“|”来连接两个表达式,若第

24、一个表达式的值为真,则不再求解第二个表达式,因为使用“|”连接的两个表达式都为假时,整个逻辑表达式的值才为假,所以若第一个表达式的值为真就没有必要再求解第二个表达式。,6.位运算符与位运算表达式,(1)按位与运算符“”,参加运算的两个运算量,如果两个相应的位都是1,则结果值中的该位为1,否则为0。1)清除一个数中的某些特定位。2)取出一个数中的某些特定位。,(2)按位或运算符“|”,参加运算的两个运算量,如果两个相应的位至少有一个是1,则结果值中的该位为1,否则为0。按位或运算常用来对一个数据的某些特定位置1。,(3)按位异或运算符“”,参加运算的两个运算量,如果两个相应的位相同,即均为1或均

25、为0,则结果值中的i位为0,否则为1。按位异或运算常用来对一个数据的某些特定位进行翻转。,(4)按位取反运算符“”,“”是一个单目运算符,用来对一个二进制数按位取反,即将0变1,1变0。,(5)右移运算符“”,右移运算符用来将一个数的各二进制位全部右移若干位,移到右端的低位被舍弃。对无符号数或者有符号数中的正数,左边高位移入0;对有符号数中的负数,左边高端移入1。右移1位相当于除以2,右移n位相当于除以2n,因此a2相当于a/4。,(6)左移运算符“”,右移运算符用来将一个数的各二进制位全部左移若干位,移到左端的高位被舍弃,右边的低位补0。左移1位相当于乘以2,左移n位相当于乘以除以2n。,7

26、.复合赋值运算符,凡是二目运算符都可以和赋值运算符结合组成复合赋值运算符。C语言规定可以使用以下10种复合赋值表达式:+=、-=、*=、/=、%=、=、&=、|=、=复合赋值表达式的一般形式为:变量 复合赋值运算符 表达式,8.逗号运算符与逗号表达式,C51提供了一种特殊运算符逗号运算符,用逗号运算符可以把两个或多个表达式连接起来,形成逗号表达式。逗号表达式的一般形式为:表达式1,表达式式2,、表达式n逗号表达式的求解过程是从左到右依次计算出每个表达式的值,整个逗号表达式的值等于最右边的表达式(表达式n)的值。并非程序中任何地方出现的逗号都是逗号运算符,例如在变量定义或函数参数表中,逗号就不是

27、逗号运算符,而是用作各变量之间的间隔符。,9.条件运算符与条件表达式,条件运算符“?:”是惟一的一个三目运算符,条件表达式的一般形式为:逻辑表达式?表达式1:表达式2条件表达式的求解过程是首先计算逻辑表达式的值,如果为1(true),则整个表达式值为表达式1的值,否则为表达式2的值。,10.指针与地址运算符,C51提供了“”与“”两个单目运算符,前者的作用是返回一个地址内的变量值,取内容;后者的作用是返回操作数的地址,即取地址。这两种运算的一般形式分别为:变量=*指针变量;指针变量=&目标变量;取内容运算是将指针变量所指向的目标变量的值赋给左边的变量;取地址运算是将目标变量的地址赋给左边的变量

28、。,11.C51运算符的优先级,C51语言规定了运算符的优先级。在对有多个运算符参加运算的表达式求值时,按照运算符的优先级别高低次序执行。,11.C51运算符的优先级,课堂作业(分组完成),针对任务一中的电路图,先使D1、D3、D5、D7亮,其他灯灭;再使右4灯维持原状,而左4灯亮;再使D3D6熄,其他灯维持原状;再使右4灯状态变反,其他不变;然后所有灯状态变反;最后使所有灯的状态向左流动一次。,2.2 C51语句,2.2.1 C51语句概述一个完整的C51程序包括数据描述和数据操作。数据描述定义数据结构和数据初值,由数据定义部分来实现;数据操作是对己提供的数据进行加工,这部分的功能就是由语句

29、来实现的。,既包括与底层硬件无关的数据也包括如特殊功能寄存器(SFR)等与底层硬件状态直接相关的数据。,2.2.1 简单语句与复合语句,分号是语句的终结符,一个语句必须在最后出现分号,分号是语句中不可缺少的一部分,在后面介绍空语句时会看到,甚至一个单独的分号也可以构成一个语句。C51的语句按其复杂度可以分为简单语句和复杂语句。可以用花括号“”和“”把一些语句组合在一起,使其在语法上等价于一个简单语句,这样的语句就称之为复合语句。复合语句中最后一个语句中最后的分号不能忽略不写;结束一个复合语句的右花括号之后不能带分号。,2.2.2 分支控制语句,1ifelse语句 if(表达式)分支一else

30、分支二,2.2.2 分支控制语句,2.if语句 if(表达式)语句,既可以是简单语句也可以是复合语句,if(表达式)语句else,P0口接8只发光二极管,P1.0接一个按钮,要求将按钮按下时,左边四个发光二极管亮,当按钮放开时,右边四个发光二极管亮。,实例2-3,实例2-3,#includesbit p10=P10;main()while(1)if(p10=1)P0=0 x0f;else P0=0 xf0;,#include sbit p10=P10;void main()while(1)if(p10=1)P0=0 x0f;if(p10=0)P0=0 xf0;,3多级ifelse语句,if(表

31、达式1)分支一else if(表达式2)分支二,else if(表达式3)分支三else 分支n,多级if语句流程图,实例2-4,P0口接8只发光二极管,P1.0、P1.1分别接一个按键S1、S2,要求当没有键按下时,8全灭,当S1按键按下时,左边四个亮,当S2按键按下时,右边四个亮,当两个按键按下时,全亮。,流程图,源程序,#includesbit p10=P10;sbit p11=P11;void main()while(1)if(p10=0,P0口接8只发光二极管,P1.0、P1.1分别接一个按键S1、S2,要求当没有键按下时,8全灭,当S1按键按下时,左边四个亮,当S2按键按下时,右边

32、四个亮,当两个按键按下时,全亮。,4switch语句,switch(整形或字符型变量)case 变量可能值1:分支一;break;case 变量可能值2:分支二;break;case 变量可能值n:分支n;break;default:分支n+1或空语句;,switch语句流程图,【例2-5】,P1.0P1.3接4个按键,P1.4P1.7接4个发光二极管,现要求一般情况下,4个发光二极管全亮,如果只按S1时D1灭,只按S2时D2灭,依此类推。,源程序清单:,#includevoid main()unsigned char ctl;P1=0X0F;while(1)ctl=P1;,ctl=ctl,2

33、.2.3 循环语句,1while语句while(表达式)循环体,事先测试循环,在执行语句之前判断表达式,因此,循环可能没有执行循环体就退出。,【例2-6】,使用while语句实现从1到100的累加。,#include#includevoid main()unsigned int i=1;unsigned int sum=0;SCON=0 x52;TMOD=0 x20;TH1=0 xE8;TR1=1;,while(i=100)sum+=1;i+;printf(“sum=%dn”,sum);while(1),2for语句,for(表达式1;表达式2;表达式3)循环体 表达式1为循环控制变量初始化表

34、达式,表达式2为循环条件表达式,表达式3为循环控制变量增值表达式。“增值”仅仅是指循环控制变量发生了变化,不要按其字面意思去理解。,for语句的几点说明,for语句中的控制变量初始化表达式可以省略,但分号(;)不可省略。for语句中的循环条件表达式可以省略。此时一般要在循环体中对循环条件进行判断并提供退出循环的措施,否则会导致“死循环”。for语句中的循环控制变量增值表达式也可以省略。可以同时省略for语句中的循环控制变量初始化表达式和增量表达式,这样的for语句完全等价于while语句。,实例:,常见程序段:int i;for(i=0;i 30000;i+)自行完成例2-6的功能。,3dow

35、hile语句,do 循环体 while(表达式);,注意:在while(表达式)后面要加分号。,4嵌套的循环结构,实际应用中,经常要用到嵌套的循环结构。在嵌套循环结构中,内层循环需要置于称之为外层循环的另一个循环中。3种循环语句还可以互相嵌套。,【例2-9】,P0.0接一个发光二极管,P1.0按一个按键,要求当按键按下时,发光二极管不停地闪烁,当按键放开时,停止闪烁。,源程序清单:,#includesbit p10=P10;sbit p00=P00;void main()while(1)while(p10=0)p00=p00;,for(i=50000;i0;i-);,unsigned int

36、i;,2.2.4 转移语句,1break语句break;在switch语句中,break语句用来使流程跳出switch结构,继续执行switch之后的语句;在for语句中,break语句用来使流程跳出循环体,接着执行循环后面的语句。,【例2-10】,#include sbit P10=P10;sbit P00=P00;void main()int i;while(1)P0=P0;for(i=30000;i0;i+);if(P10=0)break;while(1);,针对例2-9,若与P0.0相连的发光二极管不停地闪烁,当与P1.0相连的按键按下时停止闪烁。,2.2.4 转移语句,2contin

37、ue语句 continue;continue语句的作用是跳过本次循环中剩余的循环体语句,立即进行下一次循环,【例2-11】,针对例2-9,其功能改变为当与P1.0相连的K1按下时,发光二极管暂停闪烁,K1放开时,发光二极管继续闪烁,试编写程序实现之。,#include sbit P10=P10;sbit P00=P00;void main()int i;while(1)if(P10=0)continue;P0=P0;for(i=30000;i0;i+);,2.3 C51函数与预编译处理,采用函数有以下优点:可以将不同的模块分别进行封装,使程序的整体结构清晰明了;可以增加程序的可重复使用性,减少

38、重复劳动;对于经常使用的程序段,使用函数可以显著地缩减代码的大小。,主函数与普通函数,主函数:每一个C51程序都必须至少有一个函数,以main为名,称为main函数或主函数。main函数是程序的入口,在程序运行时从main函数开始执行。普通函数:main函数之外的函数可以统称为普通函数。普通函数从用户使用的角度划分,可以分为标准函数(即库函数)和用户自定义函数。函数定义的形式上划分可以分为无参数函数、有参数函数和空函数。,2.3.1 函数的定义,函数定义的一般形式为有两种:ANSI C标准形式:类型标识符名 函数名(数据类型名 形式参数1,数据类型名 形式参数2,)函数体 老版C语言形式:类型

39、标识符名 函数名(形式参数1,形式参数2,)数据类型名 形式参数1;数据类型名 形式参数n;函数体,1无参数函数,类型标识符名 函数名()函数体,无参数函数往往并不返回函数值,在这种情况下,“类型标识符名,使用“void”!,串行口初始化函数,void serial_initial()SCON=0 x52;/设置串行口控制寄存器SCONTMOD=0 x20;/定时器1工作于方式2TH1=0 xE8;/11.0592MHz,1200波特率TR1=1;/启动定时器1TI=1;,2有参数函数,类型标识符名 函数名(数据类型名 形式参数1,数据类型名 形式参数2,)函数体,3空函数,类型标识符名 函数

40、名(),在实际设计中,在开发的初级阶段,程序的功能通常不是十分完善,这时就经常会使用空函数首先搭出程序的框架,再在后续的工作中逐渐扩充。但在最后定型的程序中一般是没有空函数的。,提 示:,(1)在同一工程中,函数名必须惟一。(2)形式参数在同一个函数中必须惟一,但可以与其他函数中的变量同名。(3)不能在一个函数中再定义函数。(4)在定义函数时应指明函数返回值的类型,如果没有函数返回值,应将设为void,若省略了函数返回值的类型,则默认为int型。(5)函数的返回值是通过函数中的return语句获得的,若不需要返回函数值,可以不要return语句。(6)函数名后面的圆括号不可省略,在圆括号后面也

41、不可加分号(;)。,2.3.2 函数参数和返回值,1形式参数和实际参数 在定义函数时函数名后面圆括号中的变量名称称为“形式参数”,简称“形参”;在主调函数调用被调函数时,函数名后面圆括号中的表达式称为“实际参数”,简称“实参”。,提 示:,(1)形式参数在函数定义的时候没有分配存储空间,只有在函数被调用时才分配存储空间,并把实际参数的值复制到分配的存储空间中。(2)形式参数和实际参数占据不同的地址,形式参数的变化不影响实际参数。(3)函数调用完毕后,形式参数的存储空间立即释放,但实际参数仍然存在并维持原值,能被其他函数继续使用。(4)实际参数的个数与形式参数的个数必须一致,在数据类型上与形式参

42、数一一对应匹配。(5)实际参数可以是常量、变量或表达式,但形式参数只能是变量。,2.函数的返回值,希望通过函数调用使主调函数能得到一个确定的值,这个值就是函数的返回值。函数的返回值是通过函数中的return语句获得的。如果需要从被调用函数中返回一个函数值,被调函数中必须包含return语句。返回值的类型必须与函数头中的类型标识符名致,否则以函数头中的类型为准,由系统自动转换。为了明确表示“不带回值”,可以用“void”定义“无类型”(或称“空类型”)。,2.3.3 函数的原型声明,C51语言中,主函数与其他函数是平行的,相对于在同一个源程序文件中的main()函数,其他函数可以在main()函

43、数之前定义。缺点:所有的函数都位于main()函数之前,使得整个源程序文件显得庞杂混乱。原型声明:所有的函数的定义都放在main()函数之后,但要在main()函数之前对其进行原型声明。,函数原型声明的格式,类型标识符 函数名(数据类型名;数据类型名,);,尖括号中的内容可选,也就是可以只列出各个形式参数的数据类型名而不必列出形式参数的名称。,注 意,函数原型声明与函数的定义是完全不同的,函数的定义是对函数功能的确立,是一个完整的函数单位。函数原型声明中的类型标识符名、函数名、形式参数的数据类型名都要和函数定义中一致,并且在圆括号后面必须加分号(;)。,2.3.4 函数的调用,1函数调用的一般

44、形式 函数名(实际参数列表);如果被调函数是无参数函数,则实际参数列表为空,但函数名后面的圆括号不能省略。如果实际参数列表包括多个实际参数,则各参数之间用逗号隔开,实际参数与形式参数的个数应该相等,类型应该一致,实际参数与形式参数按顺序对应,一一传递数据。,2函数调用的方式,(1)函数语句:把函数调用作为一个语句。此时不要求被调函数返回函数值,只是完成一定的操作。(2)函数表达式:函数出现在一个表达式中,这种表达式称为函数表达式,这时要求函数带回一个确定的值来参与运算。(3)函数参数:在主调函数中将函数调用作为另一个函数调用的实际参数。这种在一个函数的过程中又调用了另外一个函数的方式,称为嵌套

45、函数调用。,2.3.5 内部函数与外部函数,1内部函数 内部函数只能被本文件中其他函数所调用。static 类型标识符名 函数名(数据类型名 形式参数1,数据类型名 形式参数2,)函数体 内部函数又称静态函数。使用内部函数可以使函数只局限于所在文件,即使不同的文件中有相同函数名的函数也不会相互干扰。通常把只由同一文件使用的函数和外部变量放在一个文件中,用static加以说明使之局部化,限制其他文件对其引用。,2外部函数,外部函数的定义方法是在函数的类型标识符名前加extern,即:extern 类型标识符名 函数名(数据类型名 形式参数1,数据类型名 形式参数2,)函数体如果在定义函数时省略e

46、xtern,则默认为外部函数。在需要调用此函数的文件中对此函数进行原型声明时一般也要用extern来说明所用的函数是外部函数。,2.3.6 预处理命令,在源程序中这些命令都放在函数之外,并且一般都放在源文件的前面。在编译系统对程序进行通常的编译(包括词法分析、语法分析、代码生成、代码优化等)之前,先对程序中这些特殊的命令进行预处理,然后将预处理的结果和源程序一起再进行通常的编译处理,以得到目标代码。这些特殊的命令就是预处理命令。(1)宏定义;(2)文件包含;(3)条件编译。,1宏定义,宏定义命令为#define,其作用是用一个标识符来表示一个字符串,称为宏。被定义为宏的标识符称为宏名,而被代替

47、的字符串既可以是常数,也可以是其他任何字符串。在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为宏代换或宏展开。,(1)不带参数的宏定义,#define 宏名(字符串)当字符串为常数时通常不加括号 常对程序中反复使用的表达式进行宏定义,字符串为表达式时要加括号 宏名的有效范围是从宏定义命令#define开始,直到本源文件结束,或用undef终止宏定义。,(2)带参数的宏定义,#define 宏名(形参表)(字符串)在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。带参数的宏定义将一个带形式参数的表达

48、式定义为一个带形式参数表的宏名。对程序中所有带实际参数表的该宏名都用指定的表达式来替换,同时用参数表中的实际参数替换表达式中对应的形式参数。,提 示:,1)带参数的宏定义在进行宏展开时,只是用语句中宏名后面括号内的实际参数字符串来替换define命令行中的形式参数。因此,对于宏展开后可能出现错误的表达式,在进行宏定义时应将该表达式用圆括号括起来。2)在宏定义时,在宏名与带参数的括号之间不能加空格,否则将空格以后的字符都作为替代字符串的一部分。,宏定义与函数的区别,2文件包含,文件包含处理是指一个源文件可以将另外的文件包含到本文件中。文件包含命令行的一般形式为:#include 文件包含命令的功

49、能是把指定的文件插入该命令行位置取代该命令行,从而把指定的文件和当前的源程序文件连成一个源文件。,说 明,(1)包含命令中的文件名可以用双引号括起米,也可以用尖括号括起来。使用尖括号表示在包含文件目录中去查找(包含目录是由用户在设置环境时设置的)。使用双引号则表示首先在当前的源文件目录中查找,若未找到才到包含目录中去查找。,说 明,(2)一个include命令只能指定一个被包含文件,若有多个文件要包含则需用多个include命令。(3)文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。(4)被包含文件与其所在的文件在预编译后已经成为同一个文件而不是两个文件,因此,如果被包含文件(f

50、ilel.h)中有全局静态变量,则这些全局静态变量也在filel.c中有效,不必用extern说明。,单片机的定时控制功能是由片内的时钟电路和定时电路来完成的,而片内的时钟产生有两种方式:内部时钟方式外部时钟方式,2.4 单片机时钟电路及CPU时序,2.4.1 单片机时钟电路,内部振荡器方式,外部振荡器方式,两种时钟电路,片内的高增益反相放大器通过XTAL1、XTAL2外接作为反馈元件的片外晶体振荡器(呈感性)与电容组成的并联谐振回路构成一个自激振荡器,向内部时钟电路提供振荡时钟。振荡器的频率主要取决于晶体的振荡频率,一般晶体可在1.212 MHz之间任选,电容C1、C2可在530pF之间选择

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号