1、C程序的设计,单片机原理与应用,C 语言是一种结构化语言。所谓结构化语言就是不允许交叉程序的存在。结构化语言的基本元素是模块,在C语言中也称为函数。它是程序的一部分,只有一个出口和一个入口,不允许中途插入,也不允许以模块的其它路径退出。结构化编程语言在没有恢复堆栈和其它相关的寄存器之前,不应随便跳入或跳出一个模块。,C语言作为一种非常方便的语言而得到广泛的支持。 C语言程序本身不依赖于机器硬件系统,基本上不作修改就可将程序从不同的单片机中移植过来。 C提供了很多数学函数并支持浮点运算,开发效率高,故可缩短开发时间,增加程序可读性和可维护性。,单片机原理与应用,C语言程序的基本结构,单片机原理与
2、应用,C语言的程序结构C语言程序的基本结构可以分成三部分,即:主程序、函数和头文件。,1主程序 C语言的主程序是C语言开始执行 的程序,是不可缺少的部分,它是用main为函 数命名的。,单片机原理与应用,例2-1:如图2-1所示的电路,试写出一段程序,运行 后,使P1口上连接的8个LED发光二极管全亮。,图2-1 将变 量的 数值 从P1 口输 出,应用程序:,main( ) char a;a=0;P1=a;,单片机原理与应用,在主程序中,首先定义一个字符型变量char a,再给变量a赋值为0,最后从P1口输出变量a的值0,P1口为低电平,LED上有电流通过,所以8个LED发光二极管都亮。,程
3、序分析:,单片机原理与应用,2、函数 函数也称子程序,一个程序只有一个主程序,而函数可以有多个。除了保留字,各种名称均可为函数命名,可以有返回值。,例2-2:下面函数可以用来判断从主程序传递来的参数是否大于0。,char loge (char i) if (i0)return 1;elsereturn 0; ,单片机原理与应用,在括号中的char i ,说明调用函数时需要传送一个参数,数据类型为字符型的。程序最前面的char 说明函数结束时,要返回一个参数,数据类型也是字符型的。,单片机原理与应用,3.头文件 头文件是以x.h文件名存储的,主要是用来定义各硬件的I/O地址、常数,也可以是函数的
4、声明,主程序使用include指令将它加载。对于单片机的编程来说,头文件的定义是非常重要的。,单片机原理与应用,例2-3:下面的程序 是根据P0口的工作 状态决定P1口输出 高电平还是低电平。,#include #include main( ) if (P00)P1=0x00;elseP1=0xff; ,顺序结构,单片机原理与应用,顺序结构是一种简单的编程结构。在这种结构中,程序由低地址向高地址顺序执行指令。如图 2-2 所示,程序先执行 指令1操作,再执行指令2 操作,两者是顺序执行的关系。,main( ) char a,b,c;a=240;b=15c=a ,顺序结构流程图,单片机原理与应用
5、,例2-4:编写一个程序,将两个变量的数据相“与”后, 通过P1口输出。,选择结构流程图,单片机原理与应用,选择结构,单片机原理与应用,例2-5:如图2-4所示的电路,试写出一段程序,如果开关k闭合,P1口上的8个LED发光二极管全亮,如果开关k断开,P1口上的8个LED发光二极管全灭。,用开关控制8个LED发光二极管,main( ) char a;while(1) a=P3;a=a ,单片机原理与应用,选择语句 if,C 语言的一个基本判定语句(条件选择语句)是 if 语句。它的基本结构是: if (表达式)语句 ; 在这种结构中,如果括号中的表达式成立(为真),则程序执行花括号中的语句;否
6、则程序将跳过花括号中的语句部分,执行下面其他语句。,单片机原理与应用,C 语言提供了三种形式的 if 语句,形式一: if (表达式)语句 例:if(P3!=0)P1=0x20;,单片机原理与应用,形式二:,if (表达式) 语句1 ; else 语句 2 ; ,例:if(P3!=0)P1=0xff;elseP1=0x00;,单片机原理与应用,形式三,if (表达式 l ) 语句 1 ; else if (表达式 2 ) 语句 2 ; else if (表达式 3 ) 语句 3 ; else if (表达式 m )语句 n;else 语句 m ; ,单片机原理与应用,if 语句的嵌套的基本形式
7、,单片机原理与应用,单片机原理与应用,例2-7:下面的程序是比较a、b和d三个变量的大小,确定变量c的值。 可以用花括号将不对称的 if 括起来,以确定它们之间的相应关系。,main( ) char a=10,b=1,c,d=2;if (ab) if(ad) c=1;elsec=0;,单片机原理与应用,单片机原理与应用,例2-8:下面的程序是比较a、b和d三个变量的大小,确定变量c的值。如果 if 语句中花括号内只有一条语句,则花括号可以省略,main( ) char a=10,b=1,c,d=2;if (ab) if(ad) c=1;elsec=0; ,单片机原理与应用,如果花括号内语句不只
8、一句,则此时花括号不能省,必须使用花括号并将它们括起来。,if (ab)if(ad) c=1;elsec=0; ,单片机原理与应用,串行多分支结构及其流程图,单片机原理与应用,在串行多分支结构中,以单选择结构中的某一分支方向作为串行多分支方向继续进行选择结构的操作;一般来说,以条件为真作为串行方向。若条件为假,则执行另外的操作。最终程序在若干种选择之中选出一种操作来执行,并从一个共用的出口退出。,串行多分支结构流程图,单片机原理与应用,单片机原理与应用,例2-9: 如图2-6所示的电路,当开关k0闭合时,发光二极管LED0亮,开关k1闭合时,发光二极管LED1亮,以此类推,开关k7闭合时,发光
9、二极管LED7亮。其它情况下,8个发光二极管全灭。任一时刻只能有一个发光二极管亮。,图2-6 用8个开关控制8个发光二极管,单片机原理与应用,main ( ) while(1) if (P1= =0x01)P3=0x01;else if (P1= =0x02)P3=0x02;else if (P1= =0x04)P3=0x04;else if (P1= =0x08)P3=0x08;else if (P1= =0x10)P3=0x10;,else if (P1= =0x20)P3=0x20;else if (P1= =0x40)P3=0x40;else if (P1= =0x80)P3=0x80
10、;elseP3=0x00; ,单片机原理与应用,并行多分支结构及其流程图,单片机原理与应用,在实际应用中,常常会遇到多分支选择问题。由于一个 if 语句只有两个分支可供选择,因此必须用嵌套的 if 语句结构来处理。如果分支较多,则嵌套的 if 语句层数多,程序冗长,从而导致可读性降低。为此, C 语言提供了一个 switch 语句,用于直接处理并行多分支选择问题。,switch 语句的一般形式如下:,switch (表达式) case常量表达式1: 语句 1 ; break ;case 常量表达式2: 语句 2 ; break ;case 常量表达式 n : 语句 n ; breakdefau
11、lt : 语句 n + l ,单片机原理与应用,(1)当switch括号中表达式的值与某一 case后面常量表达式的值相等时,就执行它后面的语句,然后因遇到break而退出switch语句。当所有的case中的常量表达式的值都没有与表达式的值相匹配时,就执行default后面的语句。,单片机原理与应用,(2)每一个case的常量表达式必须是互不相同的,否则将出混乱局面(对表达式的同一 个值,有两种或两种以上的选择)。(3)各个case和default出现的次序,不影响程序执行的结果。例如可以先出现“case 常量表达式n:”,再出现“default:”,然后才是“case常量表达式1:”。,单
12、片机原理与应用,(4)如果在case语句后忘记加break语句,则程序在执行了本行case选择之后,不会按 规定退出switch语句,而是将执行后续的case语句。有经验的程序员可以在switch语句中预设一系列不含break的case语句,这样程序会把这些case语句加在一起执行。这对某些应用可能是很有效的,但对另一些情况则将引起麻烦,因此使用时必须谨慎小心。,单片机原理与应用,并行多分支结构流程图,单片机原理与应用,单片机原理与应用,例2-11:如图2-8所示的电路,当开关k0闭合时,发光二极管LED0亮,开关k1闭合时,发光二极管LED1亮,以此类推,开关k7闭合时,发光二极管LED7亮
13、。其它情况下,8个发光二极管全灭任一时刻只能有一个发光二极管亮。要求用switch - case 语句完成同样的操作。,单片机原理与应用,main ( ) unsigned char k; while(1) k=P1,case 0xef: P3=0x10;break; case 0xdf: P3=0x20;break; case 0xbf: P3=0x40;break; case 0x7f: P3=0x80;break; default : P3=0;break; ,单片机原理与应用,循环结构及其流程图,单片机原理与应用,所有的分支结构都使程序流程一直向前执行,而使用循环结有构则可使分支流程重
14、复地进行。循环结构又分成“当” (while )型循环结构和“直到, ( do while )型循环结构两种。,while 型循环结构及其流程图,单片机原理与应用,如图 2-9 所示,在( while )型循环结构中,当判断条件 P 成立(为真)时,反复执行操作 A ,直到 P 条件不成立(为假)时,才停止循环。,图 2-9 “while ”型循环结构流程图,单片机原理与应用,while 循环结构的最大特点在于,其循环条件测试处于循环体的开头。要想执行重复操作,首先必须进行循环条件测试,若条件不成立,则循环体内的重复操作一次也不能执行。,单片机原理与应用,例2-12:如图2-11所示的电路,当
15、开关k闭合时,P20为低电平,发光二极管LED0LED3亮,开关k断开时,P20为高电平,发光二极管LED4LED7亮。,图2-11用P20控制P1口的输出状态,单片机原理与应用,main ( ) while(1)while (P2 ,单片机原理与应用,“=”号与“= =”号的区别,单片机原理与应用,“=”是赋值运算符;而“= =”是测试相等运算符,只是对该符号两边的表达式进行测试和比较,而不进行赋值。,例2-13:编写一段程序从P1口输出数据0-255。,main( ) char a;while(1) for (a=0 ;a= =255 ; a+) P1=a;for (b=0 ;b50000
16、 ; b+); ,单片机原理与应用,注意:,1、在 while 循环体内若有多条语句,应使用花括号括起来,表示这是一个语句块。当循环体内只有一条语句时,可以不使用花括号,但此时使用花括号将使程序更加安全可靠;特别是在进行 while 循环的多重嵌套时,使用花括号来分隔循环体将提高程序的可读性和可靠性。 2、在 while 循环体中,应有使循环趋向于结束的语句,单片机原理与应用,main ( ) unsigned int a;a=50000;while(a0) a-; ,单片机原理与应用,例2-15 :试用“while ”型循环结构编写一段延时程序。,“直到”(do while)型循环结构,单片
17、机原理与应用,do while 的程序流程图,do while循环结构流程图,单片机原理与应用,在这种结构中,先执行操作A,再判断条件P。若P成立(为真),则再执行操作A,此时反复执行操作 A ,直到P为假为止。,说明,单片机原理与应用,在while 循环语句中,执行循环体之前要先检测循环结束的条件。如果条件不成立,则该循环不会被执行。do while 循环语句把 while 循环语句作了移位,即把循环条件测试的位置从起始处移至循环的结尾处。该语句大多用于执行至少一次以上循环的情况。,main ( ) int sum = 0, a=0;do sum+=a; a+; while(a=10);,单
18、片机原理与应用,例2-16:试用“dowhile ”型循环结构编写一段 程序,计算1+2+3+10。,单片机原理与应用,例2-17 :如图2-14所示的电路,试用“while ”型循环结构编写一段程序,当P30闭合时,P1口的8个发光二极管LED0LED7闪烁,当P30断开时,P1口的8个发光二极管LED0LED7全灭,图2-14用P30控制P1口的发光二极管闪烁,单片机原理与应用,main ( ) unsigned int a;for ( ; ; ) do P1=0xff;for(a=0;a50000;a+);x=P3; while(x ,单片机原理与应用,例2-18 :试用“dowhile
19、 ”型循环结构编写一段延时程序。,main ( ) unsigned int a;a=50000;do a-; while(a0) ,单片机原理与应用,“dowhile ”与“while ”语句的区别,在“dowhile ”型循环结构中,先执行一次循环体,再判断是否满足循环条件。而在“while ”型循环结构中,先判断是否满足循环条件,再执行一次循环体。,单片机原理与应用,for型循环结构,单片机原理与应用,for 循环语句是循环语句中最为灵活也是最为复杂的一种。它不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定但已经给出循环条件的情况。除了被重复的循环指令体外,表达式模块由三个
20、部分组成。,单片机原理与应用,第一部分是初始化表达式。 第二部分是对结束循环进行侧试。 第三部分是尺度增量。,for 循环语句的一般形式,for (表达式 1 ;表达式 2 ;表达式 3 ) 语句; *循环体* /,main( ) int a,sum;sum=0;for (a=0; a=10; a+)sum+=a; ,单片机原理与应用,例2-19 :试用“for”型循环结构编写一段程序, 计算1+2+3+10。,单片机原理与应用,例2-20:电路如图2-14所示,试用“for”型循环结构编写一段程序,从P1口输出数据,依次点亮LED0LED7,程序运行时只有一个发光二极管亮。,图2-14 从P
21、1口输出数据,单片机原理与应用,main( ) unsigned int achar b,c;for(; ;)c=0x80;for (b=0;b1;,for (;) /*循环体*/,单片机原理与应用, for 语句中的小括号内的三个表达式全部为空。,在小括号内只有两个分号,无表达式。这意味着没有设初值,无判断条件,循环变量为增值。这将导致一个无限循环。一般在编制 8051 单片机监控程序需要无限循环时,就采用这种形式的 for 循环语句。,单片机原理与应用, for 语句三个表达式中,有一个或两个缺省。 例2-22:由于变量a的值在循环体外已经确定,要求 a在现有值的基础上进行累加,在循环体内
22、可以省略变量的初值。 (表达式 1 缺省),main( ) char a=0, sum=0;for (; a=100; a+)sum=sum+a; ,单片机原理与应用,例2-23:有时程序是否退出循环不取决于变量a,而要看b的值是否大于0,这时就应省去终值条件,下面的程序就能完成这一功能。(表达式 2 缺省),main( ) char a,b,sum=0;b=1000;for (a=1; ; a+), b-;if (b0)sum=sum+aelse break; ,程序分析:,a=1; while(1) sum=sum+a;a+;,单片机原理与应用,在for (a=1; ; a+)语句中省去了
23、表达式 2,即不判断循环条件,认为表达式始终为真。循环将无休止地进行下去。它相当于:,表达式 1 , 3 省略。,单片机原理与应用,例2-24:前面的例子已经讲过如果变量的初值在进入循环体之前已经存在,可以省略表达式1。有时程序的循环体中已经有了变量的增值语句,也可以省略表达式3,这时只要有表达式2就可以了。下面的程序就能完成这一功能。,main( ) char a=0,sum=0;for (; a=100 ; ) sum=sum+a;a+; ,单片机原理与应用,程序分析:,while (a100) sum=sum+a;a+; ,单片机原理与应用,在for (;a=100 ;)语句中不但省去了
24、表达式1,还省略了表达式3,即只判断循环条件,只要表达式2的条件满足。就退出循环体。它相当于:, 没有循环体的 for 语句。,例2-25:有些延时程序,并不需要在循环体内做任何事情,只是为了消耗计算机的时间,这时就可以省略循环体。下面的程序就能完成这一功能,main( ) int m=2000; for (t=0;tm;t+); ,单片机原理与应用,单片机原理与应用,循环的基本用途之一是用嵌套循环产生时间延迟,执行指令消磨时间。这种延时方式是依靠一定数量的时钟周期来定时的,所以延时依赖于晶振的振荡频率。,单片机原理与应用,构成循环结构的常见语句主要有: while , do while 和 for 等。可以证明,由以上基本结构组成的程序,能够处理任何复杂的问题。换句话说,任何复杂的程序都是由以上三种基本结构组成的。,