MCS 51单片机C语言程序设计解读课件.ppt

上传人:小飞机 文档编号:1481154 上传时间:2022-11-30 格式:PPT 页数:128 大小:1.58MB
返回 下载 相关 举报
MCS 51单片机C语言程序设计解读课件.ppt_第1页
第1页 / 共128页
MCS 51单片机C语言程序设计解读课件.ppt_第2页
第2页 / 共128页
MCS 51单片机C语言程序设计解读课件.ppt_第3页
第3页 / 共128页
MCS 51单片机C语言程序设计解读课件.ppt_第4页
第4页 / 共128页
MCS 51单片机C语言程序设计解读课件.ppt_第5页
第5页 / 共128页
点击查看更多>>
资源描述

《MCS 51单片机C语言程序设计解读课件.ppt》由会员分享,可在线阅读,更多相关《MCS 51单片机C语言程序设计解读课件.ppt(128页珍藏版)》请在三一办公上搜索。

1、第 4 章 单片机C语言程序设计,主要内容,一、C语言与MCS-51二、C51的数据类型三、C51的运算量与存储类型四、C51的运算符和表达式五、表达式语句与复合语句六、C51的输入/输出七、C51的程序结构八、函数九、C51构造数据类型,一、C语言与MCS-51,1、C语言与51单片机2、C51与标准C3、C51程序结构,1、C语言与51单片机,C语言目前已成为电子工程师进行单片机系统开发时的常用编程语言。用C语言来编写目标系统软件,会大大缩短开发周期,且明显地增加软件的可读性,便于改进和扩充。用C语言编写的应用程序必须经单片机的C语言编译器(简称C51),转换生成单片机可执行的代码程序。基

2、于51系列单片机的C语言或C语言编译器简称为C51语言或C51。,1、C语言与51单片机,用汇编程序设计MCS51系列单片机应用程序时,必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能寄存器正确、合理的使用以及按实际地址处理端口数据。用C语言编写MCS51单片机的应用程序,虽然不像用汇编语言那样具体地组织、分配存储器资源和处理端口数据,但在C语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确地映射定位。,1、C语言与51单片机,支持MCS51系列单片机的C语言编译器有很多种。如American Automation、Avocet、BSO/TAS

3、KING、DUNFIELD SHAREWARE、KEIL、Franklin等。其中KEIL以它的代码紧凑和使用方便等特点优于其它编译器,目前用得最为普遍。,2、C51与标准C,C51的主要语法规定、程序结构及程序设计方法都与标准的C语言相同,但在某些方面有区别。 具体地说,在以下几个方面不一样:(1)C51中定义的库函数和标准C语言定义的库函数不同。标准的C语言定义的库函数是按通用微型计算机来定义的,而C51中的库函数是按MCS-51单片机相应情况来定义的;(2)C51中的数据类型与标准C的数据类型也有一定的区别,在C51中还增加了几种针对MCS-51单片机特有的数据类型;,2、C51与标准C

4、,(3)C51变量的存储模式与标准C中变量的存储模式不一样,C51中变量的存储模式是与MCS-51单片机的存储器紧密相关的;(4)C51与标准C的输入输出处理不一样,C51中的输入输出是通过MCS-51串行口来完成的,输入输出指令执行前必须要对串行口进行初始化;(5)C51与标准C在函数使用方面也有一定的区别,C51中有专门的中断函数。,3、C51程序结构,和标准C程序结构相同,采用函数结构每个C51程序由一个或多个函数组成,在这些函数中至少应包含一个主函数main(),也可以包含一个main()函数和若干个其它的功能函数。程序的执行总是从main()函数开始的,其位置无特殊规定。程序的开始部

5、分一般是预处理命令、函数说明和变量定义等。,预处理命令 include函数说明 long fun1(); float fun2(); int x,y; float z;功能函数1 fun1() 函数体 功能函数2 fun2() 函数体 主函数 main() 主函数体 ,实例 简单控制指示灯,功能要求:系统启动后,当按下一个按钮开关后再闪烁5次后熄灭。以后每次按下按钮开关,发光二极管都会闪烁5次。,硬件设计:,实际动手:,仿真:(Proteus),C程序(续):,#include #include sbit p10=P10;sbit p20=P20;void delay(unsigned int

