版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1,内容概要,本章在读者已掌握标准C语言前提下,初步介绍如何使用C51来编写AT89C51单片机的应用程序。 C51是在标准C的基础上,根据单片机存储器硬件结构及内部资源,扩展了相应的数据类型和变量,而C51在语法规定、程序结构与设计方法上,都与标准C相同。 本章重点介绍C51对标准C所扩展的部分,并通过一些例程来介绍C51的程序设计思想。,2,单片机入门主要掌握以下知识和应用,最小系统能够运行起来的必要条件。 1.电源 2.晶振3.复位电路 对单片机任意IO口的随意操作 1.输出控制电平高低2.输入检测电平高低。 定时器:重点掌握最常用的方式2 中断:外部中断、定时器中断、串口中断 串口通信
2、:单片机之间、单片机与计算机间,3,目前51系列单片机编程的C语言都采用Keil C51(简称C51),Keil C51是在标准C语言基础上发展起来的。 C语言是美国国家标准协会(ANSI)制定的编程语言标准,1987年ANSI公布87 ANSI C,即标准C语言。Keil C51语言是在ANSI C的基础上针对51单片机的硬件特点进行的扩展,并向51单片机上移植,经过多年努力,C51语言已经成为公认的高效、简洁而又贴近51单片机硬件的实用高级编程语言。,3.1 编程语言Keil C51简介,4,C 语言具有结构化和模块化特点,便于阅读和维护。 C 语言可移植性好,很多微控制器都支持C 编译器
3、。功能化的代码能够很方便的从一个工程移植到另一个工程,从而减少了开发时间。 提供的库函数包含许多标准子程序,具有较强的数据处理能力。,使用C语言的优点,5,使用C语言的优点,C 语言编写的程序比汇编语言编写的程序更符合人们的思考习惯,寄存器分配,不同存储器的寻址及数据类型等细节交由编译器管理,开发者可以更专心的考虑算法,而不是考虑一些细节问题。这样可以减少编程出错的机率,从而提高开发效率,减少调试的时间。 C 语言和微控制器是相对独立的,开发者不必知道处理器的具体内部结构和处理过程。当用新型的微控制器开发程序时,可以很快上手,减少学习时间和程序开发时间。,6,C51与标准C的主要区别,(1)头
4、文件的差异。51系列单片机厂家有多个,它们的差异在于内部资源如定时器、中断、I/O等数量以及功能的不同,而对使用者来说,只需要将相应的功能寄存器的头文件加载在程序内,就可实现所具有的功能。因此,Keil C51系列的头文件集中体现了各系列芯片的不同资源及功能。 (2)数据类型的不同。51系列单片机包含位操作空间和丰富的位操作指令,因此Keil C51与ANSI C相比又扩展了4种类型,以便能够灵活地进行操作。电脑CPU是32位或64位,运算能力强,内存大,大量使用float型与long int型变量,单片机一般为8位或16位,运算能力较弱,以char型为主,int型为辅,7,(3)数据存储类型
5、的不同。C语言最初是为通用计算机设计的,在通用计算机中只有一个程序和数据统一寻址的内存空间,而51系列单片机有片内、外程序存储器,还有片内、外数据存储器。标准C并没有提供这部分存储器的地址范围的定义。此外,对于AT89S51单片机中大量的特殊功能寄存器也没有定义。 (4)标准C语言没有处理单片机中断的定义。 (5)Keil C51与标准C的库函数有较大的不同。 由于标准C的中的部分库函数不适于嵌入式处理器系统,因此被排除在Keil C51之外,如字符屏幕和图形函数。,8,(6)目标代码 电脑生成.exe格式,编译完成后直接在电脑上运行,单片机编译生成.bin代码文件,需要烧写到单片机中并结合外
6、围电路执行。 (7)仿真调试 单片机的C程序在电脑上进行编译,然后需通过仿真器连接后进行仿真调试,近年来随着电路仿真软件的不断完善,也可通过proteus等软件直接在电脑上进行仿真调试。,9,但是从数据运算操作、程序控制语句以及函数的使用上来说,Keil C51与标准C几乎没有什么明显的差别。如果程序设计者具备了有关标准C的编程基础,只要注意Keil C51与标准C的不同之处,并熟悉AT89S51单片机的硬件结构,就能够较快地掌握Keil C51的编程。,10,(1)编译器:由源代码文件生成目标文件,(2)开发套件:包含了编译器、链接器等开发工具的组合包,(3)IDE(Integrated D
7、evelopment Environment 集成开发环境) 将项目管理、源代码编辑和程序编译、链接、调试等各种工具组合在一个功能强大的环境中,具有良好人机界面。,8051单片机所使用的C语言编译器简称为 Cx51,例如包含Cx51、Ax51、BL51、LIB51、OH51、RTX51等,Keil Vision3 IDE,3.2 Keil C51的开发工具,11,Keil Vision3 IDE,Cx51.exe,Keil C51开发套件 v7.50,12,C语言结构特点,一个C程序由一个或多个函数组成,其中必须有一个用main命名的主函数。 每个函数由头部和函数体两部分组成。 每个C语句以“
8、;”结尾。 C程序的书写格式比较自由。 可以在程序的任何位置用/*.*/对C程序中的任何部分作注释。 可以在行末用/追加注释。,13,C51的程序结构,#include void delay ( ) ; void main ( ) delay(); P0 = 0 x33; ,例:文件led.c内的代码如下:,程序的入口 函数名固定,且与书写的位置无关 有且仅有一个,库函数或用户自定义的函数 可以有若干个,C51程序大体上是若干函数的集合,14,单片机控制LED(电路图),15,我的第一个程序(单片机控制LED点亮),#include sbit LED = P10; void main( )/主
9、程序 LED = 0;/点亮LED while(1); ,16,单片机控制LED闪烁(程序),#include #define uchar unsigned char #define uint unsigned int sbit LED = P10; void delay(uint x)/延时程序 uchar i; while(x-) for(i = 0;i 120; i+); ,void main()/主程序 while(1) LED = LED; /LED灯闪烁 delay(400); ,17,KEIL与PROTEUS快速入门,Keil C51是美国Keil Software公司出品的51
10、系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。用过汇编语言后再使用C来开发,体会更加深刻。,Keil C51软件提供丰富的库函数和功能强大的集成开发调试工具,全Windows界面。另外重要的一点,只要看一下编译后生成的汇编代码,就能体会到Keil C51生成的目标代码效率非常之高,多数语句生成的汇编代码很紧凑,容易理解。在开发大型软件时更能体现高级语言的优势。,18,1、建立一个新工程 单击Project菜单,在弹出的下拉菜单中选中New Project选项,如图3所示。,图3 新建工程文件,KEIL C51快速入门,19,
11、2、然后选择你要保存的路径,输入工程文件的名字, 如图4所示,然后点击保存。,图4 新建工程文件的保存路径,KEIL C51快速入门,20,3、这时会弹出一个对话框,要求你选择单片机的型号,你可以根据你使用的单片机来选择,keil c51几乎支持所有的51内核的单片机, 如图所示,选择89C51之后,右边栏是对这个单片机的基本的说明,然后点击确定。,图5 选择单片机的型号,KEIL C51快速入门,21,4、完成上一步骤后,屏幕如图6所示。,图6 完成新建工程文件,KEIL C51快速入门,22,下面可以编写程序。 5、在图2-7中,单击“File”菜单,再在下拉菜单中单击“New”选项。,新
12、建文件后屏幕如图8所示。,图7 新建文档,图8 完成 新建文档,KEIL C51快速入门,23,此时光标在编辑窗口里闪烁,这时可以键入应用程序了,建议首先保存该空白的文件,单击菜单上的“File”,在下拉菜单中选中“Save As”选项单击,屏幕如下图所示,在“文件名”栏右侧的编辑框中,键入欲使用的文件名,用C语言编写扩展名为(.c)如果用汇编语言编写扩展名必须为(.asm)。然后,单击“保存”按钮。 如图8所示。,图8 保存新建文档,KEIL C51快速入门,24,6、回到编辑界面后,单击“Target 1”前面的“”号,然后在“Source Group 1”上单击右键,弹出菜单9。,图9
13、打开添加文档界面,KEIL C51快速入门,25,然后单击“Add File to Group Source Group 1”,屏幕如图10所示。,图10 添加文档,KEIL C51快速入门,26,选中main.c,然后单击“Add”屏幕如下图所示。,注意到“Source Group 1”文件夹中多了一个子项“main.c”子项的多少与所增加的源程序的多少相同。 7、现在便可输入程序了,输入完毕进行调试便可运行。,图10 完成添加文档,KEIL C51快速入门,27,Proteus 快速入门,Proteus软件和我们手头的其他电路设计仿真软件最大的不同即它的功能不是单一的。它的强大的元件库可以
14、和任何电路设计软件相媲美;它的电路仿真功能可以和Multisim相媲美,且独特的单片机仿真功能是Multisim及其他任何仿真软件都不具备的;它的PCB电路制版功能可以和Protel相媲美。它的功能不但强大,而且每种功能都毫不逊于Protel,是学习电子设计难得的一个工具软件。,28,ISIS智能原理图输入系统,系统设计与仿真的基本平台。 ARES 高级PCB布线编辑软件。 在Proteus中,从原理图设计、单片机编程、系统仿真到PCB设计一气呵成,真正实现了从概念到产品的完整设计。Proteus 从原理图设计到PCB设计,再到电路板完成的流程如图所示。,29,数据 数据类型、数据结构、存储类
15、型 运算 算术运算、关系运算、逻辑运算、位操作 控制 顺序结构、选择结构、循环结构、函数,3.3 C51语言程序设计基础,C51语言程序设计的三大要素,30,3.3.1 C51数据类型与存储类型,常量与变量 常量:程序运行中值不能改变的量称为常量,常量存在于ROM中。 变量:变量代表存贮器中的一个或多个存储单元,用来存放数据,一般来讲这些值在程序运行中可以改变(只读变量除外) 变量名命名规则:变量名只能由半角的字母、数字、下划线组成,且第一个字符不能是数字。 变量存在的类型称为数据类型。,31,C51数据类型与标准C数据类型的最大不同之处:位型。, 数据类型,32,C51数据类型,33,C51
16、数据类型,34,char 数据类型,单片机应用中ASCII字符和字符串的使用比较少(因为很少需要大量的文本信息),因此在单片机应用中定义为 unsigned char 和 char 的变量常用来表示数值。,数据类型的使用,单片机系统总存储空间往往比较有限,因此在实际使用中应注意节约存储空间; 对于8位单片机,8位的数据类型是运算最快的;而对于16位单片机,8位的数据和16位的数据可能运算速度是一样的。,35,C语言的变量定义与赋值,定义一个变量 先定义,后使用。例如:Int a; char b; 变量赋初值,C允许在定义变量的同时给变量赋初值。 例如: char c = a; int a =
17、7; int a,b,c=9; /定义a、b、c为整型变量,对c赋初值。 int a = 3,b = 3,c = 3; 错误:int a=b=c=3;,36,定义变量类型应考虑如下问题:程序运行时该变量可能的取值范围,是否有负值,绝对值有多大,以及相应需要的存储空间大小。在够用的情况下,尽量选择8位即一个字节的char型,特别是unsiged char。对于51系列这样的定点机而言,浮点类型变量将明显增加运算时间和程序长度,如果可以的话,尽量使用灵活巧妙的算法来避免浮点变量的引入。,37,C51的扩展数据类型,(1)位变量bit bit的值可以是1(true), 也可以是0(false)。 使
18、用关键字bit 例如: bit lock;/*将lock定义为位变量*/ bit dirention;/*将direction定义为位变量*/,38,位变量的使用 不能定义成一个指针,如不能定义:bit *pointer; 不存在位数组如不能定义:bit b_array 位变量定义时,存储类型只允许为data、bdata或者idata,如果将位变量的存储类型定义成其它类型都将导致编译出错。,39,C51的扩展数据类型,(2)特殊功能寄存器sfr AT89S51特殊功能寄存器在片内RAM区的80HFFH之间,“sfr” 数据类型占用一个内存单元。利用它可访问AT89S51内部的所有特殊功能寄存器
19、。 例如:sfr P1=0 x90这一语句定义P1口在片内的寄存器,在后面语句中可用“P1=0 xff”(使P1的所有引脚输出为高电平)之类的语句来操作特殊功能寄存器。 标准SFR在reg51.h、reg52.h 等头文件中已经被定义,只要用文件包含做出申明即可使用。,40,(3)特殊功能寄存器sfr16 “sfr16”数据类型占用两个内存单元。sfr16和sfr一样用于操作特殊功能寄存器。所不同的是它用于操作占两个字节的特殊功能寄存器。 例如: sfr16 DPTR=0 x82语句定义了片内16位数据指针寄存器DPTR,其低8位字节地址为82H。在后面的语句中可以对DPTR进行操作。,41,
20、(4)特殊功能位 sbit sbit 是指AT89C51片内特殊功能寄存器的可寻址位。例如: sfr PSW=0 xd0;/*定义PSW寄存器地址为0 xd0*/ sbit PSW 2 = 0 xd2;/*定义OV位为PSW.2*/ 符号“”前面是特殊功能寄存器的名字,“”的后面数字定义特殊功能寄存器可寻址位在寄存器中的位置,取值必须是07。 注意,不要把bit与sbit混淆。bit用来定义普通的位变量,值只能是二进制的0或1。而sbit定义的是特殊功能,42,#include sbit D3 = P22; void main() D3 = 0 ; /点亮LED while(1) /循环,挂起
21、 ; ,_ ,_ ,_ , 引用含有SFR符号定义的头文件 定义符号D3为P2口的第2位 D3可以换为其他自定义符号,作用相同,如: sbit P2_2 = P22; 点亮发光二极管的功能语句 while(1)无限循环,用于程序的反复执行或者程序挂起,很重要! 使用tab或者空格,使程序结构清晰,便于阅读 适当加入注释,使编程思路清晰,便于阅读和后期的修改,sbit的使用,43, 89S51单片机的数据存储类型,8051系列微处理器采用了哈佛结构,即程序存储器和数据存储器是分离的。8051系列微处理器提供了三种不同类型的存储区域(memory areas): 程序存储区(program mem
22、ory) 内部数据存储区(internal data memory) 外部数据存储区(external data memory) 这三种存储区域均从地址0开始编址,通过采用不同的寻址指令来解决地址重叠的问题。,44,C51数据的存储类型,在讨论C51的数据类型的时候,必须理解数据的存储类型和它与8051单片机存储器结构的关系.,45,C51存储类型,46,存储区域的划分,47,(1)内部数据存储区(internal data memory),内部数据存储区(internal data memory),共256个字节。这部分主要是作为程序的数据段。 前128 字节,称为DATA 区。该区可采用直
23、接寻址方式来访问。DATA区也以用R0 和R1间接寻址访问。 后128个字节,即从地址80H 开始的内部数据存储区,用做特殊功能寄存器区(special function register memory),简称SFR。这些特殊功能寄存器用来控制计时器,计数器,串行I/O,I/O端口和外设的工作。只能直接寻址 注意:特殊功能寄存器并未占用特殊功能寄存器区的所有地址单元,即特殊功能寄存器是离散分布。,48,内部数据存储区的DATA区又可以细分为三个子段: 四个工作寄存器组,每个寄存器组包含8个寄存器,四个寄存器组共32 个字节。由PSW 的RS1 和RS0选择四组寄存器的任意一组作为当前工作寄存器
24、组。 位寻址段BDATA, 包括16 个字节,共128 位,每一位都可单独寻址。也可以按字节进行寻址。 一般数据存储器,仅能按字节寻址,共80个字节。,内部数据存储区(internal data memory),49,(2)外部数据存储区(external data memory),也称为XDATA 区。XDATA区和CODE 区一样也采用16 位地址寻址,即寻址空间可达64KB。 该区通常包括一些通用数据存储器或者一些需要通过总线接口访问的外围器件。 访问外部数据区比访问内部数据区要慢,因为访问外部数据区时,必须先将要访问单元的16位地址装载到数据指针寄存器DPTR中,然后才能通过DPTR采
25、用间接访问方式来访问该单元。,50,C51使用两种修饰符来表示外部数据区:xdata , pdata xdata :说明外部数据空间的所有64KB的地址空间。 pdata :指向外部数据空间中的大小为一页(256字节)的数据存储空间。 注意:某些新型的51芯片有更大的XRAM(如16M的XRAM),一般用far类型来描述这些区域。可以分别用 far 和const far 来访问位于扩充RAM空间中的变量和扩充ROM空间中的常量。 某些单片机芯片提供了片内的XRAM空间,这种空间也使用和传统的外部数据空间相同的指令来访问,外部数据存储区(external data memory),51,说明:某
26、些系列的单片机(如8052) 有额外的128 字节的内部RAM, 同样位于从80H 开始的内部数据存储地址空间中,称为IDATA区。IDATA 区的地址和SFR的地址是重叠的,必须使用不同的寻址方式的指令来解决地址重叠问题。SFR区只能通过直接寻址来访问, IDATA 区只能通过间接寻址来访问。,内部数据存储区(internal data memory),52,(3)程序存储区(CODE),程序存储区,也称为CODE 区,常用来存放可执行代码。代码区的地址位数为16 位,即寻址空间可达64K。 一般情况,程序存储区是只读的,除了保存可执行代码,还可用于保存各种常量值,查找表等固定的数据结构。如
27、: unsigned char code test=“hello!”;,53,存储器类型的变量声明举例,char data var1; char code text = ENTER PARAMETER:; unsigned long xdata array100; float idata x,y,z; unsigned int pdata dimension; unsigned char xdata vector1044;,说明:声明变量时存储区修饰符和数据类型修饰符的位置可以互换,即char data x; 和 data char x; 是完全等效的。不过从兼容性考虑,建议使用前一种格式。,
28、54,变量类型修饰符总结,data: 速度最快,可以读或写操作,只有128字节,可以省略,89C51单片机默认的变量存储位置就是128字节的片内数据存储区。 idata: 速度较快,可以读或写操作,只有128字节,注意只存在于尾缀为52以上的单片机中,当data数据不够可用idata。 xdata: 速度较慢,可以读或写操作,最多有64k字节(取决于外接的SRAM芯片容量),一般用于解决内部SRAM不够用同时对变量访问不需要非常快的应用场合。 code: 速度最慢,只读,最多有64K字节(取决于内部ROM与外部ROM容量之和)。一般用于存储大量的只读数据(如图形液晶的数据,文本数据等),55,
29、定义数据的存储类型通常遵循如下原则:只要条件满足,尽量选择内部直接寻址的存储类型data,然后选择idata即内部间接寻址。对于那些经常使用的变量要使用内部寻址。在内部数据存储器数量有限或不能满足要求的情况下才使用外部数据存储器。选择外部数据存储器可先选择pdata类型,最后选用xdata类型。 需指出,扩展片外存储器,原理上虽很简单,但在实际开发中,很多时候,会带来不必要的麻烦,如可能降低系统稳定性、增加成本、拉长开发和调试周期等,推荐充分利用片内存储空间。,56,另外,通常的单片机应用都是面对小型的控制,代码比较短,对于程序存储区的大小要求很低,常常是片内RAM很紧张而片内Flash RO
30、M很富裕,因此如果实时性要求不高,可考虑使用宏,以及将一些子函数的常量数据做成数据表,放置在程序存储区,当程序运行时,进入子函数动态调用下载至RAM即可,退出子函数后立即释放该内存空间。,57,定义变量时如果省略“存储器类型”选项,则按编译时使用的存储器模式SMALL、COMPACT、或LARGE来使用默认的存储器类型。,SMALL :默认存储类型为data,访问速度最快,容量小 COMPACT :默认存储类型为pdata LARGE :默认存储类型为xdata,访问效率最低,代码长,容量大,一般使用SMALL模式,对部分容量大的变量,手动指定存储器类型(如定义为xdata类型)。, 数据存储
31、模式,58,存储模式(memory models),如果在变量声明时未声明变量的存储器类型,则该变量的存储器类型,由程序的存储模式来决定。 小模式(small model):默认data区 紧凑模式(compact model):默认pdata区 大模式(large model):默认xdata区 注意:除非应用在特殊的场合,否则SMALL存储模式可以提供最快和最有效的代码。,59,3.3.2 C51语言的特殊功能寄存器及位变量定义,特殊功能器的定义 (1)使用关键字定义sfr sfr IE = 0 xA8; (2)通过头文件访问SFR #include #include (3)特殊功能寄存器
32、中的位定义 sbit CY = PSW7; sbit CY = 0 xD07; sbit CY = 0 xD7;,60,位变量的C51定义 (1)位变量的C51定义 (2)函数可以包含类型为bit的参数,也可将其作为返回值。 (3)位变量不能定义指针和数组。,61,如何对单片机片内RAM、片外RAM及I/O进行访问,C51提供了两种比较常用的访问绝对地址的方法。,绝对宏,C51编译器提供一组宏定义来对code、data、pdata和xdata空间进行绝对寻址。在absacc.h的头文件中 在使用前,需要将头文件包含进来: #include,3.3.3 C51语言的绝对地址访问,62,绝对宏,C
33、BYTE :以字节形式对code区寻址; CWORD :以字形式对code区寻址; DBYTE :以字节形式对data区寻址; DWORD :以字形式对data区寻址; XBYTE :以字节形式对xdata区寻址; XWORD :以字形式对xdata区寻址; PBYTE :以字节形式对pdata区寻址; PWORD :以字形式对pdata区寻址。,63,_at_关键字,使用关键字_at_可以对指定的存储器空间的绝对地址进行访问,格式如下 存储器类型 数据类型说明符 变量名_at_地址常数,说明: 存储器类型和数据类型C51能识别的 地址常数必须位于有效的存储器空间之内 使用_at_定义的变量必
34、须为全局变量,64,C51的基本运算与标准C类似,主要包括: 算数运算; 关系运算; 逻辑运算; 位运算; 赋值运算及其表达式。,3.3.4 C51的数据运算,65,算术运算符及其说明,算数运算符,66,对于“/”和“%”往往会有疑问。这两个符号都涉及除法运算,但“/”运算是取商,而“%” 运算为取余数。例如“5/3”的结果(商)为1,而“5%3”的结果为2(余数)。 自增和自减运算符是使变量自动加1或减1,自增和自减运算符放在变量前和变量之后是不同的。 +i,-i:在使用i之前,先使i值加(减)1。 i+,i-:在使用i之后,再使i值加(减)1。,67,例如:若i=4,则执行x=+i时,先使
35、i加1,再引用结果,即x=5,运算结果为i=5,x=5。 再如:若i=4,则执行x=i+时,先引用i值,即x=4,再使i加1,运算结果为i=5,x=4。,68,逻辑运算符,69,关系运算符,70,位运算是指进行二进制位的运算,在单片机编程中,常需要处理二进制位的问题。 例如: 将寄存器的某一位或某几位置1、清0与取反;将一个存储单元中各二进制位左移或右移N位,两个数按位相加等等。 C语言中提供位运算的功能,更加贴近单片机硬件,与其他高级语言相比,具有很大的优越性。,位运算符,71,位运算符,72,左移运算符() 用来将一个数的各二进位全部左移若干位,左高位溢出,右低位补0。 如b=a2;a=a
36、2;a=2; a=15,左移2位等于多少? 高位左移后溢出,舍弃掉。在该数左移时被溢出舍弃的高位不包含1时,左移1位相当于该数乘以2. 152=60 1432=60,73,右移运算符() 用来将一个数的各二进位全部右移若干位,左高位补0,右低位溢出。 如b=a2;a=a2;a=2; a=15,左移2位等于多少? 低位右移后溢出,舍弃掉。 152=3 142=3,74,按位异或运算符() 异或运算符的规则是参加运算的两个二进制位相同为0(假),相异为1(真)。即 00=0;01=1;10=1;11=0; 例如:0 x2D0 x0F=0 x22,将十六进制数0 x2D与十六进制数0 x0F进行按位
37、异或运算,高四位保持不变,低四位全部翻转。通过按位运算可以实现对变量的某一位或某几位取反操作。,75,取反运算符() 是一个单目运算符,用来对一个二进制数按位取反,即将0变1,1变0。例如48。 取反运算符常与移位运算符及按为与、按位或、按位异或运算符结合使用以实现对某一位或某几位清0、置1、取反的操作。,76,按位与运算符( 功能:将c向左循环移位b位 函数原型 unsigned char _cror_(unsigned char c,unsigned char b); 功能:将c向右循环移位b位,用库函数实现上述流水灯,例如: P0 = _cror_(P0,3);/将P0带位循环右移3位,
38、79,例:unsigned char x=0 x55 ; unsigned char y=0 x37 ; unsigned char z; z=x则z=0 x2A,位运算符举例,80,位运算编程小窍门(将某一位置1、置0、取反),将某一位置1(相应位与1进行按位或运算) 例:P0 | = (1 n); /将P0的第n位置1,其它位不变 将某一位置0 (相应位与0按位进行与运算) 例:P0 /将P0的第n位置0,其它位不变 将某一位取反(相应位与1进行按位异或运算) 例:P0 = ( 1 n ),81,按位与的用途,某一位或某几位清零而其它位保持原值 如 原有数在P0寄存器中,为01011010
39、,现要将其第一位清0,其它位保持不变。 则可与11111101进行按位与。 即 P0 = P0 /将P0的第n位置0,其它位不变,82,按位与的用途,取一个数中的某些指定位 例:取单片机P0口的P0.2位状态(1或0)可这样操作: if(P0 ,83,按位异或的用途,将某一位或某几位取反(相应位与1进行按位异或运算) 例:P0 = ( 1 n ) 编程实现 8位LED灯1357位和2468位依次交替闪烁,84,按位或的用途,将某一位或某几位置1(相应位与1进行按位或运算),例:P0 | = (1 n); /将P0的第n位置1,其它位不变,85,赋值、指针和取值运算符,86,复合赋值运算符 十种
40、:, , , , ,。 按优先级顺序结合运算。 例如: a+=b 等价于a=(a+b) x*=a+b 等价于x=(x*(a+b) a else 语句2 else P0=y; if (表达式1)语句1 else if(表达式2)语句2else if(表达式3)语句3else 语句n 在选择结构中,else默认与最靠近它的if配对,可用改变配对。 if语句中,如果需要执行的语句不止一条,可用组成复合语句。,92,93,例:K1-K4按键状态显示,设计一电路和程序实现如下功能: 按下K1或K2键时LED1或LED2点亮,松开时对应的LED熄灭,当按下K3或K4后释放时,LED3或LED4点亮,再次按
41、下并释放时熄灭。,94,95,switch语句专门用来处理多路分支的情形,形式如下: switch (表达式) case 常量表达式1: 语句1: break; case 常量表达式2: 语句2: break; case 常量表达式n: 语句n: break; default: 语句n+1; break; ,96,对switch语句需要注意: case分支中的常量表达式的值必须是整形、字符型或枚举类型,不能使用条件运算符。 break语句用于跳出switch结构。若case分支中未使用break语句,则程序将继续执行下一个case分支中的语句直至遇到break语句或整个switch语句结束。这
42、可以用于多个分支需要执行相同的语句进行处理的情况。,97,for循环语句的一般格式为: for(表达式1; 表达式2; 表达式3) 循环体语句(内部可为空) for循环语句的执行过程为: STEP1:求解表达式1。 STEP2:求解表达式2。若其值为真,则执行循环体;若其值为假,则循环语句结束,执行后续语句。 STEP3:求解表达式3。并转到第2步继续执行,直至条件为假时结束循环。 注意:三个表达式之间必须用分号隔开;若第一次求解表达式2,其值就不成立,则循环体将一次都不执行。,98,while循环 格式为: while(表达式) 循环体语句(内部可为空) while语句先求解循环条件表达式的
43、值。如果为真,则执行循环体;否则跳出循环,执行后续操作。 注意:一般来说在循环体中应该有使循环最终能结束的语句。如果表达式初始值为假,则循环体将一次都不执行。,99,dowhile循环 dowhile语句格式为: do 循环体语句 while(表达式); dowhile循环是先执行循环体一次,再判断表达式的值,若为真,则继续执行循环,否则退出循环。 注意:dowhile语句至少执行循环体一次,100,while(1) /循环体; while(1); for(;);,101,goto语句 goto语句的格式: goto 语句标号; goto语句是无条件转移语句,它将程序的运行转移 到指定的标号处
44、。 注意:goto语句使程序的转移控制变得非常灵活,但是也可能破坏程序良好结构,因此应小心使用。,102,break语句 在循环语句中,break语句的作用是在循环体中测试到指定条件为真时,其控制程序立即跳出当前循环结构,转而执行循环语句的后续语句。 continue语句 continue语句只能用于循环结构中,作用是结束本次循环。一旦执行了continue语句,程序就跳过循环体中位于该语句后的所有语句,提前结束本轮循环并开始下一轮循环。,103,例程:用四个按键分组控制LED,电路图如图所示: 编程实现以下功能: 每次按下K1时LED从上到下递增点亮一只LED,全亮时再次循环开始。 K2按下
45、后点亮上面4只LED K3按下后点亮下面4只LED K4按下后关闭所有LED 要求,用switch 语句来处理按键功能的实现,104,105,作业:请到网络教学平台上下载电路图及编程要求,电路图如图所示,编程实现如下功能: 1、按下K1时,P0端口控制的LED上移一位; 2、按下K2时,P0端口控制的LED下移一位; 3、按下K3时,P2端口控制的LED上移一位; 4、按下K4时,P2端口控制的LED下移一位。 要求用三种不同的方式编程,用KEIL进行程序编制和编译,用PROTEUS进行仿真。 1、用if语句实现。 2、用switch case语句实现 3、编制一P1端口按键移动LED函数,并
46、在主函数中调用来实现。,106,107,数组简介,数组是一组具有固定数目和相同类型成分分量的有序集合。 数组数据是用同一名字的不同下标访问的; 下标为n的元素可以表示为数组名n; C51中常用的有一维数组、二维数组和字符数组。,3.3.6 C51的数组,108,(1)一维数组,一位数组的定义方式: 类型说明符 数组名整形表达式 例如: char ch10; 该例定义了一个一维字符型数组,有10个元素,每个元素由不同的下标表示,分别为ch0、ch1、ch2、ch9。,109,(1)一维数组,在定义数组时候对全部元素赋初值。 int idata a6=0,1,2,3,4,5; 只对数组的部分元素初
47、始化。 int idata a10=0,1,2,3,4,5 在定义数组时,若不对数组全部元素赋初值,则元素被缺省地赋值为0。,110,(2)二维或多维数组,具有两个或两个以上下标的数组称为二维数组或多维数组,定义二维数组的一般形式为: 数据类型说明符 数组名行数 列数,数组名是一个标识符,行数和列数都是常量表达式; 二维数组可以在定义时进行整体初始化,也可以在定以后单个进行赋值。,111,(3)字符数组,若一个数组的元素是字符型的,则该数组就是一个字符数组。例如:,char a10 = “CHENG DU”; 用双引号引起来的一串字符称为字符串常量,C51会自动在字符串末尾加上结束符0。 用单
48、引号括起来的字符为字符的ASCII码值,而不是字符串,如a表示a的ASCII码值61H,而”a”表示一个字符串,由两个字符a和0组成。,112,数组的应用,在C51编程中,数组的查表功能非常有用。例如:,数学运算中提前计算好采用查表计算,可避免单片机运算能力的不足。(如P58例) 传感器的非线性补偿。 数码管和液晶的显示字符或汉字图形码。,113,七段LED数码管,数组的应用数码管静态显示,114,七段LED数码管的结构,115,常用的七段LED数码管的正面(左)与背面(右),116,常用的七段LED数码管尺寸与引脚配置,117,共阳极七段LED数码管的应用,118,共阳极七段LED数码管编码
49、,119,共阴极七段LED数码管的应用,120,共阴极七段LED数码管驱动信号编码,121,静态显示方式 LED显示器工作方式有两种:静态显示方式和动态显示方式。静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。这种方法的优点是占用CPU时间少,显示便于监测和控制。缺点是硬件电路比较复杂,成本较高。,122,例:数码管静态显示程序设计,设计一电路和编制程序,实现按键每按下一次,7段数码管从0开始增加1一直显示到F后再由0开始增加的显示功能。,123,电路设计,124,程序设计,按键采用查询方式,在主程序中不断查
50、询按键接入I/O口是否有电平变化。 数码管显示采用查表方式,将数码管段码表预先以数组的形式放入ROM中。,125,#include #define uchar unsigned char #define uint unsigned int uchar k = 0; uchar code smg = 0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80, 0X90,0X88,0X83,0XC6,0XA1,0X86,0X8E ; sbit KEY_BIT = P33;,126,void delay10ms(uint n) uchar i,j; while(n-)
51、 for(i = 128;i 0;i-) for(j = 34;j 0;j-); ,127,void main(void) while(1) while(KEY_BIT = 1); delay10ms(1); /延时消抖 if(KEY_BIT = 0) while(KEY_BIT = 0); /等待按键释放 P0 = smgk; k+=1; if(k=16) k=0; ,128,3.3.7 C51的指针,C51指针的定义 由于MCS-51单片机有三种不同类型的存储空间,并且还有不同的存储区域,因此C51指针的内容更丰富。 指针除了具有像变量的四种属性(存储类型、数据类型、存储区、变量名)外,按
52、存储区,将指针分为通用指针和不同存储区域的专用指针。,129,通用指针,所谓通用指针,就是通过该类指针可以访问所有的存储空间。 在C51库函数中通常使用这种指针来访问。 通用指针用3个字节来表示: 第一个字节:表示指针所指向的存储空间 第二个字节:为指针地址的高字节 第三个字节:为指针地址的低字节,130,通用指针的定义与一般C语言指针的定义相同,其格式为: 存储类型 数据类型 *指针名1 ,*指针名2 , 例如: unsigned char *cpt; int *dpt; long *lpt; static char *ccpt;,通用指针的特点: 定义简单 访问所有空间 访问速度慢,131
53、,所谓存储器专用指针,就是通过该类指针,只能够访问规定的存储空间区域。 指针本身占用1个字节(data *,idata *,bdata *,pdata *)或2个字节(xdata *,code *)。 存储器专用指针的一般定义格式为: 存储类型 数据类型 指向存储区 *指针存储区 指针名1 ,*指针存储区 指针名2,专用指针,132,指向存储区: 是指针变量所指向的数据存储空间区域。不能够缺省。 指针存储区: 是指针变量本身所存储的空间区域。 缺省时认为指针存储区在默认的存储区域,其默认存储区域决定于所设定的编译模式。 指向和指针存储区,两者可以是同一个区域,但多数情况下不会是同一个区域。,1
54、33,存储器专用指针例子: unsigned char data *cpt1, *cpt2; signed int idata *dpt1, *dpt2; unsigned char pdata *ppt; signed long xdata *lpt1, *lpt2; unsigned char code *ccpt; 上面所定义的指针虽然所指向的空间不同,但指针变量本身都存储在默认的存储区域。,134,又如: 1)unsigned char data *idata cpt1,*idata cpt2; 2)signed int idata *data dpt1, *data dpt2; 3)
55、unsigned char pdata *xdata ppt; 4)signed long xdata *lpt1, *xdata lpt2; 5)unsigned char code *data ccpt; 绿色关键字为指针所指向的存储区 蓝色关键字为指针本身所存储的区域,135,注意:(1)要区分指针变量指向的空间区域和指针变量本身所存储的区域;(2)定义时,前者不能缺省,而后者可以缺省;(3)指针变量的长度:指向不同的区域,占用的字节数不同。 说明:指针变量本身所存储的区域,在定义指针时一般都省略了,指针变量本身保存在缺省存储的区域中。 定义时,缺省指针存储的区域,显得简单,并且对初学者
56、更容易理解。,136,例 编写程序,将单片机片外数据存储器中地址从0 x1000开始16个字节数据,传送到片内数据存储器地址从0 x30开始的区域。 程序段如下: unsigned char data i, *dcpt; unsigned char xdata*xcpt; dcpt=0 x30;/给指针赋地址 xcpt=0 x1000; for(i=0;i16;i+) *(dcpt+i)=*(xcpt+i);,137,例 在数字滤波中有一种叫做“中值滤波”技术,就是对采集的数据按照从大到小或者从小到大进行排序,然后取中间位置的数作为采样值。试编写一函数,对存放在片内数据存储器中,从0 x50开
57、始的21个单元的采样数据,用冒泡法排序进行中值滤波,并把得到的中值数据返回。 中值滤波函数如下: unsigned char median_filter() unsigned char data *point,i,j,n,d;,138,for(i=0;i20;i+)/外层循环20次 point = 0 x50;/point指向0 x50处 n=20i;/n为内层循环次数 for(j=0;jn;j+)/内层循环 if(*point*(point+1)/从大到小排 d=*point; *point=*(point+1); *(point+1)=d; point+;/指针指向下一个数 point=0
58、 x50+10;/指向位于中间的数 return *point;/返回得到的中值 ,139,3.4 C51语言的函数,从用户的角度来看,有两种函数:标准库函数和用户自定义函数。 函数定义的一般形式为: 函数类型 函数名(形式参数表) 形式参数说明; 局部变量定义; 函数体语句; 其中,“函数类型”说明了自定义函数返回值的类型。,140,在C语言中可以采用三种方式完成函数的调用: (1)函数语句。在主调函数中将函数调用作为一条语句。 如:delay(100); (2)函数表达式。在主调函数中将函数调用作为一个运算对象直接出现在表达式中。 如:c=2*max(a,b); (3)函数参数。在主调函数中将函数调用作为另一个函数用的实际参数。 如:m=max(a,max(b,c),141,函数举例设计可调节时间的延时程序,void delay10ms(uint n) uchar i,j; while(n-) for(i = 128;i 0;i-) for(j = 10;j 0;j-); ,142,函数举例 带参数返回函数,uchar Busy_Check() uchar state;Lcd_RS = 0;Lcd_RW = 1; Lcd_EN = 1;DelayMS(1);state = P0; Lcd_EN = 0;DelayMS(1); return s
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 五下十道题目及答案英语
- 东京入学考试题目及答案
- 养老院药品管理与使用制度
- 养老院老人生活娱乐活动组织人员职业道德制度
- 养老院老人家属沟通联系制度
- 养老院服务质量投诉处理制度
- 养老院财务管理与审计制度
- 办公室绩效考核与奖惩制度
- 针对施工现场人员的处罚制度
- 酒店规章制度奖罚制度
- DL∕T 1882-2018 验电器用工频高压发生器
- 固体废物 铅和镉的测定 石墨炉原子吸收分光光度法(HJ 787-2016)
- DB45-T 2675-2023 木薯米粉加工技术规程
- 板材眼镜生产工艺
- Unit 3 My weekend plan B Let's talk(教案)人教PEP版英语六年级上册
- 实习考勤表(完整版)
- 名师工作室成员申报表
- DB63T 2129-2023 盐湖资源开发标准体系
- 中药学电子版教材
- 第五版-FMEA-新版FMEA【第五版】
- 美术形式设计基础与应用教学燕课件
评论
0/150
提交评论