现代电子技术工程设计与实践_第1页
现代电子技术工程设计与实践_第2页
现代电子技术工程设计与实践_第3页
现代电子技术工程设计与实践_第4页
现代电子技术工程设计与实践_第5页
已阅读5页,还剩85页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、现代电子技术工程设计与实践7.2 C51单片机开发语言单片机开发语言n7.2.1 C51程序语言简介 n7.2.2 C51程序语言的基本结构n7.2.3 C51的数据类型n7.2.4 C51变量的存储种类和存储器类型n7.2.5 C51的算术与逻辑运算n7.2.6 C51程序语言的语句n7.2.7 函数和指针数组n7.2.8 预处理指令 现代电子技术工程设计与实践7.2.1 C51程序语言简介 n初级单片机程序设计者喜欢使用汇编语言撰写 8051 单片机程序,因为它可以直接操作寄存器和存储器,并掌控单片机内部的每个工作细节。但随着 8051 系列单片机种类的多样化,功能多元化与程序复杂化,使得

2、程序设计者都逐渐采用C51 语言程序编写 8051 单片机程序,原因有以下几点: n若使用汇编语言,程序设计者必须熟悉它所针对的硬体结构的每一细节,才能正确的操作装置。如果要将程序移植到其它不同的单片机上,则因为其处理器及存储器配置有所不同,势必大量修改其程序,增加开发时间。尤其是现在以 8051 为核心的单片机型号种类繁多。 现代电子技术工程设计与实践7.2.1 C51程序语言简介n使用汇编语言处理复杂运算时,程序设计者必须考虑程序中每个操作细节,例如在进行四则运算时,还要考虑如何配合特定的寄存器去执行任务,使程序变的十分冗长,缺乏可读性,增加程序设计与调试的难度。 n基于以上原因,8051

3、系列单片机有必要引用一套C51高级语言,作为程序开发语言。采用 Keil Vision 提供的C51程序语言编译与连结功能进行编译,通过编译的方式,协助使用者处理程序中许多琐碎且重复的细节。现代电子技术工程设计与实践7.2.2 C51程序语言的基本结构nC51 的程序写法基本上和一般C语言相类似。程序主体是由许多的函数(function) 汇编而成,函数的主体内容必须以大括号 包含。程序的执行,就是在函数彼此调用完成。n一个完整的程序,无论它有几个函数,其中必定有一个函数名为“main()”,它被C语言的编译器认定为是程序的起始点,也就是程序第一个被执行的函数。以下就是一个最基本C51程序。现

4、代电子技术工程设计与实践7.2.2 C51程序语言的基本结构n/ 例:C51示例n #include n void main() n n P0=0 x81; / 输出到 P0 口 n P1=0 x0F; / 输出到 P1口n P2=0 x55; /* 输出到 P2口*/ n P3=0 xC3; /* 输出到 P3口*/ n 现代电子技术工程设计与实践7.2.2 C51程序语言的基本结构n从C51 程序的基本结构看出,程序主体是由一个 main()的函数所组成。大括号内内容即为C51程序码。n撰写C51程序需要注意如下的事项: n1. C51 程序结构中,程序码是由语句 (Statement)

5、组成,每个语句就相当一行指令码,必须用分号标记 “;”做为结尾。因此在程序编辑器中换行,若编译器没有看到 “;”,会视为同一行处理。反之,就算在编辑器没换行,但是您打了“;”,编译器会视为两个不同的叙述。 现代电子技术工程设计与实践7.2.2 C51程序语言的基本结构n2. C51 会区分字母大小写,这和 BASIC 程序语言不同,所以千万不要将大小写混用,如main不可写成MAIN。 n3. C51 的注解有两种写法。一种以“/”开头,编译器会把“/”之后的文字全部当做注解,直到此行的尾端。另一种方式是用 /*( 注解 )*/ 。标记“/*”是注解的开始,标记“*/”为注解的结束,两者之间不

6、限行数。 n4. 注解不参与程序的执行,若适时在程序中加入注解,标明各区段程序的功能,可增加程序的可读性,对于日后程序的调试与维护都有很大的帮助。 n5. #include 是预编译指令,是C51 程序执行前对编译器所下的指示。 是编译 8051单片机程序必须指定载入的头文件。现代电子技术工程设计与实践7.2.3 C51的数据类型n在标准的C 语言中,提供 char, int, short, long, float, double 等基本的数据类型。数据类型的预设值是带有正负号 (以最高数据位来表示其正负号,0为正,1为负) 。若在数据类型前面加上关键字 “unsigned”,指明数据是不带符

7、号。为了配合 8051 单片机的操作,C51额外定义 bit 、sfr 、sfr16 、sbit 等数据类型。这些类型原本不包含在ANSI C中,其定义及使用方法与前述的基本形态有所差异,C51的常数、变量与各种结构的声明,是在存储器位置上预留数据存放的空间。不同的数据类型,占有存储器空间的大小与数据存放格式有所不同,因此声明就等于是在配置存储器空间。这样可以省去繁杂的数据搬移与寻址工作。 现代电子技术工程设计与实践7.2.3 C51的数据类型n表7-3Keil C51编译器支持的数据类型数据类型长度值域char1字节有符号字符,范围-128127unsigned char1字节无符号字符,范