6、 i);void main() int n,c;P1=0 xff;P2=0 xff;,C程序(续):,if (p20=0)c=1;if (c=1) n=5; while (n0) p10=0 ; delay(10000000); p10=1; delay(10000000); n-; c=0;,C程序(续):,void delay(unsigned int i) unsigned int j; for (j=0;ji;j+) ,汇编程序,org 0000hsjmp mainorg 0030hmain: mov p2,#0ffh mov c,p2.0 jc main mov r0,#5hloop

7、: mov p1,#00h acall delay mov p1,#0ffh acall delay djnz r0,loop sjmp main,汇编程序,delay: mov r1,#05hnext2: mov r2,#0ffhnext1: mov r3,#0FFh djnz r3,$ djnz r2,next1 djnz r1,next2 retend,二、C51的数据类型,特殊功能寄存器型,这是C51扩充的数据类型,用于访问MCS-51单片机中的特殊功能寄存器数据,它分sfr和sfr16两种类型。sfr为字节型特殊功能寄存器类型,占一个内存单元;sfr16为双字节型特殊功能寄存器类型,

8、占用两个字节单元。利用它们可以访问MCS-51内部的所有两个字节的特殊功能寄存器。在C51中对特殊功能寄存器的访问必须先用sfr或sfr16进行声明。,位类型,这也是C51中扩充的数据类型,用于访问MCS-51单片机中的可寻址的位单元。在C51中,支持两种位类型:bit型和sbit型。它们在内存中都只占一个二进制位,其值可以是“1”或“0”。其中用bit定义的位变量在C51编译器编译时,在不同的时候位地址是可以变化的,而用sbit定义的位变量必须与MCS-51单片机的一个可以寻址位单元或可位寻址的字节单元中的某一位联系在一起,在C51编译器编译时,其对应的位地址是不可变化的。,三、C51的运算

9、量与存储类型,1、常量2、变量 3、存储模式4、绝对地址的访问5、对特殊功能寄存器的访问6、对并行口的访问7、对位地址的访问,1、常量,常量是指在程序执行过程中其值不能改变的量。C51中支持整型常量、浮点型常量、字符型常量和字符串型常量。,(1)整型常量 C51中整型常量可以表示成以下几种形式:十进制整数。如234、-56、0等。十六进制整数。以0 x开头表示,如0 x12表示十六进制数12H。长整数。在C51中当一个整数的值达到长整型的范围,则该数按长整型存放,在存储器中占四个字节,另外,如一个整数后面加一个字母L,这个数在存储器中也按长整型存放。如123L在存储器中占四个字节。,(2)浮点

10、型常量 浮点型常量也就是实型常数。有十进制表示形式和指数表示形式。十进制表示形式又称定点表示形式,由数字和小数点组成。如 0.123、34.645等都是十进制数表示形式的浮点型常量。指数表示形式为: 数字 .数字 e 数字 例如:123.456e-3、-3.123e2等都是指数形式的浮点型常量。,(3)字符型常量字符型常量是加单引号的字符,如a、1、F等。可以是可显示的ASCII字符,也可以是不可显示的控制字符。对不可显示的控制字符须在前面加上反斜杠“”组成转义字符。利用它可以完成一些特殊功能和输出时的格式控制。常用的转义字符如课本P73表4-4所示。,表4.4 常用转义字符,(4)字符串型常

11、量字符串型常量由双引号“”括起的字符组成。如“D”、“1234”、“ABCD”等。字符串常量与字符常量是不一样的,一个字符常量在计算机内只用一个字节存放,而一个字符串常量在内存中存放时不仅双引号内的字符一个占一个字节,而且系统会自动的在后面加一个转义字符“0”作为字符串结束符。因此不要将字符常量和字符串常量混淆,如字符常量A和字符串常量“A”是不一样的。,2、变量,在C51中,变量在使用前必须对变量进行定义,指出变量的数据类型和存储模式。以便编译系统为它分配相应的存储单元。定义的格式如下:,存储种类 数据类型 存储器类型 变量名表,(1)存储种类,存储种类是指变量在程序执行过程中的作用范围。C

