版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、单片机八语言编程第1页,共137页,2022年,5月20日,2点34分,星期二第章单片机编程语言3.1 单片机编程语言概述3.2C51语言第2页,共137页,2022年,5月20日,2点34分,星期二3.1 单片机编程语言概述 51单片机的编程语言可以是汇编语言,也可以是高级语言,如由C语言演变而成的C51语言等。汇编语言产生的目标代码短,占用的存储空间小,执行速度快,能充分发挥单片机的硬件功能。但对于复杂的应用来讲使用汇编语言编程复杂,程序的可读性和可移植性不强。高级语言产生的目标代码长,占用的存储空间大,执行速度慢。但这是相对于汇编语言来讲的,其实C语言在大多数情况下的机器代码生成效率和汇
2、编语言相当,但可读性和可移植性却远远超过汇编语言,编程效率也大大高于汇编语言。 第3页,共137页,2022年,5月20日,2点34分,星期二3.1 单片机编程语言概述如果应用系统的存储空间比较小,且对实时性的要求很高,则应选用汇编语言编程。如果系统的存储空间比较大,且对实时性的要求不是很高,则C51语言是理想的编程语言。如果系统中有部分模块对实时性的要求很高,而其它模块对实时性的要求不是很高,则可以将两种语言结合,程序的主体部分使用C51编程,对实时性的要求高的模块用汇编语言编程,然后将汇编语言程序模块嵌入到C51语言程序当中。无论是高级语言还是汇编语言写的源程序都必须转换成目标程序(机器语
3、言),单片机才能执行。目前很多公司都将编辑器、汇编器、编译器、连接/定位器、符号转换程序做成了软件包,称为集成开发环境,如Keil uVision、Silicon Laboratories IDE等。第4页,共137页,2022年,5月20日,2点34分,星期二3.2C51语言早期的嵌入式系统的硬件的功能相对较弱,软件的规模相对较小,一般不超过8K。硬件工程师通常要同时进行软、硬件设计,所以一般采用汇编语言来进行程序设计。汇编程序的主要缺点是可读性和可维护性较差(特别当程序没有很好的进行注释时),代码的可重用性也比较低。目前的嵌入式系统硬件性能和软件的规模都有了很大的提高,一般采用C 语言进行
4、嵌入式系统程序设计。第5页,共137页,2022年,5月20日,2点34分,星期二使用C语言有以下的优点:C 语言具有结构化和模块化特点,便于阅读和维护。C 语言可移植性好,很多微控制器都支持C 编译器。功能化的代码能够很方便的从一个工程移植到另一个工程,从而减少了开发时间。C 语言编写的程序比汇编语言编写的程序更符合人们的思考习惯,开发者可以更专心的考虑算法,而不是考虑一些细节问题。这样可以减少编程错误出现的机率,从而提高开发效率,减少调试的时间。C 语言和微控制器是相对独立的,开发者不必知道处理器的具体内部结构和处理过程。当基于新型的微控制器开发程序时,可以很快上手,减少学习时间和程序开发
5、时间。第6页,共137页,2022年,5月20日,2点34分,星期二尽管C语言有以上的优点,但这并不是说汇编语言过时了。很多系统特别是实时嵌入式系统都是采用C 和汇编语言进行混合编程。对实时响应时间有很严格要求的应用系统,使用汇编语言成了开发者的唯一选择。C51语言是一种专门为8051单片机设计的高级语言C编译器,支持符合ANSI标准的C语言程序设计,同时针对8051单片机的自身特点做了一些特殊扩展。如果有C/C+语言的基础,C51语言能够很快掌握!第7页,共137页,2022年,5月20日,2点34分,星期二标识符、关键字标识符与关键字是C语言的基本组成部分。 标识符C语言中的标识符(ide
6、ntifier)是由一个或多个字符组成的序列,标识符可以作为变量名、函数名、数组名、类型名或文件名。标识符的第一个字符必须是字母或下划线,随后的字符必须是字母、数字或下划线。不同的编译器定义的标识符的有效长度不完全相同,但不会少于8个字符。为了程序移植方便,标识符的长度最好不超过8个字符。注意1:C语言区分字母的大小写,这和汇编语言是不同的。例如:var 和Var 是两个不同的标识符。注意2:C51编译器6.0以上版本支持标识符的有效长度为256,超过部分 忽略。 第8页,共137页,2022年,5月20日,2点34分,星期二 关键字关键字(key word)是一种具有固定名称和特定含义的标识
7、符,又称为保留字(reserved word)。这些标识符系统已经做了定义,有特定的功能。用户自定义的标识符不能和关键字同名。ANSI C语言定义了32个关键字 。第9页,共137页,2022年,5月20日,2点34分,星期二ANSI C关键字autodogotosignedunsignedbreakdoubleifsizeofvoidcaseelseintstaticvolatilecharenumlongstructwhileconstexternregisterswitchcontinuefloatreturntypedefdefaultforshortunion第10页,共137页,2
8、022年,5月20日,2点34分,星期二ANSI C关键字程序控制语句: break case continue default do else for goto if return switch volatile while存储种类说明: auto const extern register static数据类型说明: char double enum float int long short signed struct typedef union unsigned void运算符: sizeof第11页,共137页,2022年,5月20日,2点34分,星期二扩展关键字命令作用include
9、读外部文件,用指向包含文件目录中的文件,用“”指向当前目录中的文件define定义预处理宏或常数undef撤销预处理宏或常数定义if条件编译判断,若表达式为真,则开始条件编译分支ifdef条件编译判断,若命名已经定义,则开始条件编译分支ifndef条件编译判断,若命名未定义,则开始条件编译分支elif如果此前的if、ifdef、ifndef或elif未发生,并且表达式为真,则开始条件编译else如果此前的if、ifdef、ifndef或elif未发生,则开始条件编译endif结束此前的if、ifdef、ifndef、elif或else开始的条件编译分支。error输出用户定义的出错消息分支li
10、ne说明行号和可选的文件名,常用于出错消息中说明出错位置pragma说明编译命令,可以是命令行形式中的编译参数第12页,共137页,2022年,5月20日,2点34分,星期二C51关键字关键字用途说明_at_地址定位为变量进行存储器绝对空间地址定位alien函数特性声明用以声明与PL/M51兼容的函数bdata存储器类型声明可位寻址的8051内部数据存储器bit位变量声明声明位变量或位类型函数code存储器类型声明8051程序存储器空间compact存储器模式指定使用8051外部分页寻址数据存储空间data存储器类型声明直接寻址的8051内部数据存储器far存储器类型声明8051外部数据存储器
11、idata存储器类型声明间接寻址的8051内部数据存储器interrupt中断函数声明定义中断服务函数(未完,见下页)第13页,共137页,2022年,5月20日,2点34分,星期二C51关键字large存储器模式指定使用8051外部数据存储空间pdata存储器类型声明分页寻址的8051外部数据存储器_priority_多任务优先声明规定RTX51或RTX51 Tiny的任务优先级reentrant可重入函数声明定义可重入函数sbit位变量声明声明可位寻址的特殊功能位sfr特殊功能寄存器声明声明8位的特殊功能寄存器sfr16特殊功能寄存器声明声明16位的特殊功能寄存器small存储器模式指定使
12、用8051内部数据存储空间_task_任务声明定义实时多任务函数using寄存器组定义定义8051的工作寄存器组xdata存储器类型声明8051外部数据存储器第14页,共137页,2022年,5月20日,2点34分,星期二可重入函数可重入(reentrant)函数可以由多于一个任务并发使用,而不必担心数据错误。相反, 不可重入(non-reentrant)函数不能由超过一个任务所共享,除非能确保函数的互斥(或者使用信号量,或者在代码的关键部分禁用中断)。可重入函数可以在任意时刻被中断,稍后再继续运行,不会丢失数据。可重入函数要么使用本地变量,要么在使用全局变量时保护自己的数据 可重入函数: 不
13、为连续的调用持有静态数据。 不返回指向静态数据的指针;所有数据都由函数的调用者提供。 使用本地数据,或者通过制作全局数据的本地拷贝来保护全局数据。 绝不调用任何不可重入函数。 第15页,共137页,2022年,5月20日,2点34分,星期二在C51中,还使用了/* */和/符号进行注释。在/* */符号中的所有字符均表示注释说明。在/符号后的该行所有剩余文字均表示注释说明。注释的语句主要用来说明程序的功能,增加程序的可阅读性和可维护性,注释不影响程序的功能,也不会在编译后的程序中出现,即不影响运行文件的大小。第16页,共137页,2022年,5月20日,2点34分,星期二C语言的运算符符号意义
14、说明+加法运算或表示正数-减法运算或表示负数*乘法运算/除法运算当2个整数相除时,结果为整数,小数部分舍去。%模运算(求余)参加运算的均应为整数。+自增操作数据值加1-自减操作数据值减1第17页,共137页,2022年,5月20日,2点34分,星期二例:设x的初值为4 y=x+; 结果: x=5 ,y=4解释:x+先使用x的值,然后x的值再自增。y=+x; 结果:y=5, x=5解释:+xx的值先自增,然后再使用x的值。y=x-; 结果:y=4, x=3解释:x-先使用x的值,然后x的值再自减。y=-x; 结果:y=3, x=3解释:-xx的值先自减,然后再使用x的值。第18页,共137页,2
15、022年,5月20日,2点34分,星期二逻辑运算符符号含义大于=大于等于=等于小于=小于等于!=不等于&逻辑与,二个操作数均为真时,其值为真,否则为假|逻辑或,二个操作数均为假时,其值为假,否则为真!逻辑非,一元运算符,操作数为真,其值为假,操作数为假,其值为真注意:等于运算符用两个等号表示。一个等号表示赋值操作。 第19页,共137页,2022年,5月20日,2点34分,星期二位运算符符号含义&按位与|按位或按位异或按位取反。一元运算符右移操作。右边移出的位舍去,左边移入的位对无符号数补0;对有符号数补符号位第20页,共137页,2022年,5月20日,2点34分,星期二例:unsigned
16、 char x=0 x55 ; unsigned char y=0 x37 ; unsigned char z;z=x&y ; 则z=0 x15z=x|y ; 则z=0 x77z=xy ; 则z=0 x62z=x; 则z=0 xAAz=x1;则z=0 x2A第21页,共137页,2022年,5月20日,2点34分,星期二例:unsigned char x=0 x95 ; signed char y=0 x95 ; unsigned char z;z=x1;则z=0 x4Az=y1;则z=0 xCA第22页,共137页,2022年,5月20日,2点34分,星期二赋值运算符通常把=称为赋值运算符。
17、它是二元运算符,左边必须是个变量或数组元素(称为左值)右边是表达式(称为右值)。当左值和右值的数据类型不一致时,数据会自动进行数据类型转换。除了=之外,C语言还提供了10种复合赋值运算符,它们的功能是对左值和右值进行相关运算后,将运算结果赋给左值。复合赋值运算符如下所示:+= -= *= /= %= = &= = !=其中前5种是算术运算,后5种是位操作位算。第23页,共137页,2022年,5月20日,2点34分,星期二逗号运算符逗号运算符的作用是把几个表达式串在一起,成为逗号表达式。格式如下:表达式1,表达式2,表达式n注意:逗号运算符的运算顺序是从左至右,最右边表达式的值是整个逗号表达式
18、的值。例如:x=(y=5,z=y+3); 则该语句执行完成后y=5,z=8,x=8。第24页,共137页,2022年,5月20日,2点34分,星期二条件运算符条件运算符用?与:来替代简单的if-else条件语句。该运算符是三元运算符。格式如下:表达式1?表达式2:表达式3该运算符的功能是若表达式1为真,则执行表达式2,否则执行表达式3。例如:z=ab?3:5;由于ab的值为假,所以z=5。 第25页,共137页,2022年,5月20日,2点34分,星期二强制类型转换运算符在C语言程序的表达式或变量赋值运算中,有时会出现运算对象的数据类型不一致的情况,C语言允许对参与操作的标准数据类型进行隐式转
19、换和显示转换。隐式转换由系统自动按以下优先级进行:bit char int long floatsigned unsigned其中,箭头方向仅表示数据类型级别的高低,转换时由低向高进行,而不是数据转换时的顺序。例如:char变量和long变量进行运算,char变量无需先转换为int然后再转换成long,而是直接由char转换成long。第26页,共137页,2022年,5月20日,2点34分,星期二某些时候需要按用户的需要进行某些数据类型转换,可使用强制类型转换符进行显式转换。强制转换符的功能是将表达式结果转换成指定的数据类型,强制类型转换符的运算符号为()。格式为:(类型名)(表达式)例如:
20、 (int)(7.2/2) 将7.2/2的结果转换为整型,即3。第27页,共137页,2022年,5月20日,2点34分,星期二sizeof运算符C语言中可以用sizeof运算符计算数据类型变量以及表达式的字节数。它的一般使用形式为:sizeof(表达式)或sizeof(数据类型)注意:sizeof是一种特殊的运算符,不是函数。实际上字节数的计算是在程序编译时完成的,而不是在程序执行的过程中才计算出来的。 第28页,共137页,2022年,5月20日,2点34分,星期二其它运算符* :指针运算符。作用是通过指针变量间接访问指针变量所指向的变量,对其进行数据存取操作。& :取地址运算符。作用是获
21、取变量所占用的存储单元的地址。 :下标运算符。作用是用来获取数组的指定单元。- :指向结构成员运算符。作用是用结构变量的指针来访问结构中的成员变量。. :结构成员运算符,作用是用结构变量来访问结构中的成员变量。 第29页,共137页,2022年,5月20日,2点34分,星期二运算优先级优先级符号含义运算对象个数结合方向1()圆括号自左向右 下标运算符-指向结构成员运算符.结构成员运算符2!逻辑非运算符单操作数自右向左按位取反操作符+自增运算符-自减运算符-负号运算符(类型)类型转换运算符*指针运算符&取地址运算符sizeof长度运算符第30页,共137页,2022年,5月20日,2点34分,星
22、期二优先级符号含义运算对象个数结合方向3*乘法运算符双操作符自左向右/除法运算符%求余运算符4+加法运算符双操作符自左向右-减法运算符5右移运算符6、=关系运算符双操作符自左向右7=等于运算符双操作符自左向右!=不等于运算符第31页,共137页,2022年,5月20日,2点34分,星期二优先级符号含义运算对象个数结合方向8&按位与运算符双操作符自左向右9按位异或运算符双操作符自左向右10|按位或运算符双操作符自左向右11&逻辑与运算符双操作符自左向右12|逻辑或运算符双操作符自左向右13?:条件运算符三操作符自右向左14=、+=、-=、*=、/=、%=、=、&=、=、|=赋值运算符双操作符自左
23、向右15,逗号运算符自左向右第32页,共137页,2022年,5月20日,2点34分,星期二数据类型C语言中的数据根据是否允许数据值在程序执行过程中发生变化,分为常量和变量。常量又称为标量,它的值在程序执行过程中不能改变。变量是一种在程序执行过程中,其值能不断变化的量。使用一个变量前必须进行定义。在C51中变量定义的格式如下: 存储种类 数据类型 存储器类型 变量名表;第33页,共137页,2022年,5月20日,2点34分,星期二基本数据类型C语言的基本数据类型有char、int、short、long、float和double。对C51编译器来说:short类型与int类型相同double类
24、型与float类型相同。第34页,共137页,2022年,5月20日,2点34分,星期二存储区域8051系列微处理器采用了哈佛体系结构,即程序存储区和数据存储区是分离的。8051系列微处理器提供了三种不同类型的存储区域(memory areas), 程序存储区(program memory)内部数据存储区(internal data memory)外部数据存储区(external data memory)这三种存储区域均从地址0开始编址,通过采用不同的寻址指令来解决地址重叠的问题。 第35页,共137页,2022年,5月20日,2点34分,星期二第36页,共137页,2022年,5月20日,2
25、点34分,星期二程序存储区(program memory)程序存储区,也称为CODE 区,常用来存放可执行代码。代码区的地址位数为16 位,即寻址空间可达64K。一般情况,程序存储区是只读的,除了保存可执行代码,还可用于保存各种常量值,查找表等固定的数据结构。第37页,共137页,2022年,5月20日,2点34分,星期二内部数据存储区(internal data memory)内部数据存储区(internal data memory),共256个字节。这部分主要是作为程序的数据段。该区域的前128 字节,称为DATA 区。该区可采用直接寻址方式来访问。DATA区也可通过用R0 和R1存放要操
26、作的数据地址,采用间接寻址来访问。该区域的后128个字节,即从地址80H 开始的内部数据存储区,用做特殊功能寄存器区(special function register memory),简称SFR。这些特殊功能寄存器用来控制计时器,计数器,串行I/O,I/O端口和外设的工作。只能直接寻址注意:特殊功能寄存器并未占用特殊功能寄存器区的所有地址单元,即特殊功能寄存器是离散分布。第38页,共137页,2022年,5月20日,2点34分,星期二内部数据存储区的DATA区又可以细分为三个子段:第一个子段包含四个寄存器组,每个寄存器组包含8个寄存器,四个寄存器组共32 个字节。可在任何时候通过修改PSW
27、寄存器的RS1 和RS0两个位标志来选择四组寄存器的任意一组作为当前工作寄存器组。第二个子段叫做位寻址段BDATA, 包括16 个字节,共128 位,每一位都可单独寻址。这16 个字节也可像数据段中其它字节一样按字节进行寻址。第三个子段为一般的数据存储器,仅能按字节寻址,共80个字节。第39页,共137页,2022年,5月20日,2点34分,星期二说明:某些系列的单片机(如8052) 有额外的128 字节的内部RAM, 同样位于从80H 开始的内部数据存储地址空间中,称为IDATA区。IDATA 区的地址和SFR的地址是重叠的,必须使用不同的寻址方式的指令来解决地址重叠问题。SFR区只能通过直
28、接寻址来访问, IDATA 区只能通过间接寻址来访问。第40页,共137页,2022年,5月20日,2点34分,星期二外部数据存储区(external data memory)外部数据存储区,也称为XDATA 区。XDATA区和CODE 区一样也采用16 位地址寻址,即寻址空间可达64KB。该区通常包括一些通用数据存储器或者一些需要通过总线接口访问的外围器件。访问外部数据区比访问内部数据区要慢,因为访问外部数据区时,必须先将要访问单元的16位地址装载到数据指针寄存器DPTR中,然后才能通过DPTR采用间接访问方式来访问该单元。第41页,共137页,2022年,5月20日,2点34分,星期二C5
29、1使用两种修饰符来表示外部数据区:xdata , pdataxdata 用来说明外部数据空间的所有64KB的地址空间。pdata 用来指向外部数据空间中的大小为一页(256字节)的数据存储空间。注意:某些新型的8051芯片有更大的XRAM(如16M的XRAM),一般用far类型来描述这些区域。可以分别用 far 和const far 来访问位于扩充RAM空间中的变量和扩充ROM空间中的常量。第42页,共137页,2022年,5月20日,2点34分,星期二注意:某些单片机芯片提供了片内的XRAM空间,这种空间也使用和传统的外部数据空间相同的指令来访问。这种XRAM空间,通常使用芯片专用的SFR配
30、置寄存器来使能,它和传统外部存储空间占用相同的地址空间。第43页,共137页,2022年,5月20日,2点34分,星期二存储器类型C51编译器允许8051微处理器使用各种类型的存储区域。可以在变量声明时使用存储器类型(memory types)来指定变量所希望占用的存储区域。内部数据区的访问速度比外部数据区的访问速度高很多。因而一般将经常使用的变量放在内部数据区,将大的或不常使用的变量放在外部数据区。第44页,共137页,2022年,5月20日,2点34分,星期二存储器类型存储区域大小对应的汇编语句描述code程序存储区64KBMOVC A,A+DPTR用来说明常量data直接寻址的内部数据存
31、储区128BMOV XX,#ADDR访问速度快idata间接寻址的内部数据区256BMOV XX,Rn可访问整个内部数据区域bdata位寻址的内部数据存储区16B(128b)可使用位寻址或字节寻址来访问这一区域xdata外部数据存储或64KBMOVX A,DPTR使用DPTR来访问外部数据存储器far扩充的RAM和ROM使用用户定义的专用例程或特殊芯片指令扩展命令pdata分页的外部数据存储区256BMOVX A,Rn利用R0,R1来访问分页的外部数据存储器第45页,共137页,2022年,5月20日,2点34分,星期二声明变量时可以说明变量的存储器类型,如下例所示:/内部数据区的字符型变量。
32、 char data var1;/在程序区中定义字串char code text = ENTER PARAMETER:; /外部数据区的长度为100的无符号长整形数组unsigned long xdata array100; /内部数据区,间接寻址方式访问的浮点变量float idata x,y,z; /外部数据区,分页存储区中的无符号整型变量unsigned int pdata dimension;/外部数据区,无符号字符类型的三维数组变量unsigned char xdata vector1044;/内部数据区,可位操作的字符变量char bdata flags; 说明:声明变量时存储区修
33、饰符和数据类型修饰符的位置可以互换,即char data x; 和 data char x; 是完全等效的。不过从兼容性考虑,建议使用前一种格式。第46页,共137页,2022年,5月20日,2点34分,星期二存储模式(memory models)如果在变量声明时未声明变量的存储器类型,则该变量的存储器类型,由程序的存储模式来决定。小模式(small model)紧凑模式(compact model)大模式(large model)注意:除非应用在特殊的场合,否则SMALL存储模式可以提供最快和最有效的代码。 第47页,共137页,2022年,5月20日,2点34分,星期二小模式(small
34、model)在小模式下,所有未声明存储器类型的变量,缺省驻留在内部数据区,即这种方式和用data进行显式说明一样。在这种存储模式下,变量的访问是最有效。但是所有的数据对象(包括堆栈)都必须放在内部数据存储区中。第48页,共137页,2022年,5月20日,2点34分,星期二紧凑模式(compact model)在紧凑模式下,所有未声明存储器类型的变量,缺省驻留在外部数据区的一个页上,即这种方式和用pdata显示说明一样。该模式利用R0和R1寄存器来进行间接寻址(R0, R1),此时最大可寻址256字节的存储区域。这种方式的存取速度比小模式慢,但比大模式快。在紧凑模式下使用了超过256字节的外部
35、数据存储区,那么访问单元的高8位地址(即页地址)必须由端口P2来输出。 开发人员必须在链接时为PDATA设置合适的开始地址。第49页,共137页,2022年,5月20日,2点34分,星期二大模式(large model)在大模式下,所有未声明存储器类型的变量,缺省时驻留在外部数据存储区,即和用xdata显示说明一样。此时最大可寻址64K字节的存储区域。此时使用数据指针寄存器(DPTR)来进行间接寻址。使用这种寻址方式效率低,生成的代码比小模式或紧凑模式下生成的代码要长。第50页,共137页,2022年,5月20日,2点34分,星期二动态存储分配对大多数应用来说,应尽可能在编译的时候确定所需要的
36、内存空间,但是对于有些需要使用动态结构,如树和链表的应用来说,这种方式就不再适用了,这时必须要使用动态存储分配。动态存储分配的实现:用户需要声明一个字节数组作为堆,数组的大小根据所需要动态内存的大小来决定。该数组的存储器类型必须被声明为XDATA,因为库函数使用具体指针来进行内存寻址。将指向堆首地址的指针和堆的大小传递给初始化函数init_mempool ,该函数将设置一些内部变量并对动态存储空间进行初始化。初始化工作完成后就可在程序中调用malloc 和free等C语言动态分配函数。第51页,共137页,2022年,5月20日,2点34分,星期二C51语言支持以下几种动态分配的函数:mall
37、oc:申请内存空间。调用时将所申请的内存空间的大小传递给函数,函数返回一个内存空间指针。如果操作失败,返回的指针值为NULL。calloc:计算并申请内存空间。调用时将所申请的变量数目和变量所占用的大小传递给函数,函数返回一个内存空间指针。如果操作失败,返回的指针值为NULL。realloc:重新分配内存空间。调用时将一个已经申请的内存指针和新的内存空间大小传递给函数,函数返回一个内存空间指针。如果操作失败,返回的指针值为NULL。free:释放内存空间。调用时将一个已经申请的内存指针传递给函数,函数将释放该内存空间。第52页,共137页,2022年,5月20日,2点34分,星期二C51中的特
38、殊数据类型C51中有几种ANSI C所没有的特殊数据类型,这些数据类型是和存储区域和存储器类型的概念密切相关的。 位变量可位寻址的对象特殊功能寄存器第53页,共137页,2022年,5月20日,2点34分,星期二位变量位变量(Bit Types)是指用一个二进制位表示的变量。位数据类型可以用来说明变量,参数表,函数返回值等。位数据变量声明和基本的数据类型声明一样。所有的位变量都存储在内部数据区的位寻址段中。因为该段只有16个字节长,所以在一个作用域内最多只能声明128个位变量。注意:由于位变量只能存储在内部数据存储区的位变量区内,因此只能使用data 和idata两种存储器类型修饰符,其它存储
39、器类型是非法的。第54页,共137页,2022年,5月20日,2点34分,星期二例3.15 位变量的使用static bit done_flag = 0; /* 位变量 */bit testfunc ( /*位函数返回类型 */bit flag1, /*位类型参数 */bit flag2 )return (0); /* 位类型返回值 */第55页,共137页,2022年,5月20日,2点34分,星期二位变量定义或声明时必须遵循以下规则:禁止中断的函数(#pragma disable)和显式定义寄存器组( using n )的函数不能返回位变量。函数在这种情况下返回位变量时,编译器将产生一个错误
40、信息。不能将指针声明为指向一个位类型。bit *ptr; /*非法语句 */不能声明位类型的数组bit ware 5; /*非法语句*/第56页,共137页,2022年,5月20日,2点34分,星期二可位寻址的对象可位寻址的对象(Bit-addressable Objects)是指可以同时用字节(字)寻址和位寻址方式进行访问的对象。只有当数据对象占据8051内部数据区的可位寻址区时,才是一个可位寻址对象。C51使用bdata存储器类型来声明可位寻址对象。例如:int bdata ibase;/*可位寻址的整形变量 */char bdata bary 4; /* 可位寻址的字符形数组 */注意:
41、声明为bdata存储器类型的变量必须为全局变量,不能是局部变量。由于bdata区为16个字节,因此可寻址对象所占存储空间不能大于16个字节。第57页,共137页,2022年,5月20日,2点34分,星期二上例中的ibase和bary 是可位寻址对象。因此,这些变量的位可以单独的访问和更改。可使用sbit关键字声明位变量来访问用bdata声明变量的指定位。sbit mybit0 = ibase 0; /* */sbit mybit15 = ibase 15; /* */sbit ary07 = bary0 7; /* bit 7 of bary0 */sbit ary37 = bary3 7;
42、/* bit 7 of bary3 */表达式中在符号后的表达式定义了位的位置。该表达式必须是一个常量。表达式的取值范围由变量声明中的基变量的数据类型来决定。对char 和unsigned char 类型,范围为0-7;对int, unsigned int, short, unsigned short,为0-15;对long 和unsigned long 为0-31。第58页,共137页,2022年,5月20日,2点34分,星期二下面的例子,采用了位寻址,字节寻址,字寻址来改变可位寻址对象的值。ary37 = 1;/* set bit 7 in bary3 */bary3 = a;/* Byt
43、e addressing */ibase = -1;/* Word addressing */mybit15 = 0; /* */可位寻址对象不仅可以是基本变量类型,还可以是结构或联合这样的复杂数据类型。第59页,共137页,2022年,5月20日,2点34分,星期二例3.16以复杂数据类型为基变量的可位寻址对象union lftfloat mf;long ml;bdata struct badchar m1;union lft u; tcp;sbit tcpf31 = tcp.u.ml 31; /* */sbit tcpm10 = tcp.m1 0;sbit tcpm17 = tcp.m1
44、7;第60页,共137页,2022年,5月20日,2点34分,星期二说明:位变量用基地址加位偏移来获取实际的物理地址。物理地址位地址0指向第一个字节的0位,8指向第2个字节的0位。8051中整型变量存储时是高字节在低地址(第1个字节),低字节在高地址(第2个字节)。即整型的0位在第2个字节的0位上,这个地址用sbit 来标识时是位置8。第61页,共137页,2022年,5月20日,2点34分,星期二例3.17 位变量与整型变量的对应关系bdata int iData;/位寻址变量必须为全局变量sbit bTest1=iData8;sbit bTest2=iData0;main()iData=0
45、;bTest1=1;/iData=1;iData=0;bTest2=1;/iData=256;第62页,共137页,2022年,5月20日,2点34分,星期二特殊功能寄存器8051系列的微控制器提供了一个独立的内存区,用来存放特殊功能寄存器(special function register, SFR)。SFR用来在程序中控制定时器,计数器,串行I/O,端口I/O操作,以及外设的操作。SFR驻留在地址0X80到0XFF空间,可按字节寻址或按字寻址,某些寄存器还可以按位寻址。8051系列微控制器中SFR的个数和类型是变化的。C51没有预先定义SFR的名字,而是提供了许多8051兼容芯片的包含文件
46、,这些文件对芯片的SFR进行了定义。CX51编译器用sfr,sfr16,sbit来进行SFR定义。第63页,共137页,2022年,5月20日,2点34分,星期二sfr:定义8位特殊功能寄存器sfr可以用来定义8051单片机的8位特殊功能寄存器。sfr占用一个字节内存单元,取值范围是0 255。SFR的声明和C变量的声明格式是一样的,只不过使用的修饰符不是char 或int 而是sfr。例如:sfr P0 = 0 x80; /* Port-0, address 80h */sfr P1 = 0 x90; /* Port-1, address 90h */sfr P2 = 0 xA0; /* P
47、ort-2, address 0A0h */sfr P3 = 0 xB0; /* Port-3, address 0B0h */P0,P1,P2,P3是sfr声明的特殊功能寄存器的名称。特殊功能寄存器名称是一个合法的C标识符。等号后的地址必须是数值常量,不允许使用带运算符的表达式。第64页,共137页,2022年,5月20日,2点34分,星期二sfr16:定义16位特殊功能寄存器8051芯片可以将两个8位SFR作为一个16位寄存器来访问。条件是这两个SFR必须处在相邻地址上,并且是低字节在高字节地址的前面。C51提供了sfr16数据类型来进行16位特殊功能寄存器的声明,声明时低字节地址被用来作
48、为sfr16的地址。例如:sfr16 T2 = 0 xCC; /* Timer 2: T2L 0CCh, T2H 0CDh */sfr16 RCAP2 = 0 xCA;/* RCAP2L 0CAh, RCAP2H 0CBh */在这个例子中,T2和RCAP2被声明为16位的特殊功能寄存器。sfr16声明和sfr声明的规则相同。第65页,共137页,2022年,5月20日,2点34分,星期二sbit:定义特殊功能位sbit用来访问SFR中的可寻址位和其它可位寻址对象的可寻址位。在8051应用中,经常需要对SFR中的可寻址位(特殊功能位)进行独立访问。可以用sbit数据类型来将SFR中的可寻址位声
49、明为特殊功能位。sbit EA = 0 xAF;上例中将EA定义为地址0XAF,对8051而言这是中断使能寄存器(IE)的中断许可位。第66页,共137页,2022年,5月20日,2点34分,星期二有三种方法来声明位地址:方法一: sfr_name int_constant,即SFR寄存器名整形常量。这种方法使用已经定义的sfr作为sbit的基地址。该SFR的地址必须能被8整除,符号后的表达式定义了可寻址位的位地址。位地址必须是0-7之间的数。sfr PSW = 0 xD0;/声明寄存器名sfr IE = 0 xA8;sbit OV = PSW 2;/声明特殊功能位sbit CY = PSW
50、7;sbit EA = IE 7;第67页,共137页,2022年,5月20日,2点34分,星期二方法二: int_constant int_constant,即整形常量整形常量。这种方法使用整形常数作为基地址。该地址必须可以被8整除,符号后的表达式定义了可寻址位的位地址。位地址必须是0-7之间的数。sbit OV = 0 xD0 2;sbit CY = 0 xD0 7;sbit EA = 0 xA8 7;方法三:int_constant用绝对位地址来声明sbit。sbit OV = 0 xD2;sbit CY = 0 xD7;sbit EA = 0 xAF;第68页,共137页,2022年,
51、5月20日,2点34分,星期二注意:sbit、bit和位域是三种不同的数据类型。使用sbit声明时,基对象必须可位寻址变量或者是可以位寻址的特殊功能寄存器。类型访问对象sbit可位寻址变量或可位寻址的特殊功能寄存器bit可位寻址区中的位,共128位位域将字节,整型,长整型的某几个位作为一个数据存储单元,进行独立访问。第69页,共137页,2022年,5月20日,2点34分,星期二绝对变量地址开发者有时候希望把变量存储在指定的地址单元中。可用 _at_ 关键词来将变量定位在一个绝对的内存地址单元。使用方法如下:数据类型 存储器类型 变量名 _at_ 变量所在绝对地址;在 _at_ 后面的绝对地址
52、必须符合存储器类型的物理边界限制,即不超过存储区域的最大可寻址范围,该地址必须为常数。第70页,共137页,2022年,5月20日,2点34分,星期二绝对变量定位遵循以下约束:绝对变量不能初始化。类型为bit的函数和变量不能用绝对地址定位。绝对变量必须是全局变量,不能是局部变量。第71页,共137页,2022年,5月20日,2点34分,星期二例3.18struct linkstruct link idata *next;char code *test;struct link list idata _at_ 0 x40; /* list at idata 0 x40 */char xdata t
53、ext256 _at_ 0 xE000; /* array at xdata 0 xE000 */int xdata i1 _at_ 0 x8000; /* i1 at xdata 0 x8000 */void main ( void ) list.next = (void *) 0;i1 = 0 x1234;text 0 = a;第72页,共137页,2022年,5月20日,2点34分,星期二有时需要在不同的模块之间调用变量,可使用下列的语句来在另一个源文件中访问上例中用 _at_修饰的变量。例3.19struct linkstruct link idata *next;char code
54、*test;extern struct link idata list;/* list at idata 0 x40 */extern char xdata text256; /* array at xdata 0 xE000 */extern int xdata i1; /* int at xdata 0 x8000 */第73页,共137页,2022年,5月20日,2点34分,星期二数组和指针数组是一个由同种类型的变量组成的集合,它保存在连续的存储区域中,第一个元素保存在最低地址中,最末一个元素保存在最高地址中。数组可以是一维的也可以是多维的。数组的定义方式如下:数据类型 数组名常量1常量
55、2常量n;这里的n是数组的维数。在定义时可以进行数组元素的初始化,初始化的值放在 中,每个元素值用逗号分开。如果是对多维数组进行初始化,还可以使用 将元素维的大小分成组。第74页,共137页,2022年,5月20日,2点34分,星期二例如:char a23=0,1,2,3,4,5;char a23=0,1,2,3,4,5;以上两条语句的功能是相同的,执行完成后各元素的值如下: (设初始地址为ADDR)地址对应元素对应值ADDRa000ADDR+1a011ADDR+2a022ADDR+3a103ADDR+4a114ADDR+5a125第75页,共137页,2022年,5月20日,2点34分,星期
56、二对于特殊的字符串数组,初始化时不仅可以采用每个元素分别赋值,还可以以字符串的形式赋值。如char array20=”hello world”;还可以使维数的大小为空,由初始化字串的长度决定数组的长度。如char array =”hello world”;上例中,数组array的长度为12个字节(字符串赋值时会增加一个0字符,作为字符串的结束标志)。第76页,共137页,2022年,5月20日,2点34分,星期二注意:C语言中的数组元素的下标总是从0开始的。多维数组在内存中保存时,下标1变化最慢,下标n变化最快。第77页,共137页,2022年,5月20日,2点34分,星期二指针与地址的概念程
57、序中的变量经过编译处理后都对应着内存中的一个地址。编译器根据变量的类型,为其分配不同大小的内存单元来存放变量的数据。所谓指针,就是某个变量所占用存储单元的首地址。用来存放指针值的变量称为指针变量。指针变量的定义格式如下:类型说明符 *指针变量名其中:“*”表示定义的是指针变量,类型说明符表示该指针变量指向的变量的类型。第78页,共137页,2022年,5月20日,2点34分,星期二C51的指针和标准C中的指针功能相同。但是由于8051体系结构的特殊性,C51提供了两种不同类型的指针:通用指针(Generic Pointers)具体指针(Memory-specific Pointers)。通用指
58、针的声明是和标准C中的指针声明是相同的,例如:char *s; /* 指向字符类型的指针 */int *numptr; /* 指向整型类型的指针*/long *state;/* 指向长整型类型的指针 */第79页,共137页,2022年,5月20日,2点34分,星期二通用指针总是占用三个字节。第1个字节保存存储器类型编码值,第2个字节保存地址的高字节,第3 个字节保存地址的低字节。许多C51的库例程使用这种指针类型,通用指针类型可以访问任何存储区域内变量。 存储器类型idata/data/bdataxdatapdatacode编码值0 x000 x010 xFE0 xFF第80页,共137页,
59、2022年,5月20日,2点34分,星期二具体指针是在声明时指定了存储器类型的指针,是指向特定存储区域中的指针变量。char data *str; /* ptr to string in data */int xdata *numtab; /* ptr to int(s) in xdata */long code *powtab; /* ptr to long(s) in code */具体指针不需要保存存储器类型字节。具体指针可以保存在一个字节(idata, data, bdata, pdata类型指针)或2个字节(code 和xdata类型指针)中。具体指针可以用来访问8051声明的存储区
60、内的变量。具体指针的效率高,但灵活性较差。 第81页,共137页,2022年,5月20日,2点34分,星期二指定具体指针本身的存储类型的定义例:char data * xdata ptr; /* ptr in xdata to data char */int xdata * data numtab; /* numtab in data to xdata int */long code * idata powtab; /* powtab in idata to code long */注意:本例中变量定义时使用了两个存储器类型,*前的存储器类型修饰指针指向的数据,*后的存储器类型修饰指针本身,即
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 眼镜店宿舍管理员工合同
- 高端制造业技术人才派遣
- 气象站铲车租赁协议
- 招投标文件袋环保密封条
- 创意产业激励政策
- 非税收入管理环境保护
- 农业公司卫生间使用准则
- 企业辞退员工制度
- 体育行业碳资产管理办法
- 企业内部规章制度范本
- 湖南省娄底市各县区乡镇行政村村庄村名居民村民委员会明细及行政区划代码
- 《灭火器维修》GA95-2015(全文)
- 慢性肾功能衰竭合并心力衰竭护理
- 机构入驻合作协议
- 三年级上册音乐课件-秧歌舞 |人教版 (共22张PPT)
- 《一年级语文上册口语交际专项复习》精编课件
- 《习作推荐一本书》教学课件完美版
- 水泥电线杆立杆技术方案
- 中职传感器教学设计
- 设备验证(IQ、OQ、PQ)文件模板
- 建筑工程团体意外伤害保险投保单
评论
0/150
提交评论