单片机C程序设计及应用1.9.单片机C51程序设计1.10.KeilC511.11C51程序的设计实例1.9.单片机C51程序设计1.9.1单片机C程序的基本概念目前仍在使用的单片机开发设计语言大致有两类:汇编语言和C语言。C语言由于其结构化、移植性好和高效性的特点,是进行单片机开发的一种利器。C语言是一种源于编写UNIX操作系统的语言,与汇编语言相比,有以下优点:(1)不需要了解51单片机的指令系统,仅仅要求初步了解存储器结构。(2)程序有规范的结构,可分为不同的函数,使程序结构化。(3)程序可读性好。(4)提供很多标准库函数,数据处理能力强。(5)程序易于做到模块化,移植性好。1.9.2单片机C程序的基本结构C语言是一种通用性很强的结构化程序设计语言。从程序流程的角度来看,单片机C程序可以分为3种基本结构:顺序结构、选择结构和循环结构。这3种基本结构可以组成各种复杂程序。1.顺序结构顺序结构程序是仅包含一个main()函数的简单程序,适当运用表达式语句就能设计出具有某特定功能的顺序结构C51程序。这是一种最简单的基本结构,程序只由低地址向高地址顺序执行指令代码,如图10-1所示。虽然该程序设计方法简单,但在具体运用中的算法仍然采用自顶向下逐步求精的方法进行设计。图10-1顺序结构2.选择结构使单片机具有决策能力的是选择结构,这种结构也称为分支结构,如图10-2(a)所示。选择结构中包含一个判断框,执行流程根据判断条件P的成立与否,选择执行其中的一路分支。图10-2(b)所示的是特殊的选择结构,即一路为空的选择结构。这种选择结构中,当P条件成立时,执行A操作,然后脱离选择结构;如果P条件不成立,则直接脱离选择结构。它包括if语句结构和switch语句结构两种。图10-2选择结构1) if语句结构C语言的if语句有3种形式:基本if形式、if-else形式、if-else-if形式。基本if形式语法结构如下:if(表达式)处理程序;处理机理是:如果表达式的值为“真”,则执行“处理程序”的语句内容,否则不执行该语句内容。例如:voidmain(){ucharsp0=0,buffer0[2]={0,0};if(sp0==0)buffer0[sp0]=RXBUF0;//接收串口数据}if-else形式语法结构如下:if(表达式)处理程序1;else处理程序2;处理机理是:如果if表达式的值为“真”,则执行“处理程序1”的语句内容,否则执行“处理程序2”语句内容。例如:voidmain(){ucharend,rev_flag;if(end==1)rev_flag0=1;elserev_flag0=0;}if-else-if形式语法结构如下:if(表达式1)处理程序1;elseif(表达式2)处理程序2;…else(表达式n)处理程序n;处理机理是:如果表达式1的值为“真”,则执行与之相对应的“处理程序1”的语句内容;如果表达式2的值为“真”,则执行与之相对应的“处理程序2”的语句内容,依次判断表达式“x”是否为“真”,如果为“真”则执行与之相对应的“处理程序x”语句内容。例如:voidmain(){ucharsp0=0,rev_byte0,buffer0[2]={0,0},receive_frame[10];if(sp0==0){buffer0[sp0]=RXBUF0;//接收串口数据if(buffer0[0]==0xEB)sp0++;}/*判断第二个字节*/elseif(sp0==1){buffer0[sp0]=RXBUF0;if((buffer0[0]==0xEB)&&(buffer0[1]==0x90))sp0++;//数据为EB90elsesp0=0;}elseif(sp0=2){receive_frame[rev_byte0]=RXBUF0;rev_byte0++;}2) switch语句结构C语言的switch语句又称开关语句,它可以从多种情况中选择满足条件的一种情况,是多分支选择结构语句。switch形式语法结构如下:switch(表达式){case常量表达式1:[处理序列1;[break]]case常量表达式2:[处理序列2;[break]]…case常量表达式n:[处理序列n;[break]][default:处理序列n+1;]}处理机理是:计算表达式的值,并逐个与其后的常量表达式的值相比较,当表达式的值与某个常量表达式的值相等,即执行其后的处理序列语句,然后不再进行判断,继续执行后面所有case后的处理序列语句。如表达式的值与所有case后的常量表达式都不相同时,则执行default后的处理序列语句。C语言还提供了一种break语句,专用于跳出switch语句。例如:voidmain(){ucharflag=0,up=0,down=0,left=0,right=0;switch(flag){case1:up=1;break;//置标志case2:down=1;break;case3:left=1;break;case4:right=1;break;default:error=1;break;}}本例中输入一个整数,经switch判断后,选择输出是一周中的星期几,整数不在1~7的范围内时就输出“Error”。可见此类多分支程序用switch语句可以很容易实现。3.循环结构计算机的基本特征之一就是具有重复执行一组语句的能力——循环能力。循环结构是程序中一种很重要的结构。其特点是:在给定条件成立时,反复执行某程序段,直到条件不成立时为止。循环结构有两种形式:当型循环和直到型循环。1)当型循环判断条件P是否成立,若成立,则重复执行A操作,直至某次判断条件P不再成立,就不再执行A操作而退出循环结构,见图10-3(a)。2)直到型循环重复执行A操作,然后判断条件P是否成立,如果不成立再执行A操作,直到条件P成立,不再执行A操作,退出循环,见图10-3(b)。图10-3循环结构无论是顺序结构、选择结构,还是循环结构,它们有一个共同点,即只有一个入口且只有一个出口。从示意图中可以看到,如果把基本结构看做是一个整体(用虚线框表示),执行流程从a点进入基本结构,而从b点脱离基本结构。整个程序由若干个这样的基本结构组合而成,必然有良好的可读性和可维护性。它包括for语句结构和while语句结构两种。(1) for语句结构。C语言中,for语句是一种使用最为方便灵活的循环控制语句结构,它提供了一个应用非常灵活的控制部分,既可以实现计数循环程序设计,又可以实现条件控制循环程序设计。for形式语法结构如下:for(表达式1;表达式2;表达式3)处理程序;处理机理是:首先计算“表达式1”的值;再计算“表达式2”的值,若值为“真”则执行循环体一次,否则跳出循环;然后再计算“表达式3”的值,转回第2步重复执行。在整个for循环过程中,“表达式1”只计算一次,作为for的入口语句条件,“表达式2”和“表达式3”则可能计算多次。循环体也可能多次执行,也可能一次都不执行。例如:voidmain(){intn,sum=0;for(n=0;n=50;n++)sum+=n;}在使用for语句中有几点要特别注意:①循环体内的处理程序可以为空操作;②for语句的各表达式都可以省,而分号不能省,在省略各表达式时要特别小心分析,防止造成无限死循环。(2) while语句结构。while形式语法结构有当while形式和直到while形式两种。当while形式如下:while(表达式)处理程序;处理机理是:计算“表达式”的值,若为“真”则执行循环体的处理程序一次,然后再对表达式进行计算执行,直到表达式的值为“假”时停止循环。循环体也可能多次执行,也可能一次都不执行。例如:voidmain(){intn=0,sum=0;while(n50){n+=1;sum+=n;}}直到循环do-while形式如下:do处理程序;while(表达式);处理机理是:先执行处理程序,到while时计算“表达式”的值,若为“真”则再次执行循环体的处理程序一次,直到表达式的值为“假”时停止循环。循环体至少会执行一次。例如:voidmain(){intn=0,sum=0;do{n+=1;sum+=n;}while(n=50);}1.9.4单片机C程序的算术表达式C程序的运算符主要有7种类型。1.算术运算符和表达式算术运算符用于各类数值运算,包括加(+)、减(-)、乘(*)、除( / )、求余(或称模运算,%)、自增(++)、自减(--)共7种。用算术运算符和括号将运算对象连接起来的式子称为算术表达式,其中运算对象包括常量、变量、函数、数组、结构等。加法运算符“+”为双目运算符,即应有两个量参与加法运算,如a+b,4+8等。具有左结合性。减法运算符“-”为双目运算符。但减号“-”也可作负值运算符,此时为单目运算,如 -x,-5等,具有左结合性。乘法运算符“*”为双目运算符,具有左结合性。除法运算符“ / ”为双目运算符,具有左结合性。参与运算量均为整型时,结果也为整型,舍去小数。如果运算量中有一个是实型,则结果为双精度实型。求余运算符(模运算符)“%”为双目运算符,具有左结合性。要求参与运算的量均为整型。求余运算的结果等于两数相除后的余数。自增1运算符记为“++”,其功能是使变量的值自增1。自减1运算符记为“--”,其功能是使变量值自减1。自增1、自减1运算符均为单目运算,都具有右结合性。可有以下几种形式:++i:i自增1后再参与其他运算;--i:i自减1后再参与其他运算;i++:i参与运算后,i的值再自增1;i--:i参与运算后,i的值再自减1。在理解和使用上容易出错的是i++和i--,特别是当它们出现在较复杂的表达式或语句中时,常常难于弄清,因此应仔细分析。2.关系运算符和表达式关系运算符用于比较运算,包括大于()、小于()、大于等于(=)、小于等于(=)、等于(= =)和不等于(!=)6种。前4种优先级相同,后两种优先级相同,前4种的优先级又高于后两种。关系运算符的优先级低于算术运算符,但高于赋值运算符。例如:ca+b等效于c(a+b)ab!=c等效于(ab)!=c关系运算符的结合性为左结合。用关系运算符将两表达式(算术表达式、关系表达式、逻辑表达式等)连接起来的式子,称为关系表达式。关系表达式的结果为逻辑真或假。C语言以1代表真,0代表假。例如:若a=5,b=3,c=0,则:ab的值为真,表达式的值为1;d=ab,d的值为1;b+ca的值为假,表达式的值为0;e=abc,由于结合性为左结合,故ab的值为1,而1c的值为0,因此e的值为0。3.逻辑运算符和表达式C语言提供了3种逻辑运算符:与运算(&&),或运算(||),非运算(!)。与运算符“&&”和或运算符“||”均为双目运算符,具有左结合性。非运算符“!”为单目运算符,具有右结合性。非运算符“!”的优先级是这3种中最高的,比算术运算符、关系运算符、与运算符、或运算符及赋值运算符都高。与运算符“&&”和或运算符“||”只比赋值运算符的优先级高。例如:ab&&cd等价于(ab)&&(cd)!b==c||da等价于((!b)==c)||(da)a+bc&&x+yb等价于((a+b)c)&&((x+y)b)用逻辑运算符将关系表达式或逻辑量连接起来的式子称为逻辑表达式,逻辑表达式的结合性为自左向右,其值应该是一个逻辑的真或假。逻辑表达式的值和关系表达式的值相同,以1代表真,以0代表假。例如:若a=8,b=6,则:因为a=8为真,所以 !a为假(0);因为a、b均为真,所以a||b为真(1),a&&b为真(1);因为“!”的优先级高于“&&”,所以 !a&&b为假(0)。4.位操作运算符和表达式位操作运算符是用来进行二进制位运算的运算符,包括逻辑位运算符和移位运算符。逻辑位运算符是位与(&)、位或( | )、位取反(~)和位异或(^);移位运算符是位左移()和