12、51变量的存储种类有四种,分别是自动(auto)、外部(extern)、静态(static)和寄存器(register)。如果省略存储种类,则该变量默认为自动(auto)变量。,(2)数据类型说明符 数据类型说明符:指明变量的数据类型,指明变量在存储器中占用的字节数。可以是基本数据类型说明符,也可以是组合数据类型说明符,还可以是用typedef或#define定义的类型别名。 在C51中,为了增加程序的可读性,允许用户为系统固有的数据类型说明符用typedef或#define起别名,格式如下: typedef c51固有的数据类型说明符 别名; 或 #define 别名 C51固有的数据类型说

13、明符; 定义别名后,就可以用别名代替数据类型说明符对变量进行定义。别名可以用大写,也可以用小写。,例如:#define uchar unsigned char #define uint unsigned int 这样,在编程中,就可以用uchar代替unsigned char,用uint代替unsigned int来定义变量。,(3)存储器类型,存储器类型:是指定义变量时,根据51单片机存储器的特点,指明该变量所处的单片机的内存空间。MCS-51单片机的存储区主要有:片内数据存储器,特殊功能寄存器、片外数据存储器、片内程序存储器和片外程序存储器。使用汇编指令访问时,使用不同的指令和不同的寻址方

14、式即可区分。在C51中,则要通过定义存储器类型来加以说明。,(3)存储器类型,C5l编译器支持MCS-51单片机的硬件结构,可完全访问MCS-51硬件系统的所有部分。编译器通过将变量或者常量定义成不同的存储类型(data,bdata,idata,pdata,xdata,code)的方法,将它们定位在不同的存储区中。,表 C51存储器类型,(3)存储器类型,若未定义存储类型,则C51编译器自动选择默认存储器类型。默认的存储器类型与C51的存储模式有关。,(4)变量名表,变量名表格式: 变量名1=初值,变量名2=初值,.在C51中规定变量名可以由字母、数字和下划线三种字符组成,且第一个字母必须为字

15、母或下划线。变量名有两种:普通变量名和指针变量名。指针变量名前面要带“ * ”号。,例:定义变量,char i, j, k;unsigned int xdata m, n;unsigned pdata *dp1;long count; sfr P1=0 x90;,3、存储模式,如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由存储模式决定。存储模式是编译器的编译选项。可在软件中设置,或用预处理命令设置。C51的存储模式(memory models)有三种:SMALL、COMPACT和LARGE。,3、存储模式,(1)小模式 (small model)

16、。在小模式下,所有未声明存储器类型的变量,都默认驻留在内部数据区,即这种方式和用DATA进行显示说明一样。(2)紧凑模式 (compact model)。在紧凑模式下,所有未声明存储器类型的变量,都默认驻留在外部数据区的一个页上。即这种方式和用PDATA进行变量存储器类型的说明是一样的。该模式利用R0和R1寄存器来进行间接寻址(R0和Rl)。,3、存储模式,(3)大模式(large model)。在大模式下,所有未声明存储器类型的变量,都默认驻留在外部数据存储区,即和用XDATA进行显示说明一样。此时最大可寻址64KB的存储区域,使用数据指针寄存器(DPTR)来进行间接寻址。,3、存储模式,设

17、定存储模式的预处理命令:#pragma small#pragma compact#pragma large,4、绝对地址的访问,(1)使用预定义宏访问(2)使用指针访问(3)使用 _at_ 关键字访问,(1)使用预定义宏访问,C51编译器提供了一组宏定义来对51系列单片机的code、data、pdata和xdata空间进行绝对寻址。规定只能以无符号数方式访问,定义了8个宏定义,其函数原型放在absacc.h文件中。使用时须用预处理命令把该头文件包含到文件中,形式为: #include 这些宏定义函数原型如下:,#define CBYTE(unsigned char volatile*)0 x5