8、围0255int2字节有符号整型数据,范围-32768+32767unsigned int2字节无符号整数型态,范围065535long4字节有符号长整数型态,范围-214783648+214783647unsigned long4字节无符号长整数型态,范围04294967295float4字节符点型数据,范围1.75494E-38 3.402823E+38*13字节对象的地址bit位0或1sfr1字节0255sfr162字节065535sbit位0或1现代电子技术工程设计与实践7.2.3 C51的数据类型n(1)char:占用一个字节(byte)的存储器空间,即8个数据位(bit) 。一般可

9、表示-128127的整数,定义为 unsigned(无号数)时可表示 0255的整数。这是C51程序最常用到的数据类型,因为8051单片机是8位数据的,主要运算都以8位数据为主,而且存储器空间有限,所以采用这种变量型式最经济。 n(2)int:整数占用2个字节,也就是16个数据位 (bit) ,可表示-3276832767之间的整数,定义为 unsigned(无号数)可表示065536的整数。由于int需要使用两个单位的空间,在操作上也同时增加处理器的负担,所以若非必要请尽量少用。 现代电子技术工程设计与实践7.2.3 C51的数据类型n(3)short:短整数在C51中,它和 int 是等价

10、,这里不重复说明。 n(4)long:长整数占用4个字节 ,即32个数据位(bit),可表示-21474836482147483647之间的整数,定义为 unsigned(无号数)可表示04294967295之间的整数,一般在 C51较少使用。 n(5)float:浮点数占用4个字节 ,即32个数据位(bit)。其中第一个数据位为正负号,接下来 8个数据位代表指数 (以2为底),最后23数据位数代表有效位数 (忽略开头的1以节省一个数据位) ,最多可表示-3.410-38 3.41038,共有7位有效数字(十进制) ,请特别注意,不可定义unsigned float 。此外, float的操作

11、是很浪费空间和时间,若不是特殊的情况,不要轻易使用 (操作浮点数,必须连结 C51FPS.LIB 程序库)。 现代电子技术工程设计与实践7.2.3 C51的数据类型n(6)double:在C51中,此类型和 float 等价为 32 数据位的浮点数。 n由于C51程序处理有符号数的机会较少,为了提高存储器的使用效率,通常在数据类型定义时指明为不带符号的“unsigned”。由表7-3所示,数据类型的可表示范围在不用符号数情况下,正数的涵盖范围可增加一倍。n(7)bit:位标量 nbit位标量是 C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义n位指针,也不能定义位数组。它的值

12、是一个二进制位,不是 0就是1,类似一些高级语n言中Boolean类型中的True 和False。 现代电子技术工程设计与实践7.2.3 C51的数据类型n(8)sfr:C51特别提供给直接存取单片机上位于 0 x800 xFF 位址的特殊寄存器,它的定义方法为 : sfr 变量名称 = 特殊寄存器的地址。 n通过这个变量名称的定义,就可以存取特殊寄存器的内容。例如定义 “sfr P0=0 x80;”,操作P0来实现对Port 0的读写。但请注意,sfr不可在任何函数中定义,必须定义成全局变量 (也就是不包含在任何大括号中) ,这个数据类型占用8位数据。(见KeilC51INCreg51.h

13、标头档,里面有一些常用的 8051特殊寄存器的定义)。现代电子技术工程设计与实践7.2.3 C51的数据类型n(9)sfr16:16位特殊功能寄存器 nsfr16 :定义方式和特性均与 sfr 一样,但是它是针对 16位数据的特殊寄存器,因此其内容会占用 16位数据。 n(10)sbit :有两种功用,一是能定义存取RAM 中可位寻址区 (20H-2FH) 的内容。二是能定义存取位数据(80H-FFH) 中的特定数据,其定义方式与sfr相同,另外由于存储器位址都是以1个字节也就是8个位数据,如果想指明是哪个位数据,则可使用”符号,定义方式如下: n sbit 变量名称 =特殊寄存器的位址 位数

14、据编号;现代电子技术工程设计与实践7.2.3 C51的数据类型n其中位数据编号可为 07,分别对应这个位元组中的8个位数据。例如8位数据sw,可分别设定每一个位数据的名称,如 n sbit sw_0=sw0; n sbit sw_1=sw1; n 请注意,这里的符号意义是指8位数据的第07的数据位,而不是XOR运算符。现代电子技术工程设计与实践7.2.3 C51的数据类型nreg51.h 头文件头文件 nC51将8051单片机的寄存器地址定义写成一个头文件reg51.h,文件内部就利用 sfr 将寄存器以习惯常用的名称做定义。在 C:KeilC51INC 目录上可以找到这个文件,可以使用一般文

