单片机原理及应用教程(c语言版)第4章 单片机c语言及程序设计

上传人:e****s 文档编号:243436837 上传时间:2024-09-23 格式:PPT 页数:144 大小:977KB
返回 下载 相关 举报
单片机原理及应用教程(c语言版)第4章 单片机c语言及程序设计_第1页
第1页 / 共144页
单片机原理及应用教程(c语言版)第4章 单片机c语言及程序设计_第2页
第2页 / 共144页
单片机原理及应用教程(c语言版)第4章 单片机c语言及程序设计_第3页
第3页 / 共144页
点击查看更多>>
资源描述
单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,单片机原理及应用教程,(,C,语言版),第,4,章 单片机,C,语言及程序设计,主 编:,周国运,中国水利水电出版社,第,4,章,MCS-51,单片机,C,语言及程序设计,4.1,单片机,C,语言概述,4.2 C51,数据类型及存储,4.3 C51,一般变量的定义,4.4 C51,特殊功能寄存器的定义,4.5 C51,位变量的定义,4.6 C51,指针与结构体的定义,4.7 C51,的输入,/,输出,4.8 C51,函数的定义,4.9 C51,与汇编语言混合编程,主要内容,第,4,章 单片机,C,语言及程序设计,本章主要讨论,C51,变量的定义和函数的定义。,本章内容的安排,认为读者已经学习过,C,语言,具有,C,语言的基本知识,因此,本章内容完全是结合单片机来讲解,也就是补充,C,语言在单片机方面的概念、数据定义和函数定义等。,通过本章学习,使读者能够比较顺利地编写,C51,程序。,4.1 C51,概述,主要内容,4.1.1 C,语言编程的优势,4.1.2 C51,与,ANSI C,的区别,4.1.3 C51,扩展的关键字,4.1 C,51,概述,学习单片机,C,语言的必要性,随着单片机性能的不断提高,,C,语言编译调试工具的不断完善,以及现在对单片机产品辅助功能的要求、对开发周期不断缩短的要求,使得,越来越多的单片机编程人员转向使用,C,语言,,因此有必要在单片机课程中讲授“单片机,C,语言”。,“,C51”,概念:,为了与,ANSI C,区别,,把“单片机,C,语言”称为“,C51”,,也称为“,Keil C”,。,4.1.1 C,语言编程的优势,在编程方面,使用,C51,较汇编语言有诸多优势:,1,)编程容易,2,)容易实现复杂的数值计算,3,)容易阅读与交流,4,)容易调试与维护,5,)容易实现模块化开发,6,)程序可移植性好,4.1.2 C,51,与,ANSI C,的区别,C51,与,ANSI C,的区别是因为,CPU,、存储器和外部设备的不同,以及不使用操作系统等引起的。,C51,是,MCS-51,单片机的,ANSI C,,单片机与,PC,机的差异,主要由,C51,编译器(如,Keil C,)处理,一些库函数的差异,也由编译器的开发着做了修改,.,因此,我们使用,C51,编程,如基本语法、数据结构、程序结构、程序组织等各个方面,与使用,ANSI C,的感觉基本上是一样的。,但是,,C51,与,ANSI C,之间是有差异的,从单片机应用编程的角度来看,主要有以下几个方面,。,4.1.2 C,语言与,ANSI,的区别,1,)变量,(一般变量),的定义问题,如字符型、整型、浮点型、各种数组、各种结构体等。,因单片机有,4,个存储空间、,7,个存储区,,在定义时,必须要指明变量存放的存储器空间、具体的区域,。,2,)特殊功能寄存器的使用问题,这是,ANSI C,中所没有的。,在,C51,中增加了两种“特殊功能寄存器数据类型”,使用之前,像一般变量一样,需要先定义再使用,。,4.1.2 C,语言与,ANSI,的区别,3,)位变量的定义问题,这也是,ANSI C,中所没有的,,在,C51,增加了两种“位数据类型”。,见节。,4,)指针的定义问题,指针的定义和变量一样,与,ANSI C,的差异是由复杂的存储器引发,,主要是指针指向的是哪个存储器空间、哪个存储区域,。见节。,5,)函数、中断服务函数的定义问题,在,C51,的函数定义中,,增加了多个函数属性以解决单片机的要求。如中断函数、函数重入、 切换工作寄存器组等。,见节。,4.1.2 C,语言与,ANSI,的区别,6,混合编程问题,一般,PC,机程序很少混合编程,但在单片机中常混合编程。见节。,7,库函数的差异问题,由于,PC,机与单片机的差异,相对于,ANSI C,的库函数来说,,C51,的库函数减少了一部分,(如显示、键盘、磁盘,文件系统等),,增加了一部分,(如循环移位、绝对地址访问等),,修改了一部分,(如,I/O,函数等)。,4.1.3 C,51,扩充的关键字,由于单片机在结构及编程上的特殊要求,,C51,有自己的特殊关键字,称之为,C51,扩充的关键字,,下面给出常用的,C51,扩充的关键字。,_at_bdatabit code,dataidata interruptpdata,reentrant sbitsfr,sfr16usingvolatilexdata,这些关键字在后面会陆续接触到,此处不作详细讲解。,4.2 C51,数据类型及存储,主要内容,4.2.1 C51,的数据类型,4.2.2 C51,数据的存储,4.2.1 C51,的数据类型,表,4-1 C51,数据类型、长度和数值范围,数据类型,表示方法,长 度,数 值 范 围,基,本,类,型,无符号字符型,unsigned char,1,字节,0,255,有符号字符型,signed char,1,字节,-,128,127,无符号整型,unsigned int,2,字节,0,65535,有符号整型,signed int,2,字节,-,32768,32767,无符号长整型,unsigned long,4,字节,0,4294967295,有符号长整型,signed long,4,字节,-,2147483648,2147483647,浮点型,float,4,字节,1.1755E,-,38,3.40E+38,扩,充,类,型,特殊功能,寄存器,sfr,sfr16,1,字节,2,字节,0,255,0,65535,位类型,bit,、,sbit,1,位,0,或,1,4.2.1 C51,的数据类型,bit,、,sbit,数据类型转换与运算,1,),bit,、,sbit,到,char,类型转换,可以做强制类型转换。,如:,unsigned char d=5, d0=4, d1, d2, d3;,bitbb=1;,d=d+(char)bb)*8;/d=13,2,),bit,、,sbit,类型与,char,类型可直接作逻辑运算,如:,d1=d0/d1=4,d2=d0|bb;/d2=5,d3=d0bb;,/d3=5.,异或操作,注意:,bit,、,sbit,类型与,char,类型不能直接作算数运算,4.2.2 C51,数据的存储,MCS-51,单片机只有,bit,和,unsigned char,两种数据类型支持机器指令,,而其它类型的数据都需要转换成,bit,或,unsigned char,型进行存储。,为了减少单片机的存储空间和提高运行速度,要尽可能地使用,unsigned char,型数据。,一、位变量的存储,bit,和,sbit,型位变量,直接存于,RAM,的位寻址空间,包括低,128,位和特殊功能寄存器位。,4.2.2 C51,数据的存储,二、字符变量的存储,字符变量,(,char,),:,无论是,unsigned char,数据还是,signed char,数据,均为,1,个字节,能够被直接存储在,RAM,中,可以存储在,0,0x7f,区域,也可以存储在,0x80,0xff,区域,与变量的定义有关。,unsigned char,数:,可直接被,MSC-51,接受,signed char,数据:,用补码表示。,需要,额外的操作来,测试、处理符号位,,使用的是两种库函数,代码量大,运算速度降低。,4.2.2 C51,数据的存储,三、整型变量的存储,整型变量,(,int,),:,不管是,unsigned int,数据还是,signed int,数据,均为,2,个字节,其,存储方法是高位字节保存在低地址,(在前面),,低位字节保存在高地址,(在后面) 。,例如,,整型变量的值为,0x1234,,在内存中的存放如右图所示。,signed int,数据用补码表示。,地址,低,高,:,:,12,34,:,:,4.2.2 C51,数据的存储,四、长,整型变量的存储,长整型变量(,long,)为,4,个字节,其存储方法与整型数据一样,是,最高位字节保存的地址最低,(在最前面),,最低位字节保存的地址最高,(在最后面)。,如长整型变量的值为,0x12345678,,在内存中的存放方法如右图所示。不管是,unsigned long,数据还是,signed long,数据。,地址,低,高,:,:,12,34,56,78,:,:,4.2.2 C51,数据的存储,五、浮点,型变量的存储,浮点型变量,(,fload,)占,4,个字节,,用指数方式表示,,其具体格式与编译器有关。,对于,Keil C,,采用的是,IEEE-754,标准,,具有,24,位精度,尾数的最高位始终为,1,,因而不保存。,具体分布为:,1,位符号位,,8,位阶码位,,23,位尾数,如下表所示。,字节地址,偏移量,0,1,2,3,浮点数,内容,S,EEE,EEEE,E,MMM,MMMM,MMMM,MMMM,MMMM,MMMM,符号和阶码,尾数高位,尾数低位,4.2.2 C51,数据的存储,符号位,S,:,1,表示负数,,0,表示正数。,阶码:,用移码表示。如,实际阶码,-,126,用,1,表示,实际阶码,0,用,127,表示,,即实际阶码数加上,127,得到阶码的表达数,。,阶码数值范围:,-,126,+128,阶码表达为:,1,255,4.2.2 C51,数据的存储,例如浮点数,-,符号位为,1,,,的二进制数为,1100.1=1.,1001,E+0011,,,阶码数值为,3+127=130=,10000010,B,,,尾数为,1001,。因此得:,地址,低,高,:,:,C1,48,00,00,:,:,1,10000010,1001,0000000000000000000,= 0xC1480000,尾数部分,符,号,位,阶码部分,4.3 C51,一般变量的定义,主要内容,4.3.1 C51,变量的定义,4.3.2 C51,变量的存储类型,4.3.3 C51,变量的存储区,4.3.4 C51,变量定义举例,4.3.5 C51,变量的存储模式,4.3.6 C51,变量的绝对定位,4.3.7 C51,设备变量的定义,4.3.1 C51,变量的定义格式,C51,变量定义的一般格式为:,存储类型,数据类型,存储区,变量名,1=,初值, ,变量名,2=,初值, ,或,存储类型,存储区,数据类型,变量名,1=,初值, ,变量名,2=,初值, ,可见变量,(非位变量),的定义由,4,部分组成,,即在变量定义时,指定变量的,4,种属性。,数据类型:,在前面的中已经叙述过,对于变量名也无须多说,,下面主要解释“存储类型”和“存储区”等概念,。,4.3.2 C51,变量的存储类型,存储类型这个属性我们仍沿用,ANSI C,的说法,,尽量不改变原来的含义。,按照,ANSI C,,,C,语言的变量有,4,种存储类型,:,动态存储(,auto,),静态存储(,static,),全局存储(,extern,),寄存器存储(,register,),4.3.2 C51,变量的存储类型,一、动态存储,动态(存储)变量:,用,auto,定义的为动态变量,也叫自动变量,。,作用范围:,在定义它的函数内或复合语句内部,当定义它的函数或复合语句执行时,,C51,才为变量分配存储空间,结束时所占用的存储空间释放。,定义变量时,,auto,可以省略,,或者说如果省略了存储类型项,则认为是动态变量。,动态变量一般分配使用寄存器或堆栈,。,4.3.2 C51,变量的存储类型,二、静态存储,静态(存储)变量:,用,static,定义的为静态变量,。分为内部静态和外部静态变量。,内部静态变量:,在函数体内定义的为内部静态变量,。在函数内可以任意使用和修改,函数运行结束后会一直存在,但在函数外不可见,即在函数体外得到保护。,外部静态变量:,在函数体外部定义的为外部静态变量,。在定义的文件内可以任意使用和修改,外部静态变量会一直存在,但在文件外不可见,即在文件外得到保护。,4.3.2 C51,变量的存储类型,三、外部存储,外部(存储)变量:,用,extern,声明,的变量为外部变量,,是在其它文件定义过的全局变量。用,extern,声明后,便可以在所声明的文件中使用。,需要注意的是:,在定义变量时,即便是全局变量,也不能使用,extern,修饰,。,4.3.2 C51,变量的存储类型,四、寄存器存储,寄存器(存储)变量:,用,register,定义的变量为寄存器变量,。,寄存器变量存放在,CPU,的寄存器中,,这种变量处理速度快,但数目少。,C51,中的寄存器变量:,C51,的编译器在编译时,能够自动识别程序中使用,频率高的变量,,并将其,安排为寄存器变量,,用户不用专门声明。,4.3.3 C51,变量的存储区,变量的存储区属性是单片机扩展的概念,,非常重要,,它涉及到,7,个新的关键字,。,MCS-51,单片机有四个存储空间,,分成三类,它们是片内数据存储空间、片外数据存储空间和程序存储空间。,MCS-51,单片机有更多的存储区域:,由于片内数据存储器和片外数据存储器又分成不同的区域,所以,单片机的变量有更多的存储区域,。,在定义变量时,必须明确指出将其存放在哪个区域,。,4.3.3 C51,变量的存储区域,表,4-2 C51,存储区属性与存储空间的对应关系,关键字,对应的存储空间及范围,data,片内,RAM,,直接寻址,低,128,字节,bdata,片内,RAM,,位寻址区,0x20,0x2f,,可字节访问,idata,片内,RAM,,间接寻址,,256,字节,与,Ri,对应,pdata,片外,RAM,,分页寻址的,256,字节,(P2,不变,),,,P2,改变可寻址,64KB,全空间,与,MOVX Ri,对应,xdata,片外,RAM,,,64KB,全空间,code,ROM,空间,,64KB,全空间,sfr,区,特殊功能寄存器区,地址,0x80,0xff,,,128,字节,直接寻址。不能够定义一般数据类型的变量,4.3.3 C51,变量的存储区域,图,4-6 MCS-51,单片机存储区分布示意图,64KB,片外,RAM,80,H,00H,7F,H,特殊功能,寄存器区,sfr,区,bdata,区,idata,区,data,区,256B,片内,RAM,pdata,区,256B,xdata,区,64KB,Flash ROM,code,区,FFH,0000H,FFFF,00FFH,0100H,128B,位寻址区,16B, 128,位,4.3.4 C51,变量定义举例,1,)定义存储在,data,区域,的,动态,的,unsigned char,时、分、秒变量:,auto,unsigned char,data,hou=0, min=0, sec=0;,2,)定义存储在,data,区域,的,静态,的,unsigned char,扫描码变量:,static,unsigned char,data,scan=0xfe;,3),定义存储在,data,区域,的,静态,unsigned int,变量,dd,static,unsigned int,data,dd;,4,)定义存储在,bdata,区域,的,动态,的,unsigned char,标识操作的变量:,auto,unsigned char,bdata,operate, operate1;,/,定义标识操作的可位寻址的变量,4.3.4 C51,变量定义举例,5,)定义存储在,idata,区域,的,动态,的,unsigned char,、,长度为,20,的,临时,数组,temp,:,auto,unsigned char,idata,temp,20,;,6,)定义在,pdata,区域,的,动态,的有符号,int,、,长度为,30,的数组,send_data,:,int,pdata,send_data,30,; /,存放发送数据,4.3.4 C51,变量定义举例,7,)定义存储在,xdata,区域,的,动态,的,unsigned int,、长度为,50,的数组,receiv_buf,:,unsigned int,xdata,receiv_buf50;,/,定义存放接受数据的数组,8,)定义存储在,code,区域,的,unsigned char,、长度为,10,的数组,dis_code,:,unsigned char,code,dis_code = 0x3f, 0x06,0x5b, 0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f;,/,定义共阴极数码管段码数组,4.3.5 C51,变量的存储模式,存储模式:,如果在定义变量时缺省了存储区属性,则编译器会自动选择默认的存储区域,,也就是存储模式,。,变量的存储模式决定于程序(或函数)的编译模式,。,编译模式分为三种:,小模式(,small,)、紧凑模式(,compact,)和大模式(,large,)。编译模式由编译控制命令决定。,存储模式(编译模式)决定了变量的默认存储区域和参数的传递方法,。,4.3.5 C51,变量的存储模式,一、,small,模式,在,small,模式下,变量的默认存储区域是“,data”,、“,idata”,,即未指出存储区域的变量保存到片内数据存储器中,并且,堆栈也安排在该区域中,。,small,模式的特点:,存储容量小,但速度快。,在,small,模式下参数的传递:,通过寄存器、堆栈或片内数据存储区完成的。,4.3.5 C51,变量的存储模式,二、,compact,模式,在,compact,模式下,变量的默认存储区域是“,pdata”,,即未指出存储区域的变量保存到片外数据存储器的一页中,最大变量数为,256,字节,并且,堆栈也安排在该区域中,。,compact,模式的特点:,是存储容量较,small,模式大,速度较,small,模式稍慢,但比,large,模式要快。,在,compact,模式下参数的传递:,通过片外数据区的一个固定页完成的。,4.3.5 C51,变量的存储模式,三、,large,模式,在,large,模式下,变量的默认存储区域是“,xdata”,,即未指出存储区域的变量保存到片外数据存储器,最大变量数可达,64KB,,并且,堆栈也安排在该区域中,。,large,模式的特点:,存储容量大,速度慢。,large,模式下参数的传递方式:,参数的传递也是通过片外数据存储器完成的。,4.3.5 C51,变量的存储模式,C51,支持混合模式:,即可以对函数设置编译模式,所以在,large,模式下,可以对某些函数设置为,compact,模式或,small,模式,从而提高运行速度。,默认编译模式:,如果文件或函数未指明编译模式,则编译器按,small,模式处理,。,编译模式控制命令:,“,#pragma small(,或,compact,、,large)”,应放在文件的开始。,4.3.6 C51,变量的绝对定位,C51,有三种方式可以对变量,(,I/O,端口),绝对定位:,绝对定位关键字,_at_,、指针、库函数的绝对定位宏。对于后两种方式,在后面指针一节介绍。,C51,扩展的关键字,_at_,专门用于对变量作绝对定位,,,_at_,使用在变量的定义中,其格式为:,存储类型,数据类型,存储区,变量名,1,_at_,地址常数,,变量名,2,4.3.6 C51,变量的绝对定位,_,at,_,的使用方法举例,1,)定义存储在,idata,区域,中的,unsigned char,数组,cc,,且,绝对定位在,0x98,地址处:,unsignedchar,idata,cc10,_at_ 0x98,;,2,)定义端口在,xdata,区域,、,地址为,0x7fff,的,unsigned char,设备变量,ADC0809,:,unsignedchar,xdata,ADC0809,_at_ 0x7fff,;,3,)定义端口在,xdata,区域,、,地址为,0xbfff,的,unsigned char,设备变量,printer_port,:,unsigned char,xdata,printer_port,_at_ 0xbfff,;,4.3.6 C51,变量的绝对定位,对变量绝对定位的几点说明:,1,)绝对地址变量,在定义时不能初始化,,因此不能对,code,型变量绝对定位。,2,)绝对地址变量,只能够是全局变量,,不能在函数中对变量绝对定位。,3,),一次可以定义多个绝对定位的变量,4,)绝对地址变量主要用于定义在,xdata,区域的设备变量,,一般情况下不对变量作绝对定位。,5,)位变量不能使用,_at_,绝对定位,。,如:某实验板上数码管显示器的段数据端口地址为“,0xfeff”,;位控制字的端口地址为“,0xfdff”,。,4.3.7,设备变量的概念,C,语言的输入,/,输出,都是通过定义在,I/O,口的变量(字符型、位型)实现的。通过这些变量,将设备的数据、状态传递给单片机,单片机对数据、状态信息进行分析,再对设备做出相应控制。,这样的变量与设备相关联,为设备型变量,,与一般数据型变量有很大的区别,一般数据型变量访问的是存储器,不会对外部设备产生影响。,在设备型变量中,以三总线方式连接的设备型变量最复杂,初学者对其定义及操作过程往往感到不好理解而出错。为了加强对这类变量的理解,我们将其称为“设备变量”。因此,,“设备变量”的定义为,“以三总线方式连接的设备对应的变量为设备变量”,。,4.3.7 C51,设备,变量的概念,对设备变量的几点说明:,设备变量是通过设备端口获得数据和赋值的变量,,与一般数据型变量不同。,设备变量是无符号字符型变量,(因总线数据是,8,位、从设备的读取一般是无符号数)。,设备变量有确定的端口地址,(公式,4-2,中的地址常数,其值决定于电路中,P0,、,P2,口与设备的连接),,通过总线读写操作对设备进行数据输入,/,输出。, 对设备变量赋值,是单片机对设备写数据,单片机是输出;把设备变量的值赋给其它变量,是单片机从设备读取数据,单片机是输入。, 一个设备可以有多个意义不同的设备变量,,其数量决定于设备的特性(与设备的端口对应,见节)。,设备变量的定义使用“绝对定位”方式较好。,4.4 C51,特殊功能寄存器的定义,主要内容,4.4.1 8,位特殊功能寄存器的定义,4.4.2 16,位特殊功能寄存器的定义,4.4.1 8,位特殊功能寄存器的定义,特殊功能寄存器也是一种数据类型,8,位特殊功能寄存器定义的一般格式为:,sfr,特殊功能寄存器名 地址常数,地址常数范围:,0x80,0xff,。,特殊功能寄存器定义例子(可以参见、等文件):,sfrP0=0x80;/,定义,P0,寄存器,sfrP1=0x90;/,定义,P1,寄存器,sfrPSW=0xd0;/,定义,PSW,sfrIE=0xa8;/,定义,IE,4.4.2 16,位特殊功能寄存器的定义,16,位特殊功能寄存器定义的一般格式为:,sfr16,特殊功能寄存器名 地址常数,地址常数范围:,0x80,0xff,。,例如(可以参见、等文件):,sfr16 DPTR=0x82; /,含,DPL,和,DPH,sfr16 T2=0xcc; /,含,TL2,和,TH2,sfr16 RCAP2=0xca;,/,含,RCAP2L,和,RCAP2H,/,0xca,为,RCAP2L,的地址,4.4.2 16,位特殊功能寄存器的定义,几点说明:,1,)定义特殊功能寄存器中的地址必须在,0x80,0xff,范围内。,2,)定义特殊功能寄存器,必须放在函数外面作为全局变量。,3,)用,sfr,或,sfr16,每次只能定义一个特殊功能寄存器。,4,)用,sfr,或,sfr16,定义的是绝对定位的变量,(因为名字是与确定地址对应的),具有特定的意义,,在应用时不能像一般变量那样随便使用,。,4.5 C51,位变量的定义,主要内容,4.5.1 bit,型位变量的定义,4.5.2 sbit,型位变量的定义,4.5.1 bit,型位变量的定义,常说的位变量指的就是,bit,型位变量,一般位变量,。,C51,的,bit,型位变量定义的一般格式为:,存储类型, bit,位变量名,1=,初值,,位变量名,2=,初值, ,,,bit,位变量被保存在,RAM,中的位寻址区域,(字节地址为,0x20,0x2f,,,16,字节)。,例如:,bitflag_run,,,receive_bit=0,;,static bitsend_bit,;,4.5.1 bit,型位变量的定义,两点说明:,1,)位变量,不能定义指针,,,不能定义数组,;,2,),bit,型位变量与其它变量一样,,可以作为函数的形参,,也可以作为,函数的返回值,,即函数的类型可以是位型的。,4.5.2 sbit,型位变量的定义,对于能够,按位寻址,的特殊功能寄存器、定义在,位寻址区域的变量,(字节型、整型、长整型),,可以对其各位用,sbit,定义位变量,,称为特殊位变量。,为了明确起见,分开讨论,按位寻址的特殊功能寄存器中位变量的定义,和定义在位寻址区域变量中位变量的定义。,4.5.2 sbit,型位变量的定义,一、特殊功能寄存器中位变量定义,能够按位寻址的,特殊功能寄存器中位变量定义的一般格式为:,sbit,位变量名 位地址表达式,这里的位地址表达式有三种形式:,直接位地址,特殊功能寄存器名带位号,字节地址带位号,4.5.2 sbit,型位变量的定义,1,、用直接位地址定义位变量,位变量的定义格式为:,sbit,位变量名 位地址常数,位地址常数范围为,0x80,0xff,,实际是定义特殊功能寄存器的位,。例如:,sbitP0_0=0x80;/,定义,P0,口的第,0,位,sbitP1_2=0x92; /,定义,P1,口的第,2,位,sbitRS0=0xd3; /,定义,PSW,的第,3,位,sbitET0=0xa9; /,定义,IE,的第,1,位,4.5.2 sbit,型位变量的定义,2,、特殊功能寄存器名带位号定义,位变量的定义格式为:,sbit,位变量名 特殊功能寄存器名,位号常数,这里的位号常数为,0,7,。例如:,sbitP0_3=P0,3; /,定义,P0,口的第,3,位,sbitP1_4=P1,4; /,定义,P1,口的第,4,位,sbitOV=PSW,2; /,定义,PSW,的第,2,位,sbitES=IE,4; /,定义,IE,的第,4,位,4.5.2 sbit,型位变量的定义,3,、寄存器地址带位号定义位变量,位变量的定义格式为:,sbit,位变量名 特殊功能寄存器地址,位号常数,这里的位号常数同上,为,0,7,。例如:,sbitP0_6=0x80,6; /,定义,P0,口的第,6,位,sbitP1_7=0x90,7; /,定义,P1,口的第,7,位,sbitAC=0xd0,6; /,定义,PSW,的第,6,位,sbitEA=0xa8,7;/,定义,IE,的第,7,位,还可以用“逻辑或”和“加”运算:,sbitP0_6=0x80,|,6;,sbitP0_6=0x80,+,6;,4.5.2 sbit,型位变量的定义,4,、几点说明,1,)用,sbit,定义的位变量,必须能够按位操作,,而不能够对无位操作功能的位定义位变量。,2,)用,sbit,定义位变量,必须放在函数外面作为全局位变量,,而不能在函数内部定义。,3,)用,sbit,每次只能定义一个位变量,。,4,)对其它模块定义的位变量,(,bit,型或,sbit,型),的引用声明,,使用,bit,。,5,)用,sbit,定义的是一种绝对定位的位变量,(因为名字是与确定位地址对应的),具有特定的意义,在应用时不能像,bit,型位变量那样随便使用。,4.5.2 sbit,型位变量的定义,二、,位寻址区变量的,位定义,对,bdata,型变量(字节型、整型、长整型) ,被保存在,RAM,中的位寻址区,因此,可以对,bdata,型变量各位作位变量定义,。,这样,既可以对,bdata,型变量作字节(或整型、长整型)操作,也可以作位操作。,bdata,型变量的位定义格式:,sbit,位变量名 ,bdata,型变量名,位号常数,4.5.2 sbit,型位变量的定义,bdata,型变量为在此之前应该是定义过的,,位号常数可以是,0,7,(,8,位字节变量),或,0,15,(,16,位整型变量),或,0,31,(,32,位字长整型变量)。例如:,unsignedchar bdataoperate;,对,operate,的低,4,位作位变量定义:,sbit flag_key=operate,0; /,键盘标志位,sbit flag_dis=operate,1; /,显示标志位,sbit flag_mus=operate,2; /,音乐标志位,sbit flag_run=operate,3; /,运行标志位,4.6 C51,指针与结构体的定义,主要内容,4.6.1,通用指针,4.6.2,存储器专用指针,4.6.3,指针变换,4.6.4 C51,指针应用,4.6.5 C51,结构体的定义,指针概念:,是以地址方式直接访问计算机存储器的数据类型。,4.6 C51,指针的定义,由于,MCS-51,单片机有三种不同类型的存储空间,并且还有不同的存储区域,,因此,C51,指针的内容更丰富。,指针除了具有像变量的四种属性(存储类型、数据类型、存储区、变量名)外,,按存储区,将指针分为通用指针和不同存储区域的专用指针。,对于结构体变量的定义,实质上与一般变量定义是一样的。,4.6.1,通用指针,所谓通用指针,就是通过该类指针可以访问所有的存储空间,。,在,C51,库函数中通常使用这种指针来访问。,通用指针用,3,个字节来表示:,第一个字节:表示指针,所指向的存储空间,第二个字节:为指针,地址的高字节,第三个字节:为指针,地址的低字节,4.6.1,通用指针,通用指针的定义与一般,C,语言指针的定义相同,其格式为:,存储类型,数据类型 *指针名,1,,*指针名,2 ,,,(公式,4-8,),例如:,unsigned char *cpt;,int *dpt;,long *lpt;,static char *ccpt;,通用指针的特点:,定义简单,访问所有空间,访问速度慢,4.6.2,存储器专用指针,所谓存储器专用指针,就是通过该类指针,只能够访问规定的存储空间区域,。,指针本身占用,1,个字节,(,data *,,,idata *,,,bdata *,,,pdata *,),或,2,个字节,(,xdata *,,,code *,),存储器专用指针的一般定义格式为:,存储类型,数据类型,指向存储区,*,指针存储区,指针名,1,*,指针存储区,指针名,2,(公式,4-9,),4.6.2,存储器专用指针,指向存储区:,是指针变量所指向的数据存储区域。不能够缺省,。,指针存储区:,是指针变量本身所存储的区域。,缺省时认为指针存储区在默认的存储区域,其默认存储区域决定于所设定的编译模式。,指向存储区和指针存储区,两者可以是同一个区域,但多数情况下不会是同一个区域,,如指向,code,区域的指针变量,绝不会存储到,code,区域。,4.6.2,存储器专用指针,存储器专用指针例子:,unsigned char,data,*,idata,cpt1,*,idata,cpt2;,signed int,idata,*,data,dpt1, *,data,dpt2;,unsigned char,pdata,*,pdata,ppt;,signed long,xdata,*,xdata,lpt;,unsigned char,code,*,data,ccpt;,褐色关键字,为指针所指向的存储区,蓝色关键字,为指针本身所存储的区域,4.6.2,存储器专用指针,说明:,1,)要区分指针变量指向的空间区域和指针变量本身所存储的区域,。,2,)定义时,,指针指向的存储区属性不能缺省,,缺省后就变成了通用指针。,3,)指针存储区属性可以缺省,,缺省时,指针存储在默认的存储区域。,4,)指针变量的长度与指向的存储区有关,,指向,data,、,idata,、,bdata,、,pdata,区域为单字节,指向,x,data,、,code,区域为双字节。,4.6.2,存储器专用指针,指针定义的简化格式,由于指针存储区属性可以缺省,为了简单起见,,存储器专用指针的定义格式可以写为:,存储类型,数据类型,指向存储区,*指针名,1,*,指针名,2,(公式,4-9,),以后我们基本上使用该公式定义指针,这样显得简单些,并且对初学者来说更容易理解。,4.6.2,存储器专用指针,存储器专用指针简化定义为:,unsigned char,data,*,cpt1,*,cpt2;,signed int,idata,*dpt1, *dpt2;,unsigned char,pdata,*ppt;,signed long,xdata,*lpt;,unsigned char,code,*ccpt;,上面所定义的指针虽然所指向的空间不同,但,指针变量本身都存储在默认的存储区域,。,4.6.3,指针变换,一、通用指针格式,由前面的讨论知,通用指针由,3,个字节组成,,第一个字节为指向的存储区域,后两个字节为指针地址,,,第一个字节的存储区域编码如表,4-3,所示,。,表,4-3,通用指针存储区域编码,存储区,idata,xdata,pdata,data,code,编 码,1,2,3,4,5,4.6.3,指针变换,二、指针转换,指针转换有两种途径,一种是显式的编程转换,另一种是隐式的自动转换,。,指针的编程转换:,(,1,)通用指针的第一字节,与专用指针的指向数据区属性对应,二者相互转换;(,2,)通用指针后两个字节的地址,与专用指针的值对应,二者相互转换。,指针的隐式自动转换:,由编译器在进行编译时自动完成。,4.6.4 C51,指针应用,指针在,PC,机上的,C,语言中应用很广泛。,在单片机中,由于不使用操作系统,指针的应用可以独立于变量,独立地指向所需要访问的存储空间位置。,本节通过例子来学习和认识,C51,指针的这种独立应用性。,下面介绍两种利用指针访问存储区的方法。也可以访问函数。,4.6.4 C51,指针应用,一、通过专用指针直接访问存储器,使用指针直接访问存储器对,PC,机是禁止的,但对于单片机来说使用时注意是可以的。,使用指针直接访问存储器方法:,先定义所需要的指针,给指针赋地址值;然后使用指针访问存储器,。例如:,unsigned char xdata *xcpt;,xcpt=0x2000;,*xcpt=123; /,给,0x2000,送数,xcpt+;*xcpt=234;,/,给,0x2001,送数,4.6.4 C51,指针应用,例,4-1,编写程序,将单片机片外数据存储器中地址从,0x1000,开始的,20,个字节数据,传送到片内数据存储器中地址从,0x30,开始的区域。用指针实现。,程序段如下:,unsigned char,data,i, *dcpt;,unsigned char,xdata,*xcpt;,dcpt=0x30;/,给指针赋地址,xcpt=0x1000;,for(i=0;i20;i+),*(dcpt+i)=*(xcpt+i); /,通过指针传送数据,4.6.4 C51,指针应用,例,4-2,在数字滤波中有一种叫做“中值滤波”技术,就是对采集的数据按照从大到小或者从小到大进行排序,然后取中间位置的数作为采样值。,试编写一函数,对存放在片内数据存储器中、地址从,point,开始的,num,个单元的数据,用冒泡法排序进行中值滤波,并把得到的中值数据返回。,中值滤波函数如下:,unsigned char median_filter,(,unsigned char data,*point, unsigned char data num,),unsigned char,data,*pp,,,i,,,j,,,n,,,temp,;,4.6.4 C51,指针应用,unsigned char,data,*pp,,,i,,,j,,,n,,,temp,;,num-;,for(i=0,;,inum,;,i+)/,外层循环,num,次,pp = point,;,/pp,指向开始地址,n=num,i,;,/n,为内层循环次数,for(j=0,;,jn,;,j+)/,内层循环,if(,*pp*(pp+1,)/,从大到小排, temp=,*pp,;,*pp=*(pp+1),;,*,(pp+1,)= temp,;,pp+,;,/,指针指向下一个数, ,pp,=,point,+num/2,;,/,指向位于中间的数,return,*pp,;,/,返回得到的中值,4.6.4 C51,指针应用,二、通过指针定义的宏访问指定的地址,(端口或存储单元),1,、访问指定地址的宏的定义,用指针定义的、访问指定的地址的宏,(,变量,),的格式,:,#define,宏,(,变量,),名,(*(volatile,数据类型 存储区*,),地址,),(公式,4-10,),数据类型:,主要为无符号字符型、无符号整型、浮点型等普通数据类型;,存储区域:,可以使用,data,、,idata,、,bdata,、,pdata,、,xdata,和,code,存储区,共,6,种。,4.6.4 C51,指针应用,对公式,4-10,的理解,该定义的宏变量,与指定存储区、指定地址中、指定的数据类型的数据对应。,因为“*,x”,是定义,x,为指针变量,“*,(*x)”,为指针,x,指向单元的数据,即为变量;,“*,(*x)add”,中的,add,,为赋给指针变量,x,的地址值,因此“*,(*)add”,就是对应地址,add,中的变量。,因此,公式,4-10,是,定义了一个指定数据类型的宏变量,并且这个宏变量保存在指定的存储区、指定的地址中。,4.6.4 C51,指针应用,格式中的关键字“,volatile”,:,“,volatile”,是单片机中定义的,其含义为:,这种变量在程序执行中可被隐含地改变而编译器无法检测到,它会告知编译器不要做优化处理,使应用者能够得到正确的变量值。,volatile,的应用:,volatile,常用于定义寄存器,特别是状态寄存器、与端口对应的寄存器,因为这些寄存器的值不是程序员设置,而是单片机在运行中由,CPU,或外部设备设置的。,4.6.4 C51,指针应用,2,、,访问指定地址的宏变量的应用,虽然存储区属性共,6,种情况,但,该公式主要用于定义片外数据存储区的设备端口,,通过其定义的宏,能够非常方便地访问设备。例如:,#define Port_AD (*(unsigned char volatile,xdata*)0xfeff),/,定义地址为,0xfeff,的,A/D,设备变量,#define Port_DA (*(unsigned char volatile,xdata*)0xfdff),/,定义地址为,0xfdff,的,D/A,设备变量,#define Port_LED (*(unsigned char volatile,xdata*)0xfbff),/,定义地址为,0xfbff,的,LED,设备变量,4.6.4 C51,指针应用,三、通过指针定义的宏访问存储器,1,、访问存储器宏的定义,用指针定义的、访问存储器宏的格式:,#define,宏,(,数组,),名,(volatile,数据类型 存储区*,)0),(公式,4-11,),数据类型:,主要为无符号字符型、无符号整型、浮点型等普通数据类型;,存储区域:,可以使用,data,、,idata,、,bdata,、,pdata,、,xdata,和,code,存储区。,4.6.4 C51,指针应用,库函数中访问存储器宏的原型,C51,库函数提供了两组用指针定义的以绝对地址访问存储器的宏,其原型如下。,1,)按字节访问存储器的宏:,#define,CBYTE,(volatile unsigned char,code,*)0),#define,DBYTE,(volatile unsigned char,data,*)0),#define,PBYTE,(volatile unsigned char,pdata,*)0),#define,XBYTE,(volatile unsigned char,xdata,*)0),理解:,CBYTE,为指针名,,unsigned char,为指针数据类型,,code,为指针指向的区域,,0,为指针初始地址,4.6.4 C51,指针应用,2,)按整型双字节访问存储器的宏:,#define,CWORD,(volatile unsigned int,code,*)0),#define,DWORD,(volatile unsigned int,data,*)0),#define,PWORD,(volatile unsigned int,pdata,*)0),#define,XWORD,(volatile unsigned int,xdata,*)0),无,idata,型,,不能访问片内,RAM,高,128,字节区域(,0x80,0xff,),需要时可以自己定义。,这些宏定义原型放在文件中,,使用时需要用预处理命令把该头文件包含到文件中,形式为:,#include ,。,4.6.4 C51,指针应用,2,、使用宏访问存储器的方法,使用宏定义访问存储器的形式类似于数组,。,1,)按字节访问存储器宏的形式,宏,(,数组,),名,地址,=,字节数据,变量,=,宏,(,数组,),名,地址,即数组中的下标就是存储器的地址,,因此使用起来非常方便。例如:,DBYTE,0x30,=48; /,给片内,RAM 0x30,送数据,XBYTE,0x0002,=0x36;/,给片外,RAM,送数据,dis_buf0=CBYTE,TABLE+5,;,/,从,CODE,区读取,5,的显示代码,(,公式,4-12),4.6.4 C51,指针应用,2,)按整型数访问存储器宏的形式,宏,(,数组,),名,下标,=,整型数据,变量,=,宏,(,数组,),名,下标,由于整型数占两个字节,所以,下标与地址的关系为:地址,=,下标,2,。,由于数组中的下标与存储器的地址是倍数关系,使用时要注意。例如:,DWORD,0x20,=0x1234; /,给,0x40,、,0x41,单元送数,XWORD,0x0002,=0x5678;/,给,4,、,5,单元送数,通过指针定义的宏访问存储器这种方法,特别适用于访问,I/O,口。,(,公式,4-13),4.6.4 C51,指针应用,关于设备变量定义方式的比较与选用:,我们介绍了可以两种方法、四种方式定义设备变量。, 用“公式,4-2”,定义,绝对定位方法;,以下是用指针方法, 直接用指针定义, 如“例,4-1”,;, 用“公式,4-10”,定义,用访问指定端口的宏;, 用“公式,4-11”,定义,用访问存储器的宏。,这四种方式方式比较,,首推用“公式,4-2”,,绝对定位的方式,,其次用“公式,4-10”,,访问指定端口的宏的方式,。绝对定位的方式既简单又直接、清晰。,4.6.5 C51,结构体的定义,在单片机中,结构体的类型、结构体变量的定义,以及结构体使用的方法均与,PC,机一样。,下面通过例子,来示范,结构体类型,(与数据类型对应,如字符类型)的定义,然后用结构体类型定义出,结构体类型变量,(与变量对应,如字符型变量)。例如:,struct,birthday,/,定义,birthday,结构体类型,unsigned int,year,;/,定义成员,unsigned char,month,;,unsigned char,day,;,;,4.6.5 C51,结构体的定义,struct,birthday,data,li_birthday;,/,定义,birthday,类型的结构体变量,或者,data,struct,birthday,li_birthday;,static,struct,birthday,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 商业管理 > 商业计划


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!