18、0000L)#define DBYTE(unsigned char volatile*)0 x40000L)#define PBYTE(unsigned char volatile*)0 x30000L)#define XBYTE(unsigned char volatile*)0 x20000L)#define CWORD(unsigned int volatile*)0 x50000L)#define DWORD(unsigned int volatile*)0 x40000L)#define PWORD(unsigned int volatile*)0 x30000L)#define X

19、WORD(unsigned int volatile*)0 x20000L)说明:Cxxxx:code区,Dxxxx:data区,Pxxxx:pdata区,Xxxxx:xdata区。 BYTE:以字节形式寻址,WORD:以字形式寻址。,(1)使用预定义宏访问,使用预定义宏访问绝对地址的形式如下: 宏名地址如: DBYTE0 x0030 XWORD0 x0005,#include #include #define uchar unsigned char #define uint unsigned int void main(void)uchar var1;uint var2;var1=XBYTE

20、0 x0005; /*访问片外RAM的0005字节单元*/var2=XWORD0 x0000; /*访问片外RAM的0000字单元*/XWORD0 x0000=0 xAABB; /*将0 xAABB送入片外RAM的0000H0001H单元中*/.while(1);,(2)使用指针访问,采用指针的方法,可以在C51程序中对任意指定的存储器单元进行访问。 方法:先定义,后赋绝对地址值,#define uchar unsigned char #define uint unsigned int void test_memory(void)uchar idata ivar1;uchar xdata *x

21、dp; /*定义一个指向xdata区的指针*/char data *dp; /*定义一个指向data区的指针*/uchar idata *idp; /*定义一个指向idata区的指针*/xdp=0 x1000; /*xdp指针赋值指向xdata区的1000H单元*/*xdp=0 x5A; /*数据5AH送到xdata区的1000H单元*/dp=0 x61; /*dp指针赋值指向data区61H单元*/*dp=0 x23; /*将数据23H送到data区61H单元*/idp= /*数据16H送到idata区的变量ivar1所在的地址单元中,等价于ivar1=0 x16*/,(3)使用_at_关键

22、字访问,格式如下:存储器类型 数据类型说明符 变量名 _at_ 地址常数;说明:地址常数应在有效地址范围内用_at_定义的变量必须是全局变量,#define uchar unsigned char #define uint unsigned int data uchar x1 _at_ 0 x40; /*在data区中定义字节变量x1,它的地址为40H*/xdata uint x2 _at_ 0 x2000; /*在xdata区中定义字变量x2,它的地址为2000H*/void main(void)x1=0 xff;x2=0 x1234;.while(1);,5、对特殊功能寄存器的访问,如果不

23、作定义,对51单片机的特殊功能寄存器只能用直接寻址方式访问。为了能用名字直接访问这些特殊功能寄存器,C51提供了定义方法。可分为以下两种方法:(1)用sfr/sfr16数据类型访问特殊功能寄存器(2)用sbit数据类型访问特殊位,(1)用sfr/sfr16数据类型访问,访问特殊功能寄存器可用数据类型定义的方法来实现。格式如下: sfr/sfr16 特殊功能寄存器名=地址;说明:特殊功能寄存器名必须大写。sfr定义8位寄存器;sfr16定义16位寄存器。定义之后,就可以程序中直接引用寄存器名了。标准SFR在reg51.h等头文件中已经定义好,只要用#include包含命令申明即可使用。,(1)用

24、sfr/sfr16数据类型访问,定义举例:(地址可在表2.4中查出)sfr PSW=0 xd0;sfr SCON=0 x98;sfr TMOD=0 x89;sfr P1=0 x90;sfr16 DPTR=0 x82;sfr16 T1=0X8A;,(2)用sbit数据类型访问特殊位,MCS-51单片机内21个特殊功能寄存器中,共有11个特殊功能寄存器是可位寻址的。访问这些特殊位可用关键字sbit定义数据类型来实现。格式如下: sbit 特殊功能寄存器位名=位地址;其中,位地址有3种表示方法:特殊功能寄存器名位号 (如:P10)特殊功能寄存器地址位号 (如:0 xD00)特殊功能寄存器绝对位地址