15、字编辑器,如记事本打开,内容如下: 现代电子技术工程设计与实践7.2.3 C51的数据类型nHeader file for generic 80C51 and 80C31 microcontroller. n Copyright (c) 1988-1997 Keil Elektronik GmbH and Keil Software, Inc. n All rights reserved. n - -*/ n /* BYTE Register */ n sfr P0 = 0 x80; n sfr P1 = 0 x90; n sfr P2 = 0 xA0; n sfr P3 = 0 xB0; n

16、 sfr PSW = 0 xD0; n sfr ACC = 0 xE0; n sfr B = 0 xF0; n sfr SP = 0 x81; n sfr DPL = 0 x82; n sfr DPH = 0 x83; 现代电子技术工程设计与实践7.2.3 C51的数据类型n sfr PCON = 0 x87; n sfr TCON = 0 x88; n sfr TMOD = 0 x89; n sfr TL0 = 0 x8A; n sfr TL1 = 0 x8B; n sfr TH0 = 0 x8C; n sfr TH1 = 0 x8D; n sfr IE = 0 xA8; n sfr IP

17、= 0 xB8; n sfr SCON = 0 x98; n sfr SBUF = 0 x99; n /* BIT Register */ n /* PSW */ 现代电子技术工程设计与实践7.2.3 C51的数据类型nsbit CY = 0 xD7; n sbit AC = 0 xD6; n sbit F0 = 0 xD5; n sbit RS1 = 0 xD4; n sbit RS0 = 0 xD3; n sbit OV = 0 xD2; n sbit P = 0 xD0; n /* TCON */ n sbit TF1 = 0 x8F; n sbit TR1 = 0 x8E; n sbi

18、t TF0 = 0 x8D; 现代电子技术工程设计与实践7.2.3 C51的数据类型n sbit TR0 = 0 x8C; n sbit IE1 = 0 x8B; n sbit IT1 = 0 x8A; n sbit IE0 = 0 x89; n sbit IT0 = 0 x88; n /* IE */ n sbit EA = 0 xAF; n sbit ES = 0 xAC; n sbit ET1 = 0 xAB; n sbit EX1 = 0 xAA; n sbit ET0 = 0 xA9; n sbit EX0 = 0 xA8; 现代电子技术工程设计与实践7.2.3 C51的数据类型n

19、/* IP */ n sbit PS = 0 xBC; n sbit PT1 = 0 xBB; n sbit PX1 = 0 xBA; n sbit PT0 = 0 xB9; n sbit PX0 = 0 xB8; n /* P3 */ n sbit RD = 0 xB7; n sbit WR = 0 xB6; n sbit T1 = 0 xB5; n sbit T0 = 0 xB4; n sbit INT1 = 0 xB3; n 现代电子技术工程设计与实践7.2.3 C51的数据类型n sbit INT0 = 0 xB2; n sbit TXD = 0 xB1; n sbit RXD = 0

20、 xB0; n/* SCON */ n sbit SM0 = 0 x9F; n sbit SM1 = 0 x9E; n sbit SM2 = 0 x9D; n sbit REN = 0 x9C; n sbit TB8 = 0 x9B; n sbit RB8 = 0 x9A; n sbit TI = 0 x99; n sbit RI = 0 x98 ;现代电子技术工程设计与实践7.2.3 C51的数据类型nreg51.h 这个文件是 Keil Vision 系统内建的头文件,在编写 8051 单片机程序时,每个程序开头只要使用 “#include“ 预编译指令将它加入,就可以直接在程序中使用这个

21、以使用者习惯使用的变量名称定义的特殊寄存器 (SFR) ,免除使用者自行定义的麻烦。现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n1. 变量的定义 n变量使用之前,必须先定义变量的类型。基本的变量定义方法如下: n(unsigned/singed) 变量类型 变量名称 (= 初始值 ); n 变量类型与变量名称以加粗体显示,表示一定要写出,未写unsigned一律视为signed类型。变量可以先预设初始值,也可以暂时先不给定。 n有关变量的名称,要注意以下几点: n(1)禁止使用ANSI C/C51所保留的关键字,因为它在程序中有着特殊的作用。 n(2)变量开头的字符

22、不可以是数字,另外一些有特殊意义的符号如“+-*/?#;&”,也不要用在变量中,而且名称中不可有空格,如果需要分隔可使用下划线“_”来完成。 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n(3)在相同区域内 (位于同一中)的变量名称不可重复使用,即使它们具有不同的变量类型。 n(4)在同一个变量定义中,允许定义多个相同类型的变量,变量和变量间只须用逗号分隔即可,如 “int a=1,b=2,c=3;” 。 n(5)通常变量的内容是可以被任意变更的,如果想定义一个常数 (也就是在程序的任何地方都不能被改变),可在变量定义前加入关键字 ”const”,例如 const i

