单片机原理与接口技术第 2章 C程序的设计
C 语言是一种结构化语言 。 所谓结构化语言就是不允许交叉程序的存在 。 结构化语言的基本元素是模块,在 C语言中也称为函数 。 它是程序的一部分,只有一个出口和一个入口,不允许中途插入,
也不允许以模块的其它路径退出 。 结构化编程语言在没有恢复堆栈和其它相关的寄存器之前,不应随便跳入或跳出一个模块 。
第 2章 C程序的设计
2.1 C语言程序的基本结构
2.1.1 C语言的程序结构
C语言程序的基本结构可以分成三部分,
即:主程序、函数和头文件。
第 2章 C程序的设计
1.主程序
C语言的主程序是 C语言开始执行的程序,
是不可缺少的部分,它是用 main为函数命名的。
第 2章 C程序的设计例 2-1:
如图 2-1所示的电路,试写出一段程序,
运行后,使 P1口上连接的 8个 LED发光二极管全亮。如图 2-1所示的电路,试写出一段程序,运行后,使 P1口上连接的
8个 LED发光二极管全亮。
第 2章 C程序的设计应用程序:
main()
{ char a;
a=0;
P1=a;
}
第 2章 C程序的设计程序分析:
在主程序中,首先定义一个字符型变量
char a,再给变量 a赋值为 0,最后从 P1口输出变量 a的值 0,P1口为低电平,LED上有电流通过,所以 8个 LED发光二极管都亮。
第 2章 C程序的设计将变量的数值从 P1口输出第 2章 C程序的设计函数函数也称子程序,一个程序只有一个主程序,而函数可以有多个。除了保留字,各种名称均可为函数命名,可以有返回值。
第 2章 C程序的设计例 2-2:
下面函数可以用来判断从主程序传递来的参数是否大于 0。
第 2章 C程序的设计
char loge (char i)
{if (i>0)
return 1;
else
return 0;
}
第 2章 C程序的设计程序分析:
在括号中的 char i,说明调用函数时需要传送一个参数,数据类型为字符型的。程序最前面的 char 说明函数结束时,要返回一个参数,数据类型也是字符型的。
第 2章 C程序的设计头文件头文件是以 x.h文件名存储的,主要是用来定义各硬件的 I/O地址、常数,也可以是函数的声明,主程序使用 include
指令将它加载。对于单片机的编程来说,
头文件的定义是非常重要的。
第 2章 C程序的设计例 2-3:
下面的程序是根据 P0口的工作状态决定
P1口输出高电平还是低电平。
第 2章 C程序的设计
#include <stdio.h>
#include <yu.h>
main( )
{ if (P0>0)
P1=0x00;
else
P1=0xff;
}
第 2章 C程序的设计
2.1.2 顺序结构顺序结构是一种简单的编程结构。
在这种结构中,程序由低地址向高地址顺序执行指令。如图 2-2 所示,程序先执行 指令 1操作,再执行指令 2 操作,两者是顺序执行的关系。
第 2章 C程序的设计顺序结构流程图第 2章 C程序的设计例 2-4:
编写一个程序,将两个变量的数据相
“与”后,通过 P1口输出。
第 2章 C程序的设计
main( )
{ char a,b,c;
a=240;
b=15
c=a&b;
P1=c;
}
第 2章 C程序的设计程序分析:
程序中定义了三个变量,a,b和 c,
再 a赋值为 240,是二进制的 11110000B,
给 b赋值为 15,是二进制的 00001111B,
执行语句 c=a&b;两数相“与”后,
c=00000000B,通过 P1口输出 P1=0x00。
第 2章 C程序的设计
2.2选择结构计算机的基本特性之一是具有重复执行一系列指令的能力;而计算机的另一个基本特性是具有选择能力。可以想象,
如果计算机不具备这种选择能力,它在执行各种条件语句时,就不能按照人们的意志,完成人们交给计算机的任务。
图 2 -3 是选择结构流程图。
第 2章 C程序的设计选择结构流程图第 2章 C程序的设计例 2-5:
如图 2-4所示的电路,试写出一段程序,
如果开关 k闭合,P1口上的 8个 LED发光二极管全亮,如果开关 k断开,P1口上的 8个
LED发光二极管全灭。
第 2章 C程序的设计
main( )
{ char a;
while(1)
{ a=P3;
a=a&0x01;
if (a = = 00)
P1=0x00;
else
P1=0xff;
}
}
第 2章 C程序的设计用开关控制 8个 LED发光二极管第 2章 C程序的设计
2.2.1 选择语句 if
C 语言的一个基本判定语句(条件选择语句)是 if 语句。
它的基本结构是,if (表达式)
{语句 } ;
在这种结构中,如果括号中的表达式成立(为真),则程序执行花括号中的语句;否则程序将跳过花括号中的语句部分,
执行下面其他语句。
第 2章 C程序的设计
C 语言提供了三种形式的 if 语句形式一:
if (表达式)
{语句}
例,if( P3!=0) P1=0x20;
第 2章 C程序的设计形式二:
if (表达式)
{语句例 l ; }
else
{语句 2 ; }
例,if( P3!=0)
P1=0xff;
else
P1=0x00;
第 2章 C程序的设计形式三
if (表达式 l ) {语句 1 ; }
else if (表达式 2 ) {语句 2 ; }
else if (表达式 3 ) {语句 3 ; }
……
else if (表达式 m ) {语句 n ; }
else {语句 m ; }
第 2章 C程序的设计例 2-6:
如图 2-4所示的电路,下面的程序是根据 P3口的工作状态决定 P1口输出的数据。
第 2章 C程序的设计用开关控制 LED发光二极管 程序
main()
{if( P3= =0)
P1=0x00;
else if (P3= =0x01)
P1=0x01;
else if (P3= =0x02)
P1=0x02;
else if (P3= =0x04)
P1=0x04;
else
P1=0x00;
}
第 2章 C程序的设计用开关控制 8个 LED发光二极管第 2章 C程序的设计
if 语句的嵌套的基本形式第 2章 C程序的设计例 2-7:
下面的程序是比较 a,b和 d三个变量的大小,确定变量 c的值。
可以用花括号将不对称的 if 括起来,
以确定它们之间的相应关系。
第 2章 C程序的设计
main( )
{char a=10,b=1,c,d=2;
if (a>b)
{ if(a>d)
c=1;
else
c=0;
}
}
第 2章 C程序的设计例 2-8:
下面的程序是比较 a,b和 d三个变量的大小,确定变量 c的值。
如果 if 语句中花括号内只有一条语句,
则花括号可以省略第 2章 C程序的设计
main( )
{char a=10,b=1,c,d=2;
if (a>b)
{if(a>d)
c=1;
}
else
c=0;
}
第 2章 C程序的设计如果花括号内语句不只一句,则此时花括号不能省,必须使用花括号并将它们括起来。
if (a>b)
{if(a>d)
c=1;
else
c=0;
}
第 2章 C程序的设计
2,2,2串行多分支结构及其流程图在串行多分支结构中,以单选择结构中的某一分支方向作为串行多分支方向继续进行选择结构的操作;一般来说,以条件为真作为串行方向。若条件为假,则执行另外的操作。最终程序在若干种选择之中选出一种操作来执行,并从一个共用的出口退出。
第 2章 C程序的设计串行多分支结构流程图第 2章 C程序的设计例 2-9:
如图 2-6所示的电路,当开关 k0闭合时,
发光二极管 LED0亮,开关 k1闭合时,发光二极管 LED1亮,以此类推,开关 k7闭合时,
发光二极管 LED7亮。其它情况下,8个发光二极管全灭。任一时刻只能有一个发光二极管亮。
第 2章 C程序的设计用 8个开关控制 8个发光二极管第 2章 C程序的设计
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;
else
P3=0x00;
}
}
第 2章 C程序的设计
2,2,3 并行多分支结构及其流程图在实际应用中,常常会遇到多分支选择问题。例如以一个变量的值作为判断条件,将此变量的值域分成几段,每一段对应着一种选择或操作。这样当变量的值处在某一个段中时,程序就会在它所面临的几种选择中选择相应的操作。这显然是一个典型的并行多分支选择问题。
第 2章 C程序的设计虽然可以用前面已掌握的 if 语句来解决这个问题,但由于一个 if 语句只有两个分支可供选择,因此必须用嵌套的 if 语句结构来处理。如果分支较多,则嵌套的 if
语句层数多,程序冗长,从而导致可读性降低。为此,C 语言提供了一个 switch
语句,用于直接处理并行多分支选择问题。
第 2章 C程序的设计
switch 语句的一般形式如下:
{ switch (表达式)
Case常量表达式 1,{语句 l ; } break ;
Case 常量表达式 2:,{语句 2 ; } break ;
,
,
,
case 常量表达式 n,{语句 n ; } break
default,{语句 n + l }
}
第 2章 C程序的设计例 2-10:
下面的程序是根据 P0口的工作状态确定
P1口输出。
第 2章 C程序的设计
main()
{char k;
k=P0;
switch(k)
{ case 1,P1=0x01; break;
case 2,P1=0x02; break;
case 3,P1=0x03; break;
delfault,break;
}
}
第 2章 C程序的设计并行多分支结构流程图第 2章 C程序的设计例 2-11:
如图 2-8所示的电路,当开关 k0闭合时,
发光二极管 LED0亮,开关 k1闭合时,发光二极管 LED1亮,以此类推,开关 k7闭合时,
发光二极管 LED7亮。其它情况下,8个发光二极管全灭。任一时刻只能有一个发光二极管亮。要求用 switch - case 语句完成同样的操作。
第 2章 C程序的设计并行多分支结构流程图第 2章 C程序的设计
main ( )
{ unsigned char k;
while(1)
{ k=P1&0xff;
switch(k)
{case 0xfe,P3=0x01;
break;
case 0xfd,P3=0x02;
break;
case 0xfb,P3=0x04;
break;
case 0xf7,P3=0x08;
break;
case 0xef,P3=0x10;
break;
case 0xdf,P3=0x20;
break;
case 0xbf,P3=0x40;
break;
case 0x7f,P3=0x80;
break;
default,P0=0;
break;
}
}
}
第 2章 C程序的设计
2.3循环结构及其流程图所有的分支结构都使程序流程一直向前执行,而使用循环结有构则可使分支流程重复地进行。循环结构又分成“当”
(while )型循环结构和“直到,( do
while )型循环结构两种。
第 2章 C程序的设计
“当” ( while )型循环结构及其流程图如图 2-9 所示,在 ( while )型循环结构中,当判断条件 P 成立(为真)时,
反复执行操作 A,直到 P 条件不成立
(为假)时,才停止循环。
while 循环语句的语法流程图如图 2-9 所示。
第 2章 C程序的设计
“while,型循环结构流程图第 2章 C程序的设计
do while 循环的语句第 2章 C程序的设计
while 循环结构的特点
while 循环结构的最大特点在于,其循环条件测试处于循环体的开头。要想执行重复操作,首先必须进行循环条件测试,
若条件不成立,则循环体内的重复操作一次也不能执行。
第 2章 C程序的设计例 2-12:
如图 2-11所示的电路,当开关 k闭合时,P20为低电平,发光二极管
LED0~LED3亮,开关 k断开时,P20为高电平,发光二极管 LED4~LED7亮。
第 2章 C程序的设计用 P20控制 P1口的输出状态第 2章 C程序的设计
main ( )
{while(1)
{while ((P2&0x01)= =0)
{ P1=0xf0; }
P1=0x0f;
}
}
第 2章 C程序的设计
“=”号与,= =”号的区别注意,=”号与,= =”号的区别。,=”
是赋值运算符;而,= =”是测试相等运算符,只是对该符号两边的表达式进行测试和比较,而不进行赋值。
第 2章 C程序的设计例 2-13:
编写一段程序从 P1口输出数据 0-255。
第 2章 C程序的设计
main()
{char a;
while(1)
{for (a=0 ;a= =255 ; a++)
{P1=a;
for (b=0 ;b<50000 ; b++);
}
}
}
第 2章 C程序的设计注意:
1、在 while 循环体内若有多条语句,应使用花括号{}括起来,表示这是一个语句块。
当循环体内只有一条语句时,可以不使用花括号,但此时使用花括号将使程序更加安全可靠;特别是在进行 while 循环的多重嵌套时,使用花括号来分隔循环体将提高程序的可读性和可靠性。
第 2章 C程序的设计注意:
2、在 while 循环体中,应有使循环趋向于结束的语句。在本例中,当 P1.4 =0
或 y > 5 时,while 循环体结束。若无此种语句,别循环将无休止地继续下去.
第 2章 C程序的设计例 2-15,
试用,while,型循环结构编写一段延时程序。
第 2章 C程序的设计
main ( )
{ unsigned int a;
a=50000;
while(a>0)
{ a--;
}
}
第 2章 C程序的设计
“直到”( do while)型循环结构第 2章 C程序的设计
( do while)型循环结构在这种结构中,先执行操作 A,再判断条件 P。若 P成立(为真),则再执行操作
A,此时反复执行操作 A,直到 P为假为止。
第 2章 C程序的设计
do while 的程序流程图第 2章 C程序的设计说明在 while 循环语句中,执行循环体之前要先检测循环结束的条件。如果条件不成立,则该循环不会被执行。
第 2章 C程序的设计说明
do while 循环语句把 while 循环语句作了移位,即把循环条件测试的位置从起始处移至循环的结尾处。该语句大多用于执行至少一次以上循环的情况。
第 2章 C程序的设计
do while 循环语句的执行过程首先执行循环体语句,然后执行圆括号中的表达式。如果表达式的结果为真( 1),
则循环继续,并再一次执行循环语句。只有当表达式的结果为假 ( 0 )时,循环才会终止,并以正常方式执行程序后面的语句。
第 2章 C程序的设计例 2-16:
试用,while,型循环结构编写一段程序,计算 1+2+3…+10 。
第 2章 C程序的设计
main ( )
{ int sum = 0,a=0;
do
{ sum+=a;
a++;
}
while(a<=10);
}
第 2章 C程序的设计例 2-17,
如图所示的电路,试用,while,型循环结构编写一段程序,当 P30闭合时,P1口的 8个发光二极管 LED0~LED7闪烁,当 P30
断开时,P1口的 8个发光二极管
LED0~LED7全灭。
第 2章 C程序的设计用 P30控制 P1口的发光二极管闪烁第 2章 C程序的设计
main ( )
{ unsigned int a;
for ( ; ; )
{ do
{ P1=0xff;
for (a=0;a<50000;a++);
x=P3;
}
while((x&0x01)= =0);
P1=0x00;
for (a=0;a<50000;a++);
}
}
第 2章 C程序的设计例 2-18,
试用,do…while,型循环结构编写一段延时程序。
第 2章 C程序的设计
main ( )
{ unsigned int a;
a=50000;
do
{ a--; }
while(a>0)
}
第 2章 C程序的设计
“do…while,与,while,语句的区别
“do…while,语句与,while,语句的区别是,在,do…while,型循环结构中,先执行一次循环体,再判断是否满足循环条件。而在,while,型循环结构中,先判断是否满足循环条件,再执行一次循环体。
第 2章 C程序的设计
2,3,3 (for)型循环结构及其流程图第 2章 C程序的设计
for 循环语句
for 循环语句是循环语句中最为灵活也是最为复杂的一种。它不仅可以用于循环次数已经确定的情况,而且可以用于循环次数不确定但已经给出循环条件的情况。
它既可以包含一个索引计数变量,也可以包含任何一种表达式。除了被重复的循环指令体外,表达式模块由三个部分组成。
第 2章 C程序的设计表达式模块由三个部分组成第一部分是初始化表达式。对 C 语言而言,任何表达式在开始执行时都应该做一次初始化。
第二部分是对结束循环进行侧试。对 C
语言而言,可以是任何一种测试,一旦测试为假,就会结束循环。
第三部分是尺度增量。
第 2章 C程序的设计
for 循环语句的一般形式
for 循环语句的一般形式为
for (表达式 1 ;表达式 2 ;表达式 3 )
{语句; } / *循环体 * /
第 2章 C程序的设计
for 循环的语句执行过程
① 先对表达式 1 赋初值,进行初始化。
② 判断表达式 2 是否满足给定的循环条件,
若满足循环条件,则执行循环体内语句,
然后执行第 ③ 步;若不满足循环条件,则结束循环,转到第 ⑤ 步。
③ 若表达式 2 为真,则在执行指定的循环语句后,求解表达式 3 。
④ 回到第 ② 步继续执行。
⑤ 退出 for 循环,执行下面一条语句。
第 2章 C程序的设计例 2-19,
试用,for”型循环结构编写一段程序,
计算 1+2+3…+10 。
第 2章 C程序的设计应用程序
main()
{ int a,sum;
sum=0;
for (a=0; a<=10; a++)
sum+=a;
}
第 2章 C程序的设计例 2-20:
电路如图 2-14所示,试用,for”型循环结构编写一段程序,从 P1口输出数据,
依次点亮 LED0~LED7,程序运行时只有一个发光二极管亮。
第 2章 C程序的设计图 2-14 从 P1口输出数据第 2章 C程序的设计对 for 循环语句的几种特例进行说明
① for 语句中的小括号内的三个表达式全部为空。
例 2-21:在实际运用中,有时需要单片机不间断地对现场进行监测与控制,试用
for 循环语句编写一段程序,得到一个无限的循环体。
第 2章 C程序的设计
for (;;)
{…/* 循环体 */}
程序分析:
在小括号内只有两个分号,无表达式。
这意味着没有设初值,无判断条件,循环变量为增值。这将导致一个无限循环。一般在编制 8051 单片机监控程序需要无限循环时,就采用这种形式的 for 循环语句.
第 2章 C程序的设计表达式 1 缺省
② for 语句三个表达式中,有一个或两个缺省。
表达式 1 缺省。
例 2-22:由于变量 a的值在循环体外已经确定,要求 a在现有值的基础上进行累加,
在循环体内可以省略变量的初值。
第 2章 C程序的设计应用程序
main( )
{ char a=0,sum=0;
for (; a<=100; a++)
sum=sum+a;
}
第 2章 C程序的设计程序分析:
在语句 for (; a<=100; a++)中未对 a设初值,这意味着在程序的其它地方已经有了 a
的初值。在此基础上继续累加,直到 a的值等于 100。
第 2章 C程序的设计表达式 2 缺省例 2-23:有时程序是否退出循环不取决于变量 a,而要看 b的值是否大于 0,这时就应省去终值条件,下面的程序就能完成这一功能。
第 2章 C程序的设计应用程序:
main()
{char a,b,sum=0;
b=1000;
for (a=1; ; a++)
{ b--;
if (b>0)
sum=sum+a
else
break;
}
第 2章 C程序的设计程序分析:
在 for (a=1; ; a++)语句中省去了表达式 2,即不判断循环条件,认为表达式始终为真。循环将无休止地进行下去。它相当于:
第 2章 C程序的设计
a=1;
while(1)
{ sum=sum+a;
a++;
}
第 2章 C程序的设计表达式 1,3 省略。
例 2-24:前面的例子已经讲过如果变量的初值在进入循环体之前已经存在,可以省略表达式 1。有时程序的循环体中已经有了变量的增值语句,也可以省略表达式 3,
这时只要有表达式 2就可以了。下面的程序就能完成这一功能。
第 2章 C程序的设计
main()
{char a=0,sum=0;
for (; a<=100 ; )
{ sum=sum+a;
a++;
}
}
第 2章 C程序的设计程序分析:
在 for (;a<=100 ;)语句中不但省去了表达式 1,还省略了表达式 3,即只判断循环条件,只要表达式 2的条件满足。就退出循环体。它相当于:
第 2章 C程序的设计
while (a<100)
{ sum=sum+a;
a++;
}
第 2章 C程序的设计
③ 没有循环体的 for 语句。
例 2-25:有些延时程序,并不需要在循环体内做任何事情,只是为了消耗计算机的时间,这时就可以省略循环体。下面的程序就能完成这一功能。
第 2章 C程序的设计应用程序
main( )
{ int m=2000;
for (t=0;t<m;t++);
}
第 2章 C程序的设计循环语句的用途循环的基本用途之一是用嵌套循环产生时间延迟,执行指令消磨时间。这种延时方式是依靠一定数量的时钟周期来定时的,所以延时依赖于晶振的振荡频率。
第 2章 C程序的设计时钟周期数
8051单片机的数据手册中列出了每一条机器指令所需要的时钟周期数,使用 12MHz的晶振,12个振荡周期的指令花费 1μs,而 24个振荡周期指令花费 2μs。
第 2章 C程序的设计分支指令所用的时间所有 3字节指令每条指令用 2μs,所有分支指令每条指令用 2μs;所有 1~2 字节逻辑和算术指令,每条指令用 1μs,而寄存器到寄存器传送用 2μs 。
第 2章 C程序的设计使用中断有些指令要花费 4μs。当需要执行其他操作时,用软件编程的方法来获得延时的效率是很低的。软件延时使控制器在延时循环时接收不到其它的输入,解决这个问题的方法是使用中断。
第 2章 C程序的设计例 2-26:
下面是延时 1ms的程序。如给这个程序传递一个 50的数值,则可以产生约 50000μs即 50ms的延时。
第 2章 C程序的设计延时函数
void msec( unsigned int x)
{unsigned char j;
while(x--)
{ for (j=0; j<125;j++)
{;}
}
}
第 2章 C程序的设计主程序
main( )
{
msec(50)
}
第 2章 C程序的设计程序分析:
这个程序可以用整型值产生较长的延时。根据汇编代码进行的分析表明,用 j
进行的内部循环大约延时 8μs,程序编写得近似正确,但并不精确。不同的编译器会产生不同的延时,因此 j 的上限值 125
应根据实验进行补偿调整。
第 2章 C程序的设计构成循环结构的常见语句构成循环结构的常见语句主要有,while,
do while 和 for 等。
可以证明,由以上基本结构组成的程序,能够处理任何复杂的问题。换句话说,任何复杂的程序都是由以上三种基本结构组成的。
第 2章结束