25、(如:0 xD7),(2)用sbit数据类型访问特殊位,定义举例: sfr PSW=0 xD0; sbit OV=PSW2; sbit AC=0 xD02; sbit CY=0 xD7;,(2)用sbit数据类型访问特殊位,程序中的例子:#include sbit P10=P10;sbit P12=P12;void main() P10=1; P12=0; .,6、对并行口的访问,(1) 内部并口 用sfr定义(前面已介绍,略)(2) 外部并口 对片外扩展的并口,应根据其硬件译码地址,将其看作片外数据存储器的一个单元,使用#define语句进行定义。定义时用绝对地址定义,绝对地址定义在absa

26、cc.h头文件中。,6、对并行口的访问,例:操作片外并口#include #define PA XBYTE 0 xffecvoid main() PA=0 x30; /*将数据30H写入地址为0 xffec的存储单元或I/O端口*/,7、对位地址的访问,C51中可使用bit和sbit数据类型对位地址进行访问。bit定义格式如下: bit 位变量名;例: bit data a1; bit bdata a2;,四、C51的运算符和表达式,1赋值运算符2算术运算符3自增自减运算符4关系运算符5逻辑运算符6位运算符7复合运算符8. 对指针操作的运算符9. 条件运算符,四、C51的运算符和表达式,1赋值

27、运算符 赋值运算符 =在C中它的功能是给变量赋值,如x=10。赋值表达式后面加“;”号就构成了一个赋值表达式语句。,四、C51的运算符和表达式,2算术运算符C51中的算术运算符如下:+ 加或取正值运算符 减或取负值运算符* 乘运算符/ 除运算符% 模(取余)运算符,如8 % 5 = 3,即8除以5的余数是3,3自增自减运算符 自增: + + 自减: 自增自减运算符可用在操作数之前,也可放在其后,例如“x=x+1”既可以写成“+x”,也可写成“x+”,其运算结果完全相同。但在表达式中这两种用法是有区别的。,四、C51的运算符和表达式,四、C51的运算符和表达式,例: x=99; y=+x; 则y

28、=100,x=100,如果程序改为: x=99; y=x+; 则y=99,x=100。在这两种情况下,x都被置为100。一般来说,用自增和自减操作生成的程序代码比等价的赋值语句生成的代码要快。,四、C51的运算符和表达式,4关系运算符 C51中有6种关系运算符: 大于 = 大于等于 x+12”的计算,应看作是“10(x+12)”。,四、C51的运算符和表达式,5逻辑运算符逻辑与:& 逻辑或:| 逻辑非:!用法:逻辑与:条件式1 & 条件式2。逻辑或:条件式1 | 条件式2。逻辑非:!条件式。,四、C51的运算符和表达式,例如,当a = 7, b = 6, c = 0时,则:!a =0,!c=1

29、。a (a8) & (b0) =0。,四、C51的运算符和表达式,6位运算符 位运算符的作用是按位对变量进行运算,但并不改变参与运算的变量的值。位运算符不能用来对浮点型数据进行操作。位运算一般的表达形式如下: 变量1 位运算符 变量2,四、C51的运算符和表达式,6位运算符C51中共有6种位运算符:& 按位与| 按位或 按位异或 按位取反 右移,四、C51的运算符和表达式,6位运算符 位运算符也有优先级,从高到低依次是: (按位取反) (右移)& (按位与) (按位异或) | (按位或),四、C51的运算符和表达式,如:已知a = 0 x54 = 0101 0100B, b = 0 x3b =