23、nt size=5;被定义成 const 的变量必须立即给予初始值,尝试改变一个常数会被 Compiler 所纠正。现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n2. 变量的有效范围 nC51语言由函数组成,在不同的函数中定义的变量,有效范围也有一定的规范,即变量在函数中保存或释放存储器空间的方式有所不同。一般可分为局部变量、静态变量、全局变量。分别说明如下: n(1)局部变量:C51语言最常使用的变量类型。在函数的大括号“内定义的变量,有效范围仅限于大括号内部,当程序一离开此函数,变量就失去作用,占有的存储器也会被释放。在不同括号内的程序也不允许存取它,只有在 ma

24、in()函数中才有作用。此外,一些 C51语言的程序流程控制指令,如 for, while 等,也具有大括号,如果在其中定义变量,则有效范围也只限于大括号中的程序部分。 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n(2)静态变量 :局部变量一旦离开其所在的大括号就失去作用,存储器会被释放,但是能通过在定义前加入static关键字,静态变量定义让系统帮保留变量的内容,以留待下一次被调用时使用,如下面的例子 :n void function() n n static int s; n s=5; n 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n

25、当第一次调用functon 时,会建立静态变量s,并且在它结束时,保留它的值 (s=5) 。当再次调用function 时,不会再重建一个变量s,而直接把原先s的值拿出来用,所以一进入function,s的值就已经是 5了( 在执行 s=5 之前) ,静态变量一直要到程序结束后才会被清除。 n(3)全局变量:必须定义在所有大括号之外,而且通常在程序的最前面定义,它的特点是能在任何函数中被使用,而且一直要到程序结束后才会被释放,如:现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型nint g; n void main() n n g=5; n n void fun1() n

26、 n g=8; n 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n虽然定义全局变量十分方便,但是由于所有函数都能存取,因而增加管理上的不便,另外,万一外部变量和局部变量同名(这是被允许的),则系统会优先存取局部变量。 n(4)外部变量:有时候,需要存取定义在别的局部的变量或该局部下方才定义的变量,可以用extern关键字来连接这个变量,严格说起来,用 extern 定义时并不会建立一个变量,它只会到其它模组去找寻同名的变量以连结。如:现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n void main() n n extern int e; n

27、 / below main or in other file n int e; 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n此时,由于全局变量e是定义在 main函数之后,所以在main中不能直接存取这个变量(Compiler 会视同e是一个没有定义的符号),但是通过加入外部变量,就可以在main中存取变量e了,但如果定义的外部变量确实在程序中没有相应的真实变量,则易造成程序出错,在编译程序时,编译器也会提醒这一点。现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n3. 变量的存储种类n变量定义时就指定了内存种类即变量存储空间的分配,定义一个变

28、量的格式如下: n存储种类 数据类型 存储器类型 变量名表;n存储种类有四种:自动(auto),外部(extern),静态(static)和寄存器(register),缺省类型为自动(auto)。此外,C51中提供了 data 、 bdata 、 idata 、 pdata 、 xdata 、 code 等修饰字,协助指定变量储存的存储器种类,而各种存储器的特性如下: n(1)data类型:指将变量存放在内部存储器前128字节 (00H-7FH),使用直接寻址方式存取(8位寻址),所以速度最快。但这块内存的空间有限,而且前32个字节00H-20H是内定的四组暂存器使用位置,所以必须节省使用。现

29、代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n(2)bdata 类型:即位于内部存储器20H-2FH 的可位寻址区,包括16个字节(128bits) 。 定义bdata 型变量可做个别位处理。n(3)idata 类型:通过间接寻址存取的变量,如果芯片内部存储器不止128字节 ( 如 8052),则可以通过它来定义 80H 以上的存储器内容,速度不如 data 但可以存取所有的内部存储器地址 (00H-FFH),和data 一样采8位寻址。 n(4)xdata 类型:指将变量存放在外部存储器之中,通过DPTR 暂存器作间接寻址存取,为十六位寻址,处理时间较长,一般有 64

30、 Kbytes 的储存空间,如果占用空间大但存取不频繁的变量可以尽量存在这里。 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n(5)pdata 类型:是指外部存储器中的8位寻址区,称为“分页寻址区”,它位于 XDATA局部中,总共有256 个字节,采用间接寻址的方式存取,速度稍快于 xdata ,而PDATA 位于 XDATA 中的位置则要看输出给P2的内容,它决定 XDATA的16位寻址中高8位,例如若 P2=0 xFF,则 PDATA 就位于 X:0 xFF00X:0 xFFFF 中。 n(6)code 类型:是指存放程序的只读存储器ROM,定义其中的数据不可被任

