,第二级,第三级,第四级,第五级,项目,2,单片机的程序设计,2.1 C,语言的程序结构,2.2 C51,的运算符及表达式,2.3 C51,的数据,2.4 C,语言的函数,2.5 C,语言的数组,2.6,程序设计实例,单片机的开发实例,点亮一盏,LED,灯,问题描述:通过,C,语言编程,实现单片机开发板上点亮一盏,LED,灯。,实验所需软件:,Keil,、,Progisp,实验步骤:,1,、熟悉硬件电路,2,、掌握开发软件的使用方法,3,、编写程序代码并进行编译、运行,拓展:,1,、同时点亮几盏,LED,灯,2,、设计流水灯,程序代码,#include,main(),P1=0xF7;,请用,C,语言编写程序计算,234+78,的和,main( ),int,a, b, c;,a = 234;,b = 78;,c =,a+b,;,printf(“234+78=%d”, c);,1. C51,语言,C,语言编译调试工具效率高,数据类型及运算符丰富,经过不断完善,能满足单片机的开发要求,形成了单片机,C,语言。把,51,单片机,C,语言称为,C51,语言。,用,C51,编写单片机程序时,需要根据单片机存储结构及内部资源定义相应的数据类型和变量,而标准的,C,语言不需要考虑这些问题。另外,,C51,包含的数据类型、变量存储模式、输入输出处理、函数等方面与标准的,C,语言也有一定的区别。其他的语法规则、程序结构及程序设计方法则与标准的,C,语言相同。,C51,语言的特点,编程者不需要了解单片机的指令系统,仅要求对单片机的存储器结构有初步的了解,至于存储器的分配、寻址方式及数据类型等完全由编译器管理。,程序有规范化的结构,可以分为不同的函数,这种方式可以使程序结构化,将可变的选择与特殊操作组合在一起,增强程序的可读性。,编程和程序的调试时间显著缩短,从而提高了编程的效率,提供的库函数包含许多标准的子程序,具有较强的数据处理能力,可以将编好的程序很容易地移植到新程序。,C51,作为一种非常方便的语言得到了广泛的支持,目前已经成为单片机开发的主要编程语言。,2.,简单的,C51,程序,【,例,】,如下图所示,在,P1.0,口上接有一个,LED,发光二极管,要求让发光二极管发光。,#include ,sbit,P1_0=P10;,void main( ),P1_0=0;,程序如下:,程序的开始是一个文件包含处理。这段程序中包含的是,reg51.h,文件,以,.h,为后缀的称为头文件,该头文件的作用是把特殊功能寄存器中的符号和地址对应起来,这里主要是应用到,P1,这个符号,如果没有包含,reg51.h,文件,,C51,编译器不知道,P1,具体指什么,在编译过程中就会发生错误。,给,P1.0,取名为,P1_0,,是通过编译器中增加的关键字,sbit,来定义的,程序最后是主函数,每一个,C51,程序有且只有一个主函数,函数后面使用一对大括号“,”,,在“,”,中书写具体内容。,(1),一个,C51,程序从,main,函数开始执行,不管,main,函数在什么位置。,(2) C51,中字母区分大小写,如定义是,sbit,P1_0,,若后面写成,p1_0,,在编译时就会出现错误。,(3) C51,书写自由,一行可以写几个语句,一个语句也能写在几行上。,(4),每个语句必须以分号结束。,(5) C51,中的注释可以采用两种符号。第一种是“,/*/”,符号,从“,/*”,开始直到“*,/”,为止,中间的内容都是注释。第二种是“,/”,引导的注释语句,这种注释只对本行有效。,由此可见:,2.1 C,语言的程序结构,在结构上可以把,C51,程序分为,3,类,即顺序结构、选择结构和循环结构。,2.1.1,顺序结构,顺序结构是一种最基本、最简单的编程结构,在这种结构下,程序按低地址向高地址顺序逐条执行指令代码,如右图所示。,过程,A,过程,B,过程,C,请用,C,语言编写程序计算,234+78,的和,main( ),int,a, b, c;,a = 234;,b = 78;,c =,a+b,;,printf(“234+78=%d”, c);,2.1.2,选择结构,1,、,if,语句,(1)if(,表达式,),语句,如果表达式为“真”,则执行语句,否则执行,if,语句后面的语句,如:,if (a5),b=3;,(2)if(,表达式,),语句,1,else,语句,2,如果表达式为“真”,则执行语句,1,,否则执行语句,2,,如:,if (a10),b=1;,else if (a6),b=2;,else if (a2),b=3;,else,b=4;,(4) if,语句的嵌套,if(,表达式,1),if (,表达式,2),语句,1,else,语句,2,else,if (,表达式,3),语句,3,else,语句,4,使用,if,嵌套语句特别要注意,if,和,else,配对,,else,总是和最近的,if,配对,2,、,switch,语句,实际问题中,往往遇到以一个变量或表达式的值为判断条件,将此变量或表达式的值分成几段,每一段对应一种选择或操作,这种情况用,if,语句来嵌套非常麻烦,于是,,C51,提供了,switch,语句。,switch,语句的一般结构如下:,switch (,表达式,), case,常量表达式,1:,语句,1,break;,case,常量表达式,2:,语句,2,break;,case,常量表达式,n:,语句,n,break,;,default:,语句,n+1,,,break;,2.1.3,循环结构,构成循环结构的主要有,while,、,do-while,和,for,等语句。,1,、,while,循环语句,while,语句的一般表达形式为:,while (,表达式,),语句,当表达式的判断为“真”时,执行大括号内的语句,否则不执行。,2,、,do-while,循环语句,do-while,语句是先执行循环体,然后判断循环条件是,否成立,其一般形式为:,do,语句,while(,表达式,),;,分析程序:,P33,例,2.4,3,、,for,循环语句,for,语句的一般形式为:,for(,表达式,1,;表达式,2,;表达式,3),语句,for,循环语句的执行过程如下。,(1),先求解表达式,1,。,(2),求解表达式,2,,如果结果为“真”,即条件成立,则执行循环体语句;如果结果为“假”,转到第,(5),步。,(3),求解表达式,3,。,(4),转回第,(2),步。,(5),退出,for,循环语句,执行下面的语句。,表达式,3,表达式,2,真,假,表达式,1,循环体语句,【,例,】,流水灯的设计:在单片机的,P1.0-P1.7,上分别连接,8,个发光二极管,编程实现,8,个,LED,灯循环点亮。,程序如下:,#include ,#define,uchar,unsigned char,void delay( )/,延时子程序,uchar,i, j;,for( i=0; i110; i+);,for( j=0; j200;j+),void main( ),uchar,x, y;,while(1),y=0x01;,for(x,=0; x8; x+),P1=y;,delay( );,y0;delaytime-),for( i=0; i=124; i+);,void main( ), unsigned char light=0xfe;,unsigned char i;,while(1),if (P3_0)=0),light=0xfe;,P1=light;,for(i,=0;i=7;i+),Delay(1000);,if (P3_1)=0),break;,light=1;,P1=light;,P1=0xff;,2.2 C51,的运算符及表达式,C51,的运算符主要有:,算术运算符、关系运算符、逻辑运算符、位运算符、赋值及复合赋值运算符。,2.2.1.,赋值运算符和赋值表达式,(,1,)赋值运算符 “,=”,优先级较底,右结合性。,(,2,)赋值表达式,一般形式:变量名,=,表达式,赋值的类型转换规则:,在赋值运算中,当“,=”,两侧类型不一致时,系统自动将右边表达式 的值转换成左侧变量的类型,再赋值给该变量。,如:,x=1+9;,x=y=5;,2.2.2,算术运算符和算术表达式,(,1,) 基本的算术运算符,+ - * / %,(模运算或取余运算符),注:,1.,都是双目运算符,即需要两个操作数,2 .,对,/,,若两个整数相除,结果为整数(取整),3 .,对于,%,,要求,%,两侧的操作数均为整型数据,所得结果的符号与左侧操作数符号相同。,如,:,7/5=1,,,5/7=0 -93%23=-1 93%-23=1,(2),自增,自减运算符,+ +,自增,- -,自减,注:,1,、,+ +,和,- -,是单目运算符,2,、,+ +,和,- -,只能用于变量,不能用与常量和表达式。,3,、,+ +j,先自增,再使用,j+ +,先使用,后自增,如:,a=2 b=+a,后,b=3 a= 3,b=a+,后,b=2 a=3,2.2.3,关系运算符和关系表达式,(,1,)关系运算符及优先级,,,,,=,,,=,,,!=,前四个优先级相同,后两个优先级相同,前四个优先级高于后两个。,注:在优先级上,算术运算符,关系运算符,赋值运算符,(,2,)关系表达式,用关系运算符将两个表达式连接起来的表达式称为关系表达式,关系表达式的值为逻辑值,真和假,,1,代表真,,0,代表假。,ab,a=4 b=3,关系表达式为真 ,值为,1,2.2.4,逻辑运算符和逻辑表达式,(,1,)逻辑运算符及其优先级,&,逻辑与,|,逻辑或 !逻辑非,注意:,1,、,&,与,|,是双目运算符,,!是单目运算符,2,、在优先级上!, & |,(,2,)逻辑表达式,逻辑表达式值为逻辑量(真或假),执行规则:逻辑表达式是不完全执行的,只有当一定要执行下一个逻辑运算符才能确定表达式的值时,才执行该运算符。,如:,a&b&c,若,a=0,则表达式为,0,a | b | c,若,a=1,则表达式为,1,2.2.5,位运算符及其表达式,按位与,&,,按位或,|,,按位异或,按位取反,,左移,(,1,)按位与运算符,&,如:,char a=3 ,b =6,a&b,=2,00000011,00000110,00000010,作用:,1,)清零:让要清零的数与,0,按位与即可,2,)保留某些位,而将其余的位清零。,(,2,)按位或运算符,|,0|0=0 0|1=1 1|0=1 1|1=1,按位或的作用是将指定的位置置,1,(,3),异或运算符,00=0 11=0 01=1 10=1,作用:,1,)与,1,异或,使其定位翻转。任何数与,1,异或都会变成相反数。,2,)与,0,异或,使指定位保留原值。任何数与,0,异或都保持不变。,(,4,)位取反运算符,如:,unsigned char a=0x9a,b;,b=a; a,值不变,,b=0x65,(,5),位左移运算符,(,左移,1,位相当与乘,2),如:,unsigned char a=15 a=a1,00001111,a=a1,左移,1,位,a=30,a=a (,右移,1,位相当于除,2),int,a=15 : a=a2,后,a=3,注:,1,、左移运算中高位移出舍弃不用,低位补,0,2,、右移运算中低位移出舍弃不用,高位对,无符号数补,0,,对有符号数高位补符号位。,2.2.6,复合赋值运算符,赋值号前加上其他运算符构成复合赋值运算符,,c51,提供了下列十个复合赋值运算符,+=,,一,=,,*,=,,,/=,,,%=,,,&=,,,1=,,,=,,,=,,,=,a+=b a=(,a+b,),x*=,a+b,x=(x*(,a+b,),a&=b a=(,a&b,),a=4 a=(a4),单片机控制系统的设计与制作 试题,2,要求:用单片机实现抢答器的设计。当四个开关中的某一个开关按下时,数码管显示器上显示该开关对应的选手编号(,14,),且此时其他选手不能再抢答。当按下复位键后,重新开始抢答。请先设计硬件电路,再画出程序流程图,写出程序代码。,#include REGX52.H,const tab=0xf9,0xa4,0xb0,0x99; /,通过查表来显示对应数字,1,2,3,4,void,disp(int,n),P2_4=0; /,数码管控制位使能,P0 =,tabn,; /,查表来显示数字,main(),char answer = 1; /,抢答标志使能,P2_4=1; /,数码管控制位无显示,P2_0=1;,P2_1=1;,P2_2=1;,P2_3=1; /,按键定义为输入,while(1),while (answer) /,当抢答标志为,1,时执行,为,0,时表示抢答结束,,/,不执行下面抢答扫描,if (P2_0 = 0),disp(0); /,显示对应抢答号码,answer = 0; /,抢答标志取消,else if(P2_1 = 0),disp(1);,answer = 0;,else if(P2_2 = 0),disp(2);,answer = 0;,else if(P2_3 = 0),disp(3);,answer = 0;,单片机控制系统的设计与制作 试题,3,某企业承担用单片机实现双路防盗声光报警器的电气控制系统的设计与制作任务,其原理如下图,1,所示。设计要求:正常时,SW1,为断开状态,,SW2,为闭合状态。当小偷翻窗入室,会导致,SW1,闭合或,SW2,断开时,同时启动声光报警:直流蜂鸣器(,BUZZER,)通电发声,,LED1,与,LED2,交替闪亮,交替时间为,0.5,秒(时间精度不作严格要求),即,BUZ1,连续发出声音,同时,LED1,亮时,,LED2,灭,,LED1,灭时,,LED2,亮。,#include ,sbit,key1=P00;,sbit,key2=P01;,sbit,led1=P02;,sbit,led2=P03;,sbit,fengmingqi,=P04;,void delay (unsigned,int,a) /,unsigned,int,i;,while( -a ),for(i,= 0; i 600; i+);,main(),fengmingqi,=0;,while(1),if(key1=0 |key2=1),fengmingqi,=1;,led1=0;,led2=1;,delay(50);,led1=1;,led2=0;,delay(50);,if(key1=1 &key2=0),fengmingqi,=0;,led1=1;,led2=1;,C51,数据类型与标准,C,数据类型的最大不同之处:位型。,位型(,bit,),字符型(,char,),整型(,int,),长整型(,long,),浮点型(,float,),双精度浮点型(,double,),数组类型(,array,),结构体类型(,struct,),共用体(,union,),枚举(,enum,),基本类型,构造类型,指针类型,空类型,数据类型,2.3 C51,数据类型与运算,2.3.1,常量与变量,常量是指在程序执行过程中其值不能改变的量。在,C51,中支持整型常量、浮点型常量、字符型常量和字符串型常量。,变量是在程序运行过程中其值可以改变的量。一个变量由两部分组成:变量名和变量值。,变量必须先定义,后使用。,位类型,bit,:位类型是,C51,编译器的一种扩充数据类型。利用它可以定义一个位类型变量,其值是一个二进制位,只有,0,或,1,。,位类型符有两个:,bit,和,sbit,。可以定义两种位变量。,bit,位类型符用于定义一般的可位处理位变量。它的格式如下:,bit,位变量名;,在格式中可以加上各种修饰,但注意存储器类型只能是,bdata,、,data,、,idata,。只能是片内,RAM,的可位寻址区,严格来说只能是,bdata,。,【,例,】 bit,型变量的定义。,bit data a1,;,/*,正确*,/,bit,bdata,a2,;,/*,正确*,/,bit,pdata,a3,;,/*,错误*,/,bit,xdata,a4,;,/*,错误*,/,sbit,位类型符用于定义在可位寻址字节或特殊功能寄存器中的位,定义时须指明其位地址,可以是位直接地址,可以是可位寻址变量带位号,也可以是特殊功能寄存器名带位号。格式如下:,sbit,位变量名,=,位地址;,如位地址为位直接地址,其取值范围为,0x000xff,;如位地址是可位寻址变量带位号或特殊功能寄存器名带位号,则在它前面须对可位寻址变量或特殊功能寄存器进行定义。字节地址与位号之间、特殊功能寄存器与位号之间一般用“,”,作间隔。,【,例,】sbit,型变量的定义。,sbit,OV=0xd2,;,sbit,CY=oxd7,;,unsigned char,bdata,flag,;,sbit,flag0=flag0,;,sfr,P1=0x90,;,sbit,P1_0=P10,;,sbit,P1_1=P11,;,sbit,P1_2=P12,;,特殊功能寄存器变量,MCS-51,系列单片机片内有许多特殊功能寄存器,通过这些特殊功能寄存器可以控制,MCS-51,系列单片机的定时器、计数器、串口、,I/O,及其它功能部件,每一个特殊功能寄存器在片内,RAM,中都对应于一个字节单元或两个字节单元。,在,C51,中,允许用户对这些特殊功能寄存器进行访问,访问时须通过,sfr,或,sfr16,类型说明符进行定义,定义时须指明它们所对应的片内,RAM,单元的地址。格式如下:,sfr,或,sfr16,特殊功能寄存器名,=,地址;,sfr,用于对,MCS-51,单片机中单字节的特殊功能寄存器进行定义,,sfr16,用于对双字节特殊功能寄存器进行定义。特殊功能寄存器名一般用大写字母表示。地址一般用直接地址形式,具体特殊功能寄存器地址见前面内容。,【,例,】,特殊功能寄存器的定义。,sfr,PSW=0xD0,;,sfr,SCON=0x98,;,sfr,TMOD=0x89,;,sfr,P1=0x90,;,sfr16 DPTR=0x82,;,sfr16 T1=0x8A,;,2.3.2,存储种类,存储种类是指变量在程序执行过程中的作用范围。,C51,变量的存储种类有四种,分别是自动,(auto),、外部,(extern),、静态,(static),和寄存器,(register),。,1,auto,:,使用,auto,定义的变量称为自动变量,其作用范围在定义它的函数体或复合语句内部,当定义它的函数体或复合语句执行时,,C51,才为该变量分配内存空间,结束时占用的内存空间释放。自动变量一般分配在内存的堆栈空间中。定义变量时,如果省略存储种类,则该变量默认为自动,(auto),变量。,2,extern,:,使用,extern,定义的变量称为外部变量。在一个函数体内,要使用一个已在该函数体外或别的程序中定义过的外部变量时,该变量在该函数体内要用,extern,说明。外部变量被定义后分配固定的内存空间,在程序整个执行时间内都有效,直到程序结束才释放。,3,static,:,使用,static,定义的变量称为静态变量。它又分为内部静态变量和外部静态变量。在函数体内部定义的静态变量为内部静态变量,它在对应的函数体内有效,一直存在,但在函数体外不可见,这样不仅使变量在定义它的函数体外被保护,还可以实现当离开函数时值不被改变。外部静态变量是在函数外部定义的静态变量。它在程序中一直存在,但在定义的范围之外是不可见的。如在多文件或多模块处理中,外部静态变量只在文件内部或模块内部有效。,4,register,:,使用,register,定义的变量称为寄存器变量。它定义的变量存放在,CPU,内部的寄存器中,处理速度快,但数目少。,C51,编译器编译时能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户可以无需专门声明。,2.3.3,存储器类型,存储器类型是用于指明变量所处的单片机的存储器区域情况。存储器类型与存储种类完全不同。,C51,编译器能识别的存储器类型有以下几种,见表所示。,存储器类型,描,述,data,直接寻址的片内,RAM,低,128B,,访问速度快,bdata,片内,RAM,的可位寻址区(,20H2FH,),允许字节和位混合访问,idata,间接寻址访问的片内,RAM,,允许访问全部片内,RAM,pdata,用,Ri,间接访问的片外,RAM,的低,256B,xdata,用,DPTR,间接访问的片外,RAM,,允许访问全部,64k,片外,RAM,code,程序存储器,ROM64k,空间,简单交通灯的设计(,P41,),