30、 0011 1011B,则: a b1 = 00011101。,四、C51的运算符和表达式,7复合运算符 复合运算符就是在赋值运算符“=”的前面加上其他运算符。以下是C51语言中的复合赋值运算符:+= 加法赋值 = 右移位赋值-= 减法赋值 &= 逻辑与赋值*= 乘法赋值 |= 逻辑或赋值/= 除法赋值 = 逻辑异或赋值%= 取模赋值 = 逻辑非赋值= 左移位赋值,四、C51的运算符和表达式,7复合运算符其含义就是变量与表达式先进行运算符所要求的运算,再把运算结果赋值给参与运算的变量。其实这是C语言中简化程序的一种方法,凡是二目运算都可以用复合赋值运算符去简化表达。例如:a+=56等价于a=a

31、+56 y/=x+9 等价于 y=y/(x+9)。,四、C51的运算符和表达式,8.对指针操作的运算符&取地址运算符* 取内容运算符 & 又能用于按位与,此时 “&”的两边 必须有操作对象。 * 还可作为指针变量的标志,但此时 一定出现在对指针定义中。,四、C51的运算符和表达式,9. 条件运算符 C51条件运算符 ?: 条件运算符是C51语言中唯一的一个三目运算符,它要求有三个运算对象,用它可以将三个表达式连接在一起构成一个条件表达式。条件表达式的一般格式为: 逻辑表达式?表达式1:表达式2,四、C51的运算符和表达式,9. 条件运算符 逻辑表达式?表达式1:表达式2 其功能是先计算逻辑表达

32、式的值,当逻辑表达式的值为真(非0值)时,将计算的表达式1的值作为整个条件表达式的值;当逻辑表达式的值为假(0值)时,将计算的表达式2的值作为整个条件表达式的值。 例如:条件表达式max=(ab)?a:b的执行结果是将a和b中较大的数赋值给变量max。,五、表达式语句与复合语句,1、C51基本书写规则书写格式相对自由,一行可以写若干条语句,一个语句也可以写成几行,每个语句须以分号“;”结尾。C语言是区分大小写的一种高级语言。使用标识符和关键词时须注意大小写。每个变量必须先说明后引用程序的注释用 /*.*/ 或 /. 表示。函数语句块写在大括号 里面。表达式写在小括号( )里面。,五、表达式语句

33、与复合语句,2、表达式语句 在表达式的后边加一个分号“;”就构成了表达式语句,如: a=+b*9; x=8;y=7; 可以一行放一个表达式形成表达式语句,也可以一行放多个表达式形成表达式语句,这时每个表达式后面都必须带“;”号,另外,还可以仅由个分号“;”占一行形成一个表达式语句,这种语句称为空语句。,五、表达式语句与复合语句,3、复合语句 复合语句是由若干条语句组合而成的一种语句,在C51中,用一个大括号“ ”将若干条语句括在一起就形成了一个复合语句,复合语句最后不需要以分号“;”结束,但它内部的各条语句仍需以分号“;”结束。复合语句的一般形式为: 局部变量定义; 语句l; 语句2; ,六、

34、C51的输入/输出,在C51语言中,它本身不提供输入和输出语句,输入和输出操作是由函数来实现的。在C51的标准函数库中提供了一个名为“stdio.h”的一般I/O函数库,它当中定义了C51中的输入和输出函数。当对输入和输出函数使用时,须先用预处理命令“#include ”将该函数库包含到文件中。C51中, 输入/输出函数较少使用。,七、C51的程序结构,C51语言可分为三种基本结构:顺序结构选择结构循环结构,七、C51的程序结构,1、顺序结构顺序结构是指程序按语句的先后顺序逐句执行,是最基本、最简单的一种程序结构。 例求圆面积和周长的程序。 #include ”stdio.h” #define

35、 PI 3.14 main( )float r,s,y;*定义三个浮点型变量*r=30; s=PI * r * r;y=2*PI*r;,七、C51的程序结构,2、选择结构 在C51中,实现选择结构的语句有:if/else,if/else if语句switch/case语句,(1) if语句,if 语句通常有三种格式:1)if (表达式) 语句;2)if (表达式) 语句1; else 语句2;3)if (表达式1) 语句1; else if (表达式2) (语句2;) else if (表达式3) (语句3;) else if (表达式n-1) (语句n-1;) else 语句n,例1从键盘输