31、意变更,所以一般可在其中定义一些常数,code 使用DPTR寄存器作16位寻址。 现代电子技术工程设计与实践7.2.4 C51变量的存储种类和存储器类型n表7-4 存储器种类存储器类型 范围 说明 rgister R0R7 寄存器 code C:0 x0000C:0 xFFFF 程序存储器 data D:0 x00D:0 x7F 128Byte 的内部存储器 ( 可直接指定地址 ) idata 0 x800 xFF 可间接寻址存储器区 bdata 00 x200 x2F 可位寻址的内部存储器 xdata 64KB 外部存储器 pdata a=8,b=9 n b=-a; / result-a=7

32、,b=7 n递增/递减运算符放前面时,会被先执行,再执行其它的操作,如果放后面,则会先执行其它操作,再执行递增或递减的操作。现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n2. 关系运算符 n 关系运算符包含“”,“=”,“!=”,“=”等运算符,它们只会产生两种结果,分别是1(成立),或0(不成立),如写“c=6 5”,则c就为0,另外“=”在C语言中才代表相等,请不要将它和指定运算符“=”搞混了,而“!=”则代表不等于。关系运算的符号、表示式与说明如表7-6所示。现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n表 7-6 关系运算符 运算 符号 表达式说明小于

33、ab a ab ab 判断 a 是否大于 b ,成立为 1 小于等于 = a= a=b a 是否大于等于 b ,成立为 1 等于 = a=b 判断 a 是否等于 b ,成立为 1 不等于 != a!=b 判断 a 是否不等于 b ,成立为 1 现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n3. 逻辑运算符 n 逻辑运算符:(&,|,!)逻辑运算符只会针对真(1)和假(0)两种情形去处理。逻辑运算的符号、表示式与说明如表7-7所示。 现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n表7-7 逻辑运算符运算 符号 表达式 说明 AND & a&b 若 ab 两数都非零

34、,得出结果 1 ,否则为 0 OR | a|b 若 ab 两数有一数非零,得出结果 1 ,否则为 0 NOT ! !a 置于 a 数前方 ! 表示 a 数反相 现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n4. 位运算符 n 位运算符:(&, |, , ,) ,这些运算符是针对变量中每一个位操作。位运算的符号、表示式与说明如表7-8所示。 n(1)&运算符:代表对两个变量中的每一个位作AND运算 (千万不要将它和逻辑运算符& 混为一谈)。n(2)|运算符:代表对两个变量中的每一个位作 OR 运算。n(3) 运算符:代表对两个变量中的每一个位作 XOR 运算。n(4)运算符:会将

35、变量取补数 (1补数),即会把所有位作 NOT 运算。 n(4) 运算符:代表将变量左移/右移,并在最右/左端补上0, 左端代表要位移的变量,右端代表位移量。现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n表 7-8 位运算符运算 符号 表达式 说明 AND & a&b a 与 b 两变量的相对位元做 AND 运算 OR | A|b a 与 b 两变量的相对位元做 OR 运算 XOR ab a 与 b 两变量的相对位元做 XOR 运算 取反 ab a 变量的每一位元做反相运算 右移 an a 变量 内 位元右移 n 次 (n=1,2,3) 左移 an a 变量 内 位元左移 n

36、次 (n=1,2,3) 现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n5. 赋值运算符 n在执行算术逻辑运算时,通常运算结果需要存回原来的运算元,赋值运算符就提供一种处理方式。例如c=b+a,等同于a+=b,将 a+b 的结果直接存回a,省略了c变量的定义。其中“+=”就是指定运算符。其它的赋值运算符如表7-9所示。 n赋值运算符“=”,在C语言中单一等号并不代表等于,而代表将等号右侧的内容指定给左侧的变量,一般写成这种型式:变量 = 表示式;现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n在右端的表示式可以是一个变量、常数或任意的的算术或逻辑运算式,左端则必为一

37、个变量,不可以放置运算式,如果同时指定给多个变量,则可以使用下式:n变量 = 变量 = 表示式;n例如,若想让 a, b 等于5,则可以写成 a=b=5;另外,定义成const的变量不能放置于等号左端。在这里,顺变补充一下常数的表示法,在以后的程序编写中,一般只会用十进制或十六进制来表示其值,在C语言中无论键入任何数,都被预设为十进制的,如果想使用十六进制表示数,必须在前面加上 “ox” ,如想表示16进制数1FH ,则写成 0 x1F 。如果将一个四则运算式指定给一个变量,而该四则运算中又包含该变量,可以用复合指定运算符来简化,如 a=a+4 可以简写成 a+=4 。n变量 A= 变量 A

38、(+,-,*,/,%) 表达式等价于变量 A (+,-,*,/,%)= 表达式;现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n表 7-9 赋值运算符运算 符号 表达式 说明 加法 += a+=b 等同于 a=a+b 减法 -= a-=b 等同于 a=ab 乘法 *= a*=b 等同于 a=a*b 除法 /= a/=b 等同于 a=a/b 余数 %= a%=b 等同于 a=a%b 与&= a&=b 等同于 a=a&b 或 |= a|=b 等同于 a=a&b 互斥 = a=b 等同于 a=a&b 左移 = a= a=b 等同于 a=a&b 现代电子技术工程设计与实践7.2.5 C5

