




已阅读5页,还剩155页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
2019年12月5日10时29分,1,6.1概述6.251单片机C语言编写的一般方法6.3C51数据类型及在MCS-51中的存储方式6.4C51语言的程序结构6.5C语言在MCS-51单片机中的典型运用,第6章C语言编程与应用,2019年12月5日10时29分,2,6.1概述,传统开发单片机系统主要用汇编语言编写系统程序。汇编语言的缺点:可读性和结构较差,可移植性也不好,跨硬件平台移植几乎不可能。采用汇编语言编写单片机应用程序的周期长,测试和排错比较困难,产品开发周期变长。为了提高编写系统和应用程序的效率,改善程序的可读性和可移植性,缩短产品开发周期,采用高级语言的开发平台来开发单片机系统已经成为时尚和趋势。基于高级语言开发平台进行单片机开发,具有开发速度快、语言简洁易读、可移植性好、可进行结构化程序设计和多人协同工作、可进行脱离硬件平台的软件仿真等优点。实践证明,采用高级语言开发单片机系统的效率要比用汇编语言的高几倍甚至几十倍。,2019年12月5日10时29分,3,单片机的高级语言包括:Basic语言、PL/M语言和C/C+语言。Basic语言主要应用在MCS-51系列单片机上,效果不是很理想,现在已经不再使用。PL/M语言对硬件的控制能力和代码效率都很好,但局限于Intel公司的单片机系列,移植性差。C/C+语言是目前单片机的主流编程语言。,2019年12月5日10时29分,4,单片机C语言编译器不仅把开发者的C语言编译成8051可以识别的机器码,更主要的是能够自动安排程序存储器的空间,分配8051内部RAM与外部RAM的空间、自动安排堆栈位置。这些事情都是汇编语言开发者必须自己作的。C51编译器还可以把不同函数的数据实行覆盖有效利用片上有限的RAM空间。一般情况下只懂C语言不懂得单片机的指令集的开发者也能够用C51编写完美的单片机程序。所以开发者学习单片机而不懂C语言将在激烈的市场竞争中处于十分不利的地位。,2019年12月5日10时29分,5,1单片机应用系统开发的软硬件环境构成,补充:单片机应用系统开发的软硬件环境,当用户目标系统设计完成后,还需要应用软件支持,用户目标系统才能成为一个满足用户要求的单片机应用系统。但该用户目标系统不具备自开发能力,需要借助于单片机仿真器(也称单片机开发系统)完成该项工作。,2019年12月5日10时29分,6,一个典型的单片机系统开发环境组成如图所示。,单片机系统开发环境组成,2019年12月5日10时29分,7,2单片机应用系统开发工具选择原则,全地址空间的仿真。不占用任何用户目标系统的资源。必须实现硬断点,并且具有灵活的断点管理功能。硬件实现单步执行功能。可跟踪用户程序执行。可观察用户程序执行过程中的变量和表达式。可中止用户程序的运行或用户程序复位。系统硬件电路的诊断与检查。支持汇编和高级语言源程序级调试。,2019年12月5日10时29分,8,3使用JTAG界面单片机仿真开发环境,JTAG仿真开发环境如图所示。在JTAG单片机仿真开发环境中,JTAG适配器提供了计算机通信口到单片机JTAG口的透明转换,并且不出借CPU和程序存储器给应用系统,使得仿真更加贴近实际目标系统。单片机内部已集成了基于JTAG协议调试和下载程序。,2019年12月5日10时29分,9,在线编程目前有两种实现方法:在系统编程(ISP)和在应用编程(IAP)。ISP一般通过单片机专用的串行编程接口对单片机内部的Flash存储器进行编程,而IAP技术是从结构上将Flash存储器映射为两个存储体,当运行一个存储体上的用户程序时,可对另一个存储体重新编程,之后将控制从一个存储体转向另一个。ISP的实现一般需要很少的外部电路辅助实现,而IAP的实现更加灵活,通常可利用单片机的串行口接到计算机的RS232口,通过专门设计的固件程序对内部的FLASH存储器编程。,4单片机的在线编程,2019年12月5日10时29分,10,6.251单片机C语言编写的一般方法,KeelC51软件是目前最流行开发8051系列单片机的软件工具,这从近年来各单片机仿真机厂商纷纷宣布全面支持KeilC51即可看出。KeilC51提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(Vision3IDEIntegrationDevelopEntironment)将这些部份组合在一起。掌握这一软件的使用对于使用8051系列单片机的爱好者来说是十分必要的,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令开发者事半功倍。,用C语言编写程序,离不开KeilC51软件!,2019年12月5日10时29分,11,Vision3IDE主要特性:,Vision3IDE基于Windows的开发平台,包含一个高效的编辑器、一个项目管理器和一个MAKE工具。Vision3IDE支持所有的KeilC51工具,包括C编译器、宏汇编器、连接/定位器、目标代码到HEX的转换器。,Vision3IDE内嵌多种符合当前工业标准的开发工具,可以完成从工程建立、管理、编译连接、目标代码的生成、软件仿真、硬件仿真等完整的开发流程。,2019年12月5日10时29分,12,集成开发环境,C51编译器和A51汇编器,LIB51库管理器,BL51链接器/定位器,Vision3软件调试器,Vision3IDE硬件调试器,RTX51实时操作系统,Vision3IDE主要特性如下:,2019年12月5日10时29分,13,6.2.1建立您的第一个KEILC51项目,安装完keil软件后,用户可以双击桌面“Vision3”运行图标进入IDE环境。,1.建立工程文件,在项目开发中,并不是只有一个用C或汇编语言编写的源程序就行了的,还要为项目选择所用的CPU,Keil支持数百种CPU,而这些CPU的特性并不完全相同;还要确定编译、汇编、连接的参数,指定调试的方式,有一些项目还会有多个文件组成等。为了管理和使用方便,Keil使用工程(Project)这一概念,将上述参数设置和所需的所有文件都加在一个工程中,只能对工程而不能对单一的源程序进行编译(汇编)和连接等操作。,2019年12月5日10时29分,14,(1)点击“ProjectNewProject.”菜单,出现一个对话框,选择工程要保存的路径,输入工程文件名。为了方便管理,通常我们将一个工程放在一个独立文件夹下,如保存到exam_1文件夹,工程文件的名字为exam_1,如下图所示,然后单击保存按钮。工程建立后,此工程名变为exam_l.uv2。,2019年12月5日10时29分,15,(2)点击“保存”按钮后,出现下图所示对话框,这个对话框要求选择目标CPU(即所用芯片的型号),Keil支持的CPU很多,Keil软件的关键是程序代码的编写,而非用户选择什么硬件,我们选择Atmel公司的89C52芯片。,2019年12月5日10时29分,16,点击ATMEL前面的“+”号,展开该层,点击其中的89C52。出现的界面上页图所示,右边【Description】栏里是对该型号单片机的基本说明,我们可以单击其他型号单片机浏览一下其功能特点,然后再点击“确定”按钮,弹出将8051初始化代码复制到项目中的询问窗口,如下图所示。,2019年12月5日10时29分,17,(3)单击“否”按钮,出现下图所示的窗口。如果需要重命名Target1和SourceGroup1,在左侧ProjectWorkspace区用鼠标左键选中Target1,再用鼠标左键单击Target1,即可重新命名Target1。用同样的方法可以修改SourceGroup1,这里对此不做修改。,2019年12月5日10时29分,18,到此为止,我们还未建立好一个完整的工程,虽然工程名有了,但工程当中还没有源文件及代码,接下来我们添加文件及代码。,2019年12月5日10时29分,19,(4)使用菜单“FileNew”或者点击工具栏的新建文件按钮,新建文件后窗口界面如图2-6所示。,2019年12月5日10时29分,20,此时光标在编辑窗口中闪烁,可以输入用户的应用程序,但此时这个新建文件与我们刚才建立的工程还没有直接的联系,单击保存,窗口界面如图2-7所示,在【文件名(N)】编辑框中,输入要保存的文件名,同时必须输入正确的扩展名。注意,如果用C语言编写程序,则扩展名必须为.c;如果用汇编语言编写程序,则扩展名必须为.asm。这里的文件名不一定要和工程名相同,用户可以随意填写文件名,然后单击【保存】按钮。,2019年12月5日10时29分,21,(5)回到编辑界面,单击【Target1】前面的“+”号,然后在【SourceGroup1】选项上,单击右键,弹出如下图所示的菜单。然后选择【AddFilestoGroupSourceGroup1】菜单项,对话框如图2-9所示。,2019年12月5日10时29分,22,选中文件后的对话框,2019年12月5日10时29分,23,图2-10将文件加入工程后的屏幕窗口,选中【exam_1.c】,单击【Add】按钮,再单击【Close】按钮,然后我们再单击左侧【SourseGroup1】前面的“+”号,屏幕窗口如图2-10所示,2019年12月5日10时29分,24,点亮一个二极管的控制系统硬件电路,2019年12月5日10时29分,25,(6)在编辑窗口中输入点亮一个发光二极管的C语言源程序:#include/52系列单片机头文件sbitled1=P10;/声明单片机P1口的第一位voidmain()led1=0;/*点亮LED发光二极管while(1);/程序停止到这里,2019年12月5日10时29分,26,程序输入完毕后保存,界面如下图。,2019年12月5日10时29分,27,程序输入完毕后保存,界面如下图。通过以上(1)(6)步我们学习了如何在Keil编译环境下建立一个工程。,2019年12月5日10时29分,28,2.工程的设置,见实验指导书中实验一,2019年12月5日10时29分,29,3.软件仿真调试,见实验指导书中实验一,2019年12月5日10时29分,30,编写并调试让二极管以间隔1s的时间亮灭闪烁的程序。,#include/52系列单片机头文件sbitled1=P10;/声明单片机P1口的第一位unsignedinti,j;/声明无符号整型变量i,jvoidmain()/主函数while(1)/大循环led1=0;/点亮LED发光二极管for(i=1000;i0;i-)/延时for(j=110;j0;j-);/led1=1;/关闭LED发光二极管for(i=1000;i0;i-)for(j=110;j0;j-);,2019年12月5日10时29分,31,再来看P1口控制流水灯的电路,2019年12月5日10时29分,32,如果我们要控制八个发光二极管先是二极管D1、D3、D5、D7亮,然后是二极管D2、D4、D6、D8亮,则程序为:#include/52系列单片机头文件unsignedinti,j;/声明无符号整型变量i,jvoidmain()/主函数while(1)/大循环P1=0 x55;/点亮LED发光二极管for(i=1000;i0;i-)/延时for(j=110;j0;j-);/P1=0 xAA;/关闭LED发光二极管for(i=1000;i0;i-)/延时for(j=110;j0;j-);,2019年12月5日10时29分,33,6.3.2C语言的标识符和关键字,1标识符标识符是用来标识源程序中某个对象的名字,这些对象可以是语句、数据类型、函数、变量、数组等等。例如:intcount;/count为整型变量的标识符charname20;/name为包含20个元素的数组的标识符C51的标识符可以由字母、数字(09)和下划线组成,最多可支持32个字符。其中标识符的第一个字符必须为字母或下划线,例如count2是正确的,而2count则是错误的。通常以下划线开头的标识符是编译系统专用的,因此在编写C语言源程序时一般不要使用以下划线开头的标识符。而且C语言是区分大小写的,name与NAME是两个不同的标识符。,2019年12月5日10时29分,34,6.3.2C语言的标识符和关键字,2关键字关键字是编程语言保留的特殊标识符,它们具有固定名称和含义,在程序编写中不允许标识符与关键字相同。如int、if、for等等。在KeilC51开发环境的文本编辑器中编写C程序,系统会把关键字以不同颜色显示。在C语言的程序编写中不允许标识符与关键字相同。与其他计算机语言相比,C语言的关键字较少,ANSIC标准共规定了32个关键字,,2019年12月5日10时29分,35,6.3.2C语言的标识符和关键字,表6-1ANSIC标准关键字,2019年12月5日10时29分,36,6.3.2C语言的标识符和关键字,续表6-1ANSIC标准关键字,2019年12月5日10时29分,37,表6-2KeilC51编译器扩展的关键字,2019年12月5日10时29分,38,6.3.3KeilC51中的基本数据类型,KeilC51编译器具体支持的数据类型有:位型(bit)、无符号字符(unsignedchar)、有符号字符(singedchar)无符号整型(unsignedint)、有符号整型(signedint)无符号长整型(unsignedlong)、有符号长整型(signedlong)浮点型(float)和指针类型等。,2019年12月5日10时29分,39,6.3.3KeilC51中的基本数据类型,2019年12月5日10时29分,40,1char字符类型char类型的长度是一个字节,通常用于定义处理字符数据的变量或常量。分无符号字符类型unsignedchar和有符号字符类型signedchar,默认值为signedchar类型。这很合适MCS-51单片机,因为MCS-51单片机每次可处理8位数据。unsignedchar类型用字节中所有的位来表示数值,所以可表达的数值范围是0255。signedchar类型用字节中最高位字节表示数据的符号,“0”表示正数,“1”表示负数,负数用补码表示。所能表示的数值范围是-128+127。2int整型int整型长度为两个字节,用于存放一个双字节数据。分有符号整型数signedint和无符号整型数unsignedint,默认值为signedint类型。,2019年12月5日10时29分,41,3long长整型long长整型长度为四个字节,用于存放一个四字节数据。4float浮点型浮点型变量(float):浮点型变量为32位,占4个字节,许多复杂的数学表达式都采用浮点变量数据类型。应用符号位表示数的符号,用阶码和尾数表示数的大小。5*指针型指针型本身就是一个变量,在这个变量中存放指向另一个数据的地址。这个指针变量要占据一定的内存单元,对不同的处理器长度也不尽相同,在C51中它的长度一般为13个字节。具体可参考相关C语言教程。,2019年12月5日10时29分,42,6bit位变量bit位变量是C51编译器的一种扩充数据类型,利用它可定义一个位变量,但不能定义位指针,也不能定义位数组。它的值是一个二进制位,不是0就是1。类似于一些高级语言中的Boolean类型中的True和False。7sfr特殊功能寄存器sfr也是一种扩充数据类型,占用一个内存单元,值域为0255。利用它可以访问51单片机内部的所有特殊功能寄存器。如用sfrP1=0 x90,这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1=255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。,2019年12月5日10时29分,43,8sfr1616位特殊功能寄存器sfr16占用两个内存单元,值域为065535。sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,可用于定时器T0和T1。9sbit可寻址位sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。例如:sfrP1=0 x90;sfrP1_1=P11;sfrP1_1=0 x91;,2019年12月5日10时29分,44,8sfr1616位特殊功能寄存器sfr16占用两个内存单元,值域为065535。sfr16和sfr一样用于操作特殊功能寄存器,所不同的是它用于操作占两个字节的寄存器,可用于定时器T0和T1。9sbit可寻址位sbit同位是C51中的一种扩充数据类型,利用它可以访问芯片内部的RAM中的可寻址位或特殊功能寄存器中的可寻址位。例如:sfrP1=0 x90;sfrP1_1=P11;sfrP1_1=0 x91;,2019年12月5日10时29分,45,在8051单片机系统中,经常要访问特殊功能寄存器中的某些位,用关键字sbit定义可位寻址特殊功能寄存器的位寻址对象。定义方法有如下三种:(1)sbit位变量名=位地址将位的绝对地址赋给位变量,位地址必须位于Ox80HxFFH之间。例如:sbitOV=0 xD2;sbitCY=0XD7;,2019年12月5日10时29分,46,(2)sbit位变量名=特殊功能寄存器名位位置当可寻址位位于特殊功能寄存器中时,可采用这种方法。位位置是一个07范围内的常数。例如:sfrSCON=0 x98;/*定义SCON*/sbitRI=SCON0;/*定义SCON的各位*/sbitTI=SCON1;sbitRB8=SCON2;shitTB8=SCON3;shitREN=SOON4;sbitSM2=SCON5;sbitSM1=SCON6;sbitSM0=SCON7;,2019年12月5日10时29分,47,(3)sbit位变量名=字节地址位位置这种方法是以一个常数(字节地址)作为基地址,该常数必须在0 x80H0 xFF范围内。位位置是一个07范围内的常数。例如:sbitOV=0 xD02;sbitCY=0 xD07;8051单片机中的特殊功能寄存器和特殊功能寄存器可寻址位,己被预先定义放在文件reg51.h或reg52.h中,在程序的开头只需加上#include或#include即可。另外,sbit还可以访问8051单片机片内20H2FH范围内的位对象。C51编译器提供了一个bdata存储器类型,允许将具有bdata类型的对象放入8051单片机片内可位寻址区。例如:,2019年12月5日10时29分,48,intbdatabi_var1;/*在位寻址区定义一个整型变量bi_var1*/charbdatabc_array3;/*在位寻址区定义字符型数组整型变量bc_array*/sbitbi_var1_bit0=bi_var10;/*使用位变量bi_var1_bit0访问bi_var1第0位*/sbitbi_var1_bit15=bi_var115;/*使用位变量bi_var1_bit15访问bi_var1第15位*/sbitbc_array05=bc_array05;/*使用位变量bc_array05访问bc_array0第5位*/,2019年12月5日10时29分,49,6.3.4变量的存储种类和存储器类型,变量是一种在程序执行过程中,其数值不断变化的量。同ANSIC一样,C51规定变量必须先定义后使用。C51对变量的进行定义的格式如下:存储种类数据类型存储器类型变量名表其中,存储种类和存储器类型是可选项。,2019年12月5日10时29分,50,存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:自动(auto)外部(extern)静态(static)寄存器(register),2019年12月5日10时29分,51,使用外部种类存储符extern定义的变量称为外部变量。在一个函数体内,要使用一个已在该函数体外或别的程序模块文件中定义过的外部变量时,该变量在本函数体内要用extern说明。,当片内RAM资源紧张时,不建议将外部变量放在片内RAM。,2019年12月5日10时29分,52,使用存储种类说明符static定义的变量称为静态变量。静态变量分为局部静态变量和全局静态变量。,局部静态变量是在两次函数调用之间仍能保持其值的局部变量。有些程序要求在多次调用之间仍然保持变量的值,使用自动变量无法作用到这一点。使用全局变量有时会带来意外的副作用,这时可采用局部静态变量。,2019年12月5日10时29分,53,使用存储种类说明符register定义的变量称为寄存器变量。8051访问寄存器的速度最快,通常将使用频率最高的那些变量定义为寄存器变量。C51编译器能自动识别程序中使用频率最高的变量,并自动将其作为寄存器变量,用户无需专门声明。,2019年12月5日10时29分,54,2.存储器类型,定义变量时,除了说明存储种类外,还允许说明变量的存储器类型。存储器类型和存储种类是完全不同的概念,存储器类型指明该变量所处的单片机的内存空间。C51编译器可识别以下存储器类型,如下表所示。,2019年12月5日10时29分,55,2019年12月5日10时29分,56,图6-14MCS-51单片机存储器结构示意图,2019年12月5日10时29分,57,如果在变量定义时省略了存储器类型标识符,C51编译器会选择默认的存储器类型。默认的存储器类型由SMALL、COMPACT和LARGE存储模式指令决定。,2019年12月5日10时29分,58,1)data区对data区的寻址是最快的,所以应该把使用频率高的变量放在data区,由于空间有限,必须注意使用data区,data区除了包含程序变量外,还包含了堆栈和寄存器组data区。,在SMALL存储模式下,未说明存储器类型时,变量默认被定位在data区。,2019年12月5日10时29分,59,2)bdata区当在DATA区的位寻址区定义变量,这个变量就可进行位寻址,并且声明位变量。这对状态寄存器来说十分有用,因为它可以单独使用变量的每一位,而不一定要用位变量名引用位变量。,3)idata区idata区也可以存放使用比较频繁的变量,使用寄存器作为指针进行寻址。在寄存器中设置8位地址进行间接寻址,与外部存储器寻址比较,它的指令执行周期和代码长度都比较短。,2019年12月5日10时29分,60,4)pdata和xdata区在这两个区声明变量和在其他区的语法是一样的,pdata区只有256B,而xdata区可达65536B,5)code区code区即8051的程序代码区,所以代码区的数据是不可改变的,8051的代码区不可重写。一般代码区中可存放数据表,跳转向量和状态表,2019年12月5日10时29分,61,C51编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式COMPACT、大编译模式LARGE。,6.3.5存储模式,2019年12月5日10时29分,62,一个变量的存储器模式确定了未声明存储器类型的变量在内存中的地址空间。在SMALL模式下,该变量在8051单片机的内部RAM中;在COMPACT和LARGE模式下,该变量在8051单片机的外部RAM中。,建议在编写源程序时,把存储模式设定为SMALL,再在程序中把xdata、pdata和idata等类型变量进行专门声明。,2019年12月5日10时29分,63,6.3.6MCS-51特殊功能寄存器(SFR)的C51定义,MCS-51单片机中,除了程序计数器PC和4组工作寄存器组外,其它所有的寄存器均为特殊功能寄存器(SFR),分散在片内RAM区的高128字节中,地址范围为80H0FFH。SFR中有11个寄存器具有位寻址能力。为了能直接访问这些SFR,KeilC51提供了一种自主形式的定义方法。特殊功能寄存器C51定义的一般语法格式如下:sfrsfr-name=intconstant;“sfr”是定义语句的关键字,其后必须跟一个MCS-51单片机真实存在的特殊功能寄存器名,“=”后面必须是一个整型常数,不允许带有运算符的表达式,是特殊功能寄存器“sfr-name”的字节地址,这个常数值的范围必须在SFR地址范围内,位于0 x800 xFF。例如:sfrSCON=0 x98;sfrTMOD=0 x89;,2019年12月5日10时29分,64,6.3.3KeilC51中的基本数据类型,KeilC51编译器具体支持的数据类型有:位型(bit)、无符号字符(unsignedchar)、有符号字符(singedchar)无符号整型(unsignedint)、有符号整型(signedint)无符号长整型(unsignedlong)、有符号长整型(signedlong)浮点型(float)和指针类型等。,2019年12月5日10时29分,65,6.3.4变量的存储种类和存储器类型,变量是一种在程序执行过程中,其数值不断变化的量。同ANSIC一样,C51规定变量必须先定义后使用。C51对变量的进行定义的格式如下:存储种类数据类型存储器类型变量名表其中,存储种类和存储器类型是可选项。,2019年12月5日10时29分,66,存储种类是指变量在程序执行过程中的作用范围。变量的存储种类有四种,分别为:自动(auto)外部(extern)静态(static)寄存器(register),2019年12月5日10时29分,67,2019年12月5日10时29分,68,C51编译器允许采用三种存储模式:小编译模式SMALL、紧凑编译模式COMPACT、大编译模式LARGE。,6.3.5存储模式,2019年12月5日10时29分,69,一个变量的存储器模式确定了未声明存储器类型的变量在内存中的地址空间。在SMALL模式下,该变量在8051单片机的内部RAM中;在COMPACT和LARGE模式下,该变量在8051单片机的外部RAM中。,建议在编写源程序时,把存储模式设定为SMALL,再在程序中把xdata、pdata和idata等类型变量进行专门声明。,2019年12月5日10时29分,70,6.3.6MCS-51特殊功能寄存器(SFR)的C51定义,MCS-51单片机中,除了程序计数器PC和4组工作寄存器组外,其它所有的寄存器均为特殊功能寄存器(SFR),分散在片内RAM区的高128字节中,地址范围为80H0FFH。SFR中有11个寄存器具有位寻址能力。为了能直接访问这些SFR,KeilC51提供了一种自主形式的定义方法。特殊功能寄存器C51定义的一般语法格式如下:sfrsfr-name=intconstant;“sfr”是定义语句的关键字,其后必须跟一个MCS-51单片机真实存在的特殊功能寄存器名,“=”后面必须是一个整型常数,不允许带有运算符的表达式,是特殊功能寄存器“sfr-name”的字节地址,这个常数值的范围必须在SFR地址范围内,位于0 x800 xFF。例如:sfrSCON=0 x98;sfrTMOD=0 x89;,2019年12月5日10时29分,71,6.4C51的运算符和表达式,C语言有丰富的运算符,绝大多数的操作都可以通过运算符来处理。运算符就是完成某种特定运算的符号,包括算术运算符、赋值运算符、逻辑运算符、关系运算符、位运算符、条件运算符等。按照表达式中运算对象的个数又可将运算符分为单目运算符、双目运算符和三目运算符。单目运算符只需要有一个运算对象,双目运算符要求有两个运算对象,三目运算符则要求有三个运算对象。表达式是由运算符和运算对象所组成的具有特定含义的式子。运算符和表达式可以组成C语言程序的各种语句。,2019年12月5日10时29分,72,6.4.1算术运算符,算术运算符包括以下几种:+加或取正值运算符-减或取负值运算符*乘运算符/除运算符%取余运算符+自增运算符-自减运算符,2019年12月5日10时29分,73,加、减、乘法运算符合一般的算术运算规则。除法运算则有些特殊,如果是两个浮点数相除,其结果为浮点数,如3.0/10.0所得值为0.3,而当两个整数相除时,所得值就是整数,如7/3,值为2,舍去小数部分。取余运算符也是进行除法运算,只是结果不是商而是余数。如8%5=3,即8除以5的余数是3。像别的语言一样C的运算符也有优先级和结合性,也可以用括号()来改变优先级。,6.4.1算术运算符,2019年12月5日10时29分,74,自增、自减运算符的作用是使变量的值加1或减1。+i先使i的值加1,然后再使用;-i先使i的值减1,然后再使用;i+使用完i的值以后,再使i的值加1;i-使用完i的值以后,再使i的值减1。,6.4.1算术运算符,2019年12月5日10时29分,75,例如:假设i=8,则执行j=+i时,i先加1变为9,然后把9赋给变量j,所以执行结果为i=9,j=9。而执行j=i+时,先将i的值8赋给j,然后再使i的值加1,执行结果为i=9,j=8。,6.4.1算术运算符,2019年12月5日10时29分,76,例:voidmain()inti=8;inta,b,c,d,e,f;a=+i;b=-i;c=i+;d=i-;e=-i+;f=-i;while(1);,6.4.1算术运算符,2019年12月5日10时29分,77,“=”就是赋值运算符,其功能是将一个数据赋给一个变量,如a=8;b=5;c=a/b;a=b=6;以上语句都是合法的。语句的执行过程是先计算出右边表达式的值,再将该值赋给左边的变量。,6.4.2赋值运算符,2019年12月5日10时29分,78,关系运算符的功能就是判断两个数的关系。C语言有以下六种关系运算符:大于小于大于等于小于等于测试等于!测试不等于关系运算符的优先级低于算术运算符,高于赋值运算符。六种关系运算符中前四种具有相同的优先级,后两种具有相同的优先级,而且前四种的优先级高于后两种。注意赋值运算符“=”和测试等于“=”关系运算符不一样。,6.4.3关系运算符,2019年12月5日10时29分,79,两个表达式用关系运算符连接起来就构成了关系表达式。关系表达式的值为逻辑值,即只有真(true)和假(false)两种状态,在C语言中用1表示真,用0表示假。若关系表达式的条件成立,则表达式的值为真(1),否则为假(0)。,6.4.3关系运算符,2019年12月5日10时29分,80,例观察关系运算符的用法和功能。voidmain()inta,b,c,d,e,f;a=(56);b=(3=10);d=(106),6.4.4逻辑运算符,2019年12月5日10时29分,84,6.4.5位运算符,位运算符的功能是对变量按位进行运算,但并不改变运算变量的值。C语言有以下六种位运算符:charx=0 xa6;i=0 x36;j=0 x98;a=i,2019年12月5日10时29分,88,6.4.6复合赋值运算符,复合赋值运算符是C语言的一种特色,它简化了代码的编写。该类运算符的功能是将某个变量先与表达式进行指定的运算,再将运算结果赋予该变量。C语言有以下十种复合赋值运算符:+=加并赋值运算符-=减并赋值运算符*=乘并赋值运算符/=除并赋值运算符%=取余并赋值运算符=右移并赋值运算符charx=0 xa6;i=0 x36,j=0 x98;a=0 x23,b=0 x34;a,2019年12月5日10时29分,90,6.4.7条件运算符,条件运算符是三目运算符,格式如下:判断结果=(判断式)?结果1:结果2其含义是先求判断式的值,若为真,则判断结果=结果1;若为假,则判断结果=结果2。,2019年12月5日10时29分,91,6.4.7条件运算符,例4-8观察条件运算符的用法和功能。voidmain()chara,b,max;a=10;b=16;max=ab?a:b;while(1);,执行结果::max=16。,2019年12月5日10时29分,92,6.4.8指针和地址运算符,在前面学习数据类型时,接触过指针类型数据,知道它是一种存放指向另一个数据的地址的变量类型。C语言中提供了两个专门用于指针和地址的运算符:*指针运算符(取内容)a=10;m=,2019年12月5日10时29分,94,作业:第六章1、2、3、4补充:P1口的P1.2和P1.3各接一开关S1、S2,.P1.4、P1.5、P1.6和P1.7各接一个发光二极管,如图所示。由开关S1和S2的不同状态,确定哪个发光二极管亮,真值表如下表所示:请编写程序实现上述功能。并用proteus仿真验证。,2019年12月5日10时29分,95,C语言源程序由若干个函数单元组成,每一个函数都是完成某个特殊任务的子程序段。一个C语言程序必须而且只能有一个名为main()的函数。它是一个特殊的函数,也称为该程序的主函数,程序的执行都是从main()函数开始的。C语言程序一般具有如下结构:预处理命令#include函数定义charfun1();floatfun2();主函数main()函数体功能函数1fun1()功能函数2fun2(),6.5C51语言的程序设计,2019年12月5日10时29分,96,6.5.151程序结构,C语言程序有顺序结构、选择结构、循环结构三种基本结构。,2019年12月5日10时29分,97,6.5.151程序结构,循环结构又分为“while”型循环结构和“do-while”型循环结构,相应的流程图如下图所示。,2019年12月5日10时29分,98,6.5.2C51语言的语句,C51语言的语句是单片机执行的操作命令,每条语句都以分号结尾,需要注意的是,变量、函数的声明部分也以分号结尾,但不是语句。C语言包括以下语句:1.表达式语句由一个表达式加上一个分号就构成了表达式语句。如:i=7;j=a=b;i+;,2019年12月5日10时29分,99,6.5.2C51语言的语句,2.复合语句用大括号“”将多条语句括起来就组成了复合语句,也称为功能块。复合语句中的每一条语句都必须以“;”结束,而不允许将“;”写在“”外。复合语句不需要以“;”结束。C语言中将复合语句视为一条单语句,也就是说在语法上等同于一条单语句。对于一个函数而言,函数体就是一个复合语句。如:i=7;j=a=b;i+;,2019年12月5日10时29分,100,6.5.2C51语言的语句,3.空语句空语句是仅由一个分号“;”组成的语句。空语句什么也做,语句格式:;,2019年12月5日10时29分,101,6.5.2C51语言的语句,4.函数调用语句函数调用的一般形式加上分号就构成了函数调用语句。语句格式:函数名(实际参数表);执行函数调用语句就是调用函数体并把实际参数赋予函数定义中的形式参数,然后执行被调函数体中的语句。,2019年12月5日10时29分,102,6.5.2C51语言的语句,5.控制语句控制语句用于控制程序的流程,以实现程序的各种结构方式。C51的控制语句有以下几类:(1)选择语句ifif语句是C语言的一种基本的选择控制语句,它有以下三种形式:,2019年12月5日10时29分,103,6.5.2C51语言的语句,if(表达式)语句序列;其它语句功能:如果表达式的值为真则执行语句,否则不执行语句。流程图如图所示。,if分支结构示意图,2019年12月5日10时29分,104,例仿真电路如下图所示,试编程实现:当开关K闭合时上面四个发光二极管先亮,下面四个二极管后亮,当开关K打开时仅下面四个发光二极管亮。,程序如下:#includesbitk=P34;voidmain()while(1)if(k=0)P1=0 xf0;P1=0 x0f;,2019年12月5日10时29分,105,例仿真电路如下图所示,试编程实现:当开关K闭合时上面四个发光二极管先亮,下面四个二极管后亮,当开关K打开时仅下面四个发光二极管亮。,#includesbitk=P34;voidmain()while(1)if(k=0)P1=0 xf0;P1=0 x0f;,2019年12月5日10时29分,106,if(表达式)语句序列1;else语句序列2;其它语句功能:如果表达式的值为真则执行语句序列1,否则执行语句序列2。,if-else分支结构示意图,2019年12月5日10时29分,107,例仿真电路如下图所示,试编程实现:当开关K闭合时8个发光二极管亮,K断开时8个发光二极管灭。,程序如下:#includesbitk=P34;voidmain()while(1)if(k=0)P1=0 x00;elseP1=0 xff;,2019年12月5日10时29分,108,if(表达式1)语句序列1;elseif(表达式2)语句序列2;elseif(表达式3)语句序列3;elseif(表达式n)语句序列n;else语句序列n+1;其它语句,if-elseif分支结构示意图,2019年12月5日10时29分,109,例4-12假设从键盘输入数据x,请编写一程序,判断x大于0,等于0,还是小于0;并输出其判断结果。,解:程序如下:#includevoidmain()charx,y;scanf(“%d”,2019年12月5日10时29分,110,(2).switch语句switch语句是多分支选择语句,也称开关语句。一般格式如下:switch(表达式)case常量表达式1:语句序列1;case常量表达式2:语句序列2;case常量表达式n:语句序列n;default:语句序列n+1;,2019年12月5日10时29分,111,每个case和default出现的顺序不影响执行结果,但每个常量表达式的值必须互不相同。该语句的执行过程如下:求switch后括号内的表达式的值,并将其值与各case后的常量表达式值进行比较;当表达式的值与某个常量表达式相等时,则执行该常量表达式后边的语句序列;接着执行下一个常量表达式后边的语句序列,直到后边所有的语句序列都执行完(即执行到语句序列n+1);如果表达式的值与所有case后的常量表达式都不相等,则执行default后面的语句序列。,2019年12月5日10时29分,112,但是我们通常只是需要当某个常量表达式的值与switch后表达式的值相等时就执行该case后的语句序列,并不希望程序一直执行下去,直到语句序列n+1。要达到这一目的,只需要在每个语句序列的后边加上“break”语句即可。格式如下:switch(表达式)case常量表达式1:语句序列1;break;case常量表达式2:语句序列2;break;case常量表达式n:语句序列n;break;default:语句序列n+1;,2019年12月5日10时29分,113,switch分支结构示意图,2019年12月5日10时29分,114,例仿真电路如下图所示,试编程实现:当只有K1闭合时,LED1亮,只有K2闭合时,LED2亮,依此类推。,#includevoidmain()unsignedchark;while(1)P1|=0 xf0;/P1做I/O口时为准双向口,/用作输入时应先写“1”k=P1;k=k,2019年12月5日10时29分,115,3.for语句for语句是一个很实用的计数循环语句。其格式如下:for(表达式1;表达式2;表达式3)语句序列;/循环体其中表达式1通常为赋值表达式,用来确定循环结构中控制循环次数的变量的初始值,实现循环控制变量的初始化。表达式2通常为关系表达式或逻辑表达式,用来判断循环是否继续进行。表达式3通常为表达式语句,用来描述循环控制变量的变化,最常见的是自增或自减表达式,实现对循环控制变量的修改。当循环条件满足时就执行循环体内的语句序列。语句序列可以是简单语句,也可以是复合语句。若只有一条语句,则可以省略。,20
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 博图SCL官方培训
- 软包电池外观培训
- 城市交通规划合同管理论文咨询重点基础知识点
- 产品组装技能培训课件
- 【培训课件】非处方药市场推广策略
- 配方出售保密协议书模板
- 《医疗设备监测的护理》课件
- 车辆无偿借用合同协议
- 公司培训计划书
- 连锁餐厅转让合同协议
- 成都青羊小升初5+4考试习题真题
- 在线网课学习知道《五人制足球技术(电子科大)》单元测试考核答案
- MOOC 人力资源管理-四川大学 中国大学慕课答案
- (正式版)JBT 14582-2024 分户减压阀
- 《水电工程岩爆风险评估技术规范》(NB-T 10143-2019)
- 中医养生与养生茶饮
- 知心慧学提分宝-数学
- 人教部编版四年级语文下册课外阅读练习题30篇(经典版)带答案解析
- 康复科护理的沟通技巧和有效的交流
- 吉祥航空飞行报告
- 银行网点安全评估报告
评论
0/150
提交评论