36、入两实数,然后按值的大小顺序输出,#include ”stdioh” main( ) float a,b,t; scanf(“f,f”, ,例2 双分支,if (x=1) y=x+5;else y=x*5;,(2)switch/case语句,switch是C51中提供的专门处理多分支结构的多分支选择语句。它的格式如下:switch (表达式) case 常量表达式1:语句1;break; case 常量表达式2:语句2;break; case 常量表达式n:语句n;break; default:语句n+1;,例 多分支,switch (score) case 10:case 9:g=A;bre

37、ak;case 8:g=B;break;case 7:g=C;break;case 6:g=D;break;case 5:case 4:case 3:case 2:case 1:case 0:g=E; ,七、C51的程序结构,3、循环结构 实现循环结构的语句主要有:while语句do while语句for语句,(1)while语句,while语句在C51中用于实现当型循环结构,它的格式如下: while(表达式) 语句;,例 求1十2十3十100的和。,int i ,sum=0; i=1; while(i=100) sum=sum + i; i+; ,(2)do while语句,do whil

38、e语句在C51中用于实现直到型循环结构,它的格式如下: do 语句; while(表达式);,例 求1十2十3十100的和。,inti ,sum=0; i=1; do sum=sum+i; i+; while(i=100);,(3)for语句,for语句可以方便地实现计数循环,格式如下: for(表达式1;表达式2;表达式3) 语句; 例求1十2十3十100的和。 int t, sum=0; for(i=1; i100;i+) sum=sum+i;,(4)break和continue语句,break语句break语句可以跳出switch结构,使程序继续执行switch结构后面的一个语句。bre

39、ak语句还可以从循环体中跳出循环,提前结束循环而接着执行循环结构下面的语句。,【例4-19】下面一段程序用于计算圆的面积,当计算到面积大于100时,由break语句跳出循环。for (r=1;r100) break;,break和continue语句,continue语句用在循环结构中,用于结束本次循环,跳过循环体中continue下面尚未执行的语句,直接进行下一次是否执行循环的判定。,【例4-20】 输出100200间不能被3整除的数。 for (i=100;i=200;i+) if (i%3= =0) continue; printf(“%d ”;i); ,(5)goto语句,goto语句

40、的格式为: goto 语句标号; goto语句是无条件转移语句,它将程序运行的流向转到指定的标号处。,八、函数,1、函数的定义函数定义的一般格式如下:函数类型 函数名(形式参数表) interrupt n using n形式参数说明局部变量定义函数体(有返回值的要有return语句),例:,delay(int t) /*延时函数*/ int i,j; /*采用默认的存储类型*/ /*用双重空循环延时*/ for(i=0; it; i+) for(j=0; j10; j+); ,1、函数的定义,格式说明:(1)函数类型 函数类型说明了函数返回值的类型。(2)函数名 函数名是用户为自定义函数取的名

41、字以便调用函数时使用。(3)形式参数表 形式参数表用于列录在主调函数与被调用函数之间进行数据传递的形式参数。,(4)interrupt n 修饰符,interrupt n是C51函数中非常重要的一个修饰符,这是因为中断函数必须通过它进行修饰。在C51程序设计中,当函数定义时用了interrupt n修饰符,系统编译时把对应函数转化为中断函数,自动加上程序头段和尾段,并按MCS-51系统中断的处理方式自动把它安排在程序存储器中的相应位置。,(4)interrupt n 修饰符,其中,n的取值为031,对应的中断情况如下:0外部中断01定时/计数器T02外部中断13定时/计数器T14串行口中断5定

42、时/计数器T2其它值预留。,编写MCS-51中断函数注意如下:1)中断函数不能进行参数传递,如果中断函数中包含任何参数声明都将导致编译出错。2)中断函数没有返回值,如果企图定义一个返回值将得不到正确的结果,建议在定义中断函数时将其定义为void类型,以明确说明没有返回值。3)在任何情况下都不能直接调用中断函数,否则会产生编译错误。因为中断函数的返回是由8051单片机的RETI指令完成的,RETI指令影响8051单片机的硬件中断系统。如果在没有实际中断情况下直接调用中断函数,RETI指令的操作结果会产生一个致命的错误。,4)使用C51编写中断服务程序,程序员无需关心ACC、B、DPH、DPL、P