39、1的算术与逻辑运算n 6. 运算符优先顺序 n 在一个复杂的算式中,若包括超过一个以上的运算符,如 h=a*(b+c|d)-e/(f&g),必须考虑到运算的优先顺序。最常见有 “先乘除,后加减”,因为乘除的优先顺序高于加减运算符,说明如表 7-10所示。现代电子技术工程设计与实践7.2.5 C51的算术与逻辑运算n表 7-10 运算符的优先顺序顺序 运算符 作用 1 () 括号 2 ,! 取反, NOT 运算 3 +,- 递增 / 递减 4 *, /,% 乘,除,余数 5 +,- 加,减 6 移位 7 =, 关系运算符 8 =, != 相等 / 不相等 9 & 位操作 AND 10 位操作 X

40、OR 11 | 位操作OR 12 & 逻辑 AND 运算 13 | 逻辑 OR 运算 14 =,*=,+=,/=,-=,=,&=,|=,= 赋值 / 复合赋值 现代电子技术工程设计与实践7.2.6 C51程序语言的语句nC51程序语言的代码,相当于汇编语言的指令码,但其功能与形式比汇编语言更为强大与精简。C51程序语言的语句大致可分为下列四种: n声明、定义语句,利用常数、变量与各种结构的声明、定义,替代汇编语言中繁琐的数据搬移与定址方式。 n算术逻辑运算语句,利用简单的运算符号,提供加、减、乘、除、与AND、OR 、NOT、 XOR等运算。 n程序流程控制语句,提供更简便的循环、条件判断等的

41、程序流程控制功能。 n函数调用语句,通过函数调用功能,提供具有结构化的程序。 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n1. 循环控制语句 n 循环控制功能是让程序某几行语句能够重复执行。C51语言常用的循环语句有for、while、do-while 三个。三者的差异在于判断循环是否执行的先后时机,用法分述如下: n(1)for 循环:最典型的循环形式,控制循环的方式包含循环变量初值、循环条件与循环变量增值。要求重复执行的程序段落必须放置在大括号内。语句的写法如下: n for (循环变量初值; 循环条件; 循环变量增值) n n ( 要求重复执行的语句 ) n 现代电子技术

42、工程设计与实践7.2.6 C51程序语言的语句n进入for循环会先给循环变量赋初值,然后再判断循环条件。这里的循环条件主要是由7.2 节的关系运算符与逻辑运算符组成,也可为任意运算表示式,如果运算结果为成立 (非0),则循环会继续执行,若不成立 (0)则会跳出循环。如果指定一个非0的常数或根本不写判断条件,就会形成无穷循环 (当然如果指定常数0,这将是一个没有意义的循环),最后会执行循环变量的增加或减少。循环变量初值和循环变量增值都可以省略。两个以上叙述之间以逗号“,”分隔。n例如: for (i=0,j=0;i5;) 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n循环内重复执行

43、的程序必须加上大括号。如果只有一个叙述,括号可省略。需要注意的是,无论是for,还是之后将介绍的while,do while,ifelse,switch 等等,其所包含的程序区段一样会被视为一个局部,在其中定义的变量,视为局部变量,只有在该局部有效。 n(2)while循环:若程序循环不需初始条件和更新条件,则可考虑使用while循环,它只须处理判断条件,语句的写法如下: n while ( 判断运算式 ) n n ( 要求重复执行的语句 ) n n判断运算式的作用和for循环一样,如果为非0值,会被继续执行,为0则跳出循环。常看到以”while(1)”代表程序将进入无穷循环,而被大括号括住的

44、程序码会被重复执行。 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n(3)dowhile循环:功能几乎和while一样,唯一的差别在于它先执行后判断,也就是说它至少会做一次,语句的写法如下: ndo n (要求重复执行的语句) n n while(判断运算式) n 例 循环应用实例 n使用三种不同方式的循环,执行 1 累加到10的计算过程。 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n void main() n n int i,sum1=0; / for 循环用变量 n int j=1,sum2=0; / while 循环用变量 n int k=1,sum3=0

45、; / do while 循环用变量 n /* for 循环叙述计算 1 加到 10 的总和 */ n for(i=1;i=10;i+) n sum1+=i; n /* while 循环叙述计算 1 加到 10 的总和 */ n while(j=10)n n sum2+=j; n j+; n n /* do-while 循环叙述计算 1 加到 10 的总和 */ n do n sum3+=k; n k+; n n while(k=10); n 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n2. 条件分支控制 n 条件分支控制的功能是让程序在某些条件成立下,才去执行某些叙述。C51

46、语言常用的有ifelse和switchcase。功能与使用说明如下:n(1)ifelse 语句n最典型的条件形式,只有判断条件成立才会执行其所包含的程序叙述,它的写法如下: n if ( 判断运算式 A) n n (A 成立时要执行的叙述 ) n n else if ( 判断运算式 B) n n (A 不成立但 B 成立要执行的叙述 ) n else n (A 、 B 皆不成立要执行的叙述 ) n 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n判断运算式的写法和前述的 for 和 while 写法完全一样,基本上由关系和逻辑运算式组成。对于单一条件的判断,通常可以省略 else

47、if 叙述,只需使用 ifelse ,如下面的范例所示的简单条件分支应用。若不考虑条件不成立的情况,连 else 也可以省略掉。 n例:简单条件分支应用实例 n使用 if-else简单条件支判断功能,执行由P1口的输入状态,决定 P0 输出的执行过程。 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n#include n void main() n n while(1)n n if(P1=0 x01) n P0=0 x80; n else n P0=0; n n 现代电子技术工程设计与实践7.2.6 C51程序语言的语句n(2)switchcase 语句n如果条件分支判断要处理多种

48、不同情形时,虽然可用多个 ifelse if if 来完成,但是如果是要依照某个变量的值,判断要执行那一部份的程序,则 switch case语句会使程序更为清楚明确:现代电子技术工程设计与实践7.2.6 C51程序语言的语句n switch ( 要判断的变量名称 ) n n case 常数 1: n ( 程序叙述 1) n break; n case 常数 2: n ( 程序叙述 2) n break; n case 常数 3: n ( 程序叙述 3) n break; n . n default: n ( 程序叙述 n) n 现代电子技术工程设计与实践7.2.6 C51程序语言的语句nsw

49、itch 结构是由多个case标记组成的,case后面必须是一个已定义的常数(不能是变量),如果变量值正好等于其中某一常数,则程序就会跳到该标记去执行,然后一直执行到switch叙述尾端。假如不想让程序逐一执行到最后一项,则可以用break叙述,强迫跳出 switch 叙述。至于default标记是用来处理这些常数都不等于该变量时,程序所要跳到的地方,但也可以将它省略。现代电子技术工程设计与实践7.2.6 C51程序语言的语句n(3)无条件跳转 (goto) n这是最基本的流程控制指令,意义相当于汇编语言中的 ”JMP” 指令,程序一旦执行到 goto 指令,就会跳到其后面指定的程序位址,由于

50、在C语言中一般没有用行号来标示各程序叙述,也不过问程序码放置在存储器中的位址,使用 goto 叙述时,必须自己定义标记,定义方式如下 : n 标记名称 : ( 程序叙述 ) n其中标记名称是可以自己命名的 (只要不是C51的关键字即可) ,在后面加上一个冒号以声明它是标记,例如 :现代电子技术工程设计与实践7.2.6 C51程序语言的语句nredo: n ( 程序叙述 ) ;n goto redo; n程序就会不断执行标记 redo 到goto 叙述中间的程序叙述。虽然使用goto很方便,但是在程序码中加入太多的goto会破坏程序整体的结构,降低程序的可读性以及增加日后程序修改维护的难度,而且

51、在大多数情形下,goto 叙述是可以被其它流程控制方式所取代。 现代电子技术工程设计与实践7.2.7 函数和指针数组n1. 函数nC语言程序的架构由函数组成,其中又以函数 main()最为重要。理论上可以把所有程序叙述全部放在 main()函数中,但是这样会使程序看起来没有条理,而且有许多程序叙述会重复,所以当程序愈写愈大时,必须试着将负责处理各种机能的程序叙述分别写成一个个不同的函数,这样一来,不但程序代码变的清楚明了,而且许多重复的地方,都可以通过调用相同的函数来完成。 现代电子技术工程设计与实践7.2.7 函数和指针数组n(1)基本函数的建构 n函数主体在程序中存放的位置,可以在程序中的

52、任何地方,而函数之间也可以互相调用。但不可在一个函数中包含另一个函数,通常在定义函数之前,会在程序的最前端,定义函数的原型 (function prototype),方法如下:n函数返回值数据类型 函数名称 ( 数据类型 传递参数 1, 数据类型 传递参数 2 ); n定义函数原型的用意在于让编译器知道程序有哪些函数,这样不论函数放在程序的那个地方,最后一定能顺利连结。另外,定义函数原型就像写作文之前先将大纲列出来一样,能让别人更容易了解程序架构与内容。定义完原型后,就可以在程序中的任何地方撰写函数主体。定义完原型后,就可以在程序中的任何地方撰写函数主体。函数主体如下:现代电子技术工程设计与实

53、践7.2.7 函数和指针数组n函数返回值数据类型 函数名称 (数据类型 传递参数 1, 数据类型 传递参数 2); n n ( 函数中的程序语句 ) n . n . nreturn 返回值 ; n n这里无论是函数返回数据类型,函数名称及传递参数数量和其数据类型等等,都必须和函数的原型吻合,否则会发生连结的错误,在函数的最后使用 return语句将数值返回,当想要调用函数的时后,可以用以下的格式调用:函数名称 (传递参数1,传递参数 2) n所传递参数的数量和型态都必须和想调用的函数相同,否则会出错。 现代电子技术工程设计与实践7.2.7 函数和指针数组n例:函数应用-延迟子程序范例 n805