43、SW等寄存器的保护,C51编译器会根据上述寄存器的使用情况在目标代码中自动增加压栈和出栈。,例:一个定时器中断服务程序,void Timer_Initial(void) TMOD = 0 x01; /timer0, mode 1; TH0 = (65535 - 50000)/256; TL0 = (65535 - 50000)%256; /50ms ET0 = 1; /open the timer isr TR0 = 1; /begin the counter EA = 1;,void Timer_ISR(void) interrupt 1 static int num=0; TH0 = (6

44、5535 - 50000)/256; TL0 = (65535 - 50000)%256; /50ms num+; if(num=20) num = 0;. ,(5)函数返回值,返回语句return用来回送一个数值给定义的函数,从函数中退出。返回值是通过return语句返回的。返回值的类型如果与函数定义的类型不一致,那么返回值将被自动转换成函数定义的类型。如果函数无须返回值,可以用void类型说明符指明函数无返回值。,例:,int add(int c,int d,int e,int f)int result;result=max(c,d)+max(e,f); /调用函数maxreturn(re

45、sult);,(6)using n 修饰符,修饰符using n用于指定本函数内部使用的工作寄存器组,其中n的取值为03,表示寄存器组号。 对于using n修饰符的使用,注意以下几点:1)加入using n后,C51在编译时自动的在函数的开始处和结束处加入以下指令。PUSH PSW ;标志寄存器入栈MOV PSW,#与寄存器组号相关的常量POP PSW ;标志寄存器出栈,(6)using n 修饰符,2)using n修饰符不能用于有返回值的函数,因为C51函数的返回值是放在寄存器中的。如寄存器组改变了,返回值就会出错。,2、函数的调用与声明,函数调用的一般形式如下: 函数名(实参列表);,

46、2、函数的调用与声明,被调用的函数必须是已经存在的函数。按照函数调用在主调函数中出现的位置,函数调用方式有以下三种:(1)函数作为语旬。把函数调用作为一个语句,不使用函数返回值,只是完成函数所定义的操作。例如: refresh_led( );,(2)函数作为表达式。函数调用出现在一个表达式中,使用函数的返回值。 int k; k=sum(a,b);(3)函数作为一个参数。函数调用作为另一个函数的实参。 int k; k=sum(sum(a,b),c);,函数的声明,与使用变量一样,在调用一个函数之前,必须对该函数进行声明。函数声明的一般格式为 extern 函数类型 函数名(形式参数列表) 函

47、数定义时参数列表中的参数称为形式参数,简称形参。函数调用时所使用的替换参数,是实际参数,简称实参。定义的形参与函数调用的实参类型应该一致,书写顺序应该相同。,如果声明的函数在文件内部,则声明时不用extern,如果声明的函数不在文件内部,而在另一个文件中,声明时须带extern,指明使用的函数在另一个文件中。,3、函数的嵌套与递归,1)函数的嵌套 在一个函数的调用过程中调用另一个函数。2)函数的递归 自身调用。因51单片机的RAM空间小,嵌套与递归的深度都较小。递归一般较少使用。,九、C51构造数据类型,数组指针结构联合枚举 因51单片机存储器容量较小,以上数据类型中较常用的有数组和指针,其余

48、较少使用。,十、C编程与单片机开发板使用实例,使用51单片机,用4个按键来控制4个LED灯的亮灭,当按键K1按下时,LED1发光;K2被按下时,LED2发光.K4被按下时,LED4发光。请编程并使用单片机开发板实现。,#include sbit p30=P30;sbit p31=P31;sbit p32=P32;sbit p33=P33;sbit p00=P00;sbit p01=P01;sbit p02=P02;sbit p03=P03;,void main(void) P3=0 xFF; P0=0 xFF; if (p33=0) p03=0; if (p32=0) p02=0; if (p31=0) p01=0; if (p30=0) p00=0; ,END,

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

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


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号