54、1单片机程序中常常会用到时间延迟子程序。建立一个时间为 10ms 延迟子程序,并利用传递参数100,做1秒钟的时间延迟(1sec=10010ms) 。nvoid delay10ms(int count) n n int i,j; n for(i=0;icount;i+) / 通过引数 count 控制外循环数 n for(j=0;j1940;j+); n n main() n n delay10ms(100); n 现代电子技术工程设计与实践7.2.7 函数和指针数组n(2)C51的特殊函数 nC51为了配合8051程序的需求,衍生出一些具有特殊作用的函数,例如中断函数 (interrupt

55、function)。 n所谓中断函数就是在执行程序时,因为某件事情发生 ( 如计时器时间到了,或者触动开关 等等)中断函数,去处理这种状况所定义的函数。在汇编语言中,处理中断的方法是将处理中断的程序码放置于特定的存储器局部,触发中断时就会自动跳过去执行,但在C51中可以让编译器帮助完成这项工作。在C51中定义中断函数的方法如下:函数定义 interrupt 中断编号 using 暂存器组。n中断编号是指明要处理何种中断,在C51中其值可以是031,不过常用的是05,其作用如下表7-11 所示:现代电子技术工程设计与实践7.2.7 函数和指针数组n表 7-11 中断编号与中断向量地址n 中断编号

56、 中断源名称 中断向量地址 0 外部中断 0 0 x03 0 x03 1 计时计数 0 0 x0B 0 x0B 2 外部中断 1 0 x13 0 x13 3 计时计数器 1 0 x1B 0 x1B 4 串行通信0 x23 0 x23 5 计时计数 1 0 x2B 0 x2B 现代电子技术工程设计与实践7.2.7 函数和指针数组nusing后面接的是使用寄存器编号,其值为03,可以省略,如下面的例子将会定义外部中断0并使用第0组寄存器的中断函数。 nvoid Int_0() interrupt 0 using 0 n n ( 中断常式 ) n 现代电子技术工程设计与实践7.2.7 函数和指针数组

57、n(3)C51的函数库 nC51即是程序库(run-time library)提供超过100个预设的函数和宏指令, 8051程序设计者可直接取用,这对单片机系统程序设计,会有很大的帮助。例如数据的转换、字串与缓冲区的操作,数学函数与浮点数的运算等相关的资料,KeilVision2 都有提供,读者可自行查询参考。参考文件的取得可以直接在Vision2 中开启 Books Windows 中的C51 Users Guide与C51 Library Functions文件手册。现代电子技术工程设计与实践7.2.7 函数和指针数组n2. 指针 nC语言有一种特殊的数据类型,称为指针(Pointer),

58、专门用来存放存储器位址。这项功能跟 8051 汇编语言的间接寻址存取存储器的观念类似。假设一个变量 ptr_a 资料,存放在另一个变量 var_a 的存储器地址,称为“变量 ptr_a 指向变量 var_a 的指针”,或“ptr_a 为一指针的变量”。当定义变量 ptr_a 为一个指针时,必须在变量名称前以星号*标示,它的定义方式如下:n数据类型 * 指针 变量名称 (= 初始值 ); 现代电子技术工程设计与实践7.2.7 函数和指针数组n3. 数组与指针 n在高级语言中,数组 (Array)可用来处理一长串连续的变量数据。使用数组处理大量的变量数据,除了可免除每一变量必须逐一定义的麻烦外,变

59、量资料的存取程序更便捷。在单片机系统中,数组是一段连续的存储空间。因此使用指针来存取数组资料,是一种常用的方式。它的定义如下:n变量型 态存储器类型数组 名称元素个数= 初始值 ,; 现代电子技术工程设计与实践7.2.7 函数和指针数组n其中元素各数必须是一个常数,初始值和初始值之间必须用逗号来分隔,假如不指定元素个数,编译器会根据在后面加入了多少个初始值,来决定数组长度,若连初始值都没写,则编译器会显示错误信息。另外,数组名称被赋予的意义是一个指针,它指向数组开始处的存储器地址。 n如果要存取数组中第一个元素,只要用 *Array 即可,第二个即为 *(Array+1) 第 n 个就是 *(

60、Array+n-1),为了简化写法,C语言中特别定义 Arrayn 为 *(Array+n),存取数组Array中第n个元素就可简写成Arrayn-1 ,如此一来,配合程序循环的使用,就可以轻松地处理大量连续的数据。 n应用范例:观察指针与数组 现代电子技术工程设计与实践7.2.7 函数和指针数组n将数组数据结合指针功能,利用 Keil Vision 观察如何利用指针存取数组资料。程序如下: n #include n void main() n n int i; n char array5=0 xc1,0 xc2,0 xc3,0 xc4,0 xc5; n char *ptr_a; n ptr_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论