您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 第4章80C51单片机C语言程序设计
2020/2/251第4章80C51单片机C语言程序设计C51对标准C的扩展4.1C51的指针4.2C51的函数4.3C51与汇编程序的接口4.42020/2/2524.1C51对标准C的扩展4.1.1C51的数据类型数据是计算机操作的对象,包含常量和变量。C51扩展了ANSIC,以适应单片机的结构和特点。数据类型就是数据的格式,它决定数据的值域范围、占用存储单元的个数及能参与哪种运算。编写C51程序,先要确定数据类型、储存分区应尽可能采用无符号格式(unsigned)C51中,多字节数据采用“大端对齐”格式数据起始字节置于高地址端2020/2/253数据类型长度(位)取值范围字符型signedchar8-128~127unsignedchar80~255整型signedint16-32768~32767unsignedint160~65535长整型signedlong32-21474883648~21474883647unsignedlong320~4294967295浮点型float32±1.75494E-38~±3.402823E+38位型bit10,1sbit10,1访问SFRsfr80~255sfr16160~65535C51数据类型表2020/2/254bit定义位变量名字,编译器在位寻址区自动分配该位变量;Sbit声明位变量的名字和地址,地址是确定的(SFR区确定位、位寻址区变量的某确定位)。几点说明:unsignedcharbdataibase;sbitmybitf=ibase^0;sbitCY=0xD7;bitflag1=0;含义:赋值含义:声明2020/2/2554.1.2C51数据的存储分区存储器类型长度(位)对应单片机存储器bdata1片内RAM位寻址区,共128位。(亦能字节访问)data8直接寻址,共128字节。idata8间接寻址,共256字节。pdata8片外RAM分页间址,共256字节。(MOVX@Ri)xdata16间接寻址,共64k字节。(MOVX@DPTR)code16ROM间接寻址,共64k字节。(MOVCA,@A+DPTR)经常使用的变量应该置于片内RAM中,要用bdata、data、idata来定义不常使用的变量或规模较大的变量应该置于片外RAM中,要用pdata、xdata来定义bitbdataflags;//位变量flags定位在片内位寻址区chardatavar;//字符变量var定位在片内RAM区floatidatax,y;//实型变量x,y定位在片内间址RAM区unsignedcharpdataz;//无符号字符变量z定位在片外分页间址RAM区2020/2/257编译模式默认存储分区特点SMALLdata小模式。变量默认在片内RAM。空间小,速度块。COMPACTpdata紧凑模式。变量默认在片外RAM的页(256字节,页号由P2口决定)。LARGExdata大模式。变量默认在片外RAM的64KB范围。空间大,速度慢。编译模式默认的变量存储分区4.1.3C51的编译模式未对变量存储分区定义时,C51编译器采用默认存储分区。例如:charvar;//SMALL模式时,var定位于data存储区//COMPACT模式时,var定位于pdata存储区//LARGE模式时,var定位于xdata存储区2020/2/2594.1.4用_at_定义变量绝对地址用关键字“_at_”定义变量存放的首地址idatainty_at_0x30;//idata区域整型变量y的首地址为0x30例如:又如:xdatacharstring[20]_at_0x3000;//xdata中字符型数组string的首地址为0x3000注意,C51编程时不要轻易使用绝对地址定位变量。2020/2/25104.2C51的指针对于一个变量a,利用&a表示变量a的地址。则语句p=&a;表明把a的地址赋给了指针变量p,则“p指向了变量a”。可以用*P表示变量a指针变量的定义char*p;//定义指针变量Pp=30H;//指针变量赋值,30H为片内RAM地址x=*p;//30H单元的内容送给变量x*P指针变量数据变量4.2.1已定义数据存储分区的指针定义时就指定了所指向数据的存储分区。该指针占1个字节(idata*,data*,pdata*)或2个字节(code*,xdata*)示例:chardata*str;//指针str指向的char型数据存于data空间intxdata*num;//指针num指向的int型数据存于xdata空间基于存储器的指针长度比通用指针短,可以节省存储器空间,运行速度快,但它所指对象具有确定的存储器空间,兼容性不好。数据数据分区2020/2/2512定义时未指定所指向的数据的存储分区。也称通用指针。4.2.2未定义数据存储分区的指针---通用指针通用指针占3个字节第一字节存放该指针的默认存储器类型编码(见表)第二字节存放该指针的高位地址偏移量第三字节存放该指针的低位地址偏移量存储器类型编码存储器类型bdata/data/idataxdatapdatacode编码0x000x010xfe0xff2020/2/2513通用指针定义示例:char*xdatastrptr;//指针本身存于xdata空间,它指向char型数据int*datanumber;//指针本身存于data空间,它指向int型数据由于指向对象的存储空间在编译时无法确定(运行时确定),因此必须生成通用代码以保证对任意空间的对象进行存取。所以通用指针生成的代码速度较慢。指针char型数据指针分区2020/2/25144.2.3利用指针进行绝对地址访问unsignedchardata*p;p=0x40;*p=0x55;//数据0x55送入内部RAM的0x40单元例如:C51编译器提供了一组宏定义实现对80C51绝对地址的访问。这组宏定义原型放在absacc.h文件中,形如:#defineDBYTE((unsignedcharvolatiledata*)0)从而使DBYTE用于以字节形式对data区访问,可以写成:*(DBYTE)=0x55H;或DBYTE[0]=0x55H;4.2.3利用指针进行绝对地址访问#defineDBYTE((unsignedcharvolatiledata*)0)#definePBYTE((unsignedcharvolatilepdata*)0)#defineXBYTE((unsignedcharvolatilexdata*)0)#defineCBYTE((unsignedcharvolatilecode*)0)指针类型-unsignedchar存储区域-databdataidatapdataxdatacode绝对地址-0上述宏定义的含义-将0值转化为具有指定存储区域无符号字符类型变量的指针,并且此变量位于指定存储区域的起始位置。4.2.3利用指针进行绝对地址访问DBYTE[0]=0x55*(DBYTE+0)=0x55;DBYTE[4]=0x55*(DBYTE+4)=0x55;执行操作-使用地址指针并通过数组下标来实现data存储区的指定存储位置(下标为偏移地址)的单字节写操作。XBYTE[0]=0x55*(XBYTE+0)=0x55;XBYTE[4]=0x55*(XBYTE+4)=0x55;执行操作-使用地址指针并通过数组下标来实现xdata存储区的指定存储位置(下标为偏移地址)的单字节写操作。4.2.3利用指针进行绝对地址访问#defineDWORD((unsignedintvolatiledata*)0)#definePWORD((unsignedintvolatilepdata*)0)#defineXWORD((unsignedintvolatilexdata*)0)#defineCWORD((unsignedintvolatilecode*)0)指针类型-unsignedint存储区域-data,pdata,xdata,code绝对地址-0上述宏定义的含义-将0值转化为具有指定存储区域无符号整数类型变量的指针,并且此变量位于指定存储区域的起始位置。4.2.3利用指针进行绝对地址访问DWORD[0]=0x3355*(DWORD+0)=0x3355;DWORD[4]=0x3355*(DWORD+4)=0x3355;执行操作-使用地址指针并通过数组下标来实现data存储区的指定存储位置(下标为偏移地址)的双字节写操作。XWORD[0]=0x3355*(XWORD+0)=0x3355;XWORD[4]=0x3355*(XWORD+4)=0x3355;执行操作-使用地址指针并通过数组下标来实现xdata存储区的指定存储位置(下标为偏移地址)的双字节写操作。4.2.3利用指针进行绝对地址访问pdata:片外RAM,256字节,分页间址访问。MOVXA,@R0-读片外RAM,最大寻址256字节。MOVX@R0,A-写片外RAM,最大寻址256字节在Startup.A51中与pdata有关的伪指令代码:PPAGEENABLEEQU0:为1时可使用pdata变量。PPAGEEQU0:指定当前页的页号。PDATASTARTEQU0H:指定pdata存储区的起始地址。PDATALENEQU0H:指定pdata存储区的长度(字节)。大多数芯片将pdata存储区定义为xdata区的低256字节,C51对于pdata存储区的使用存在一些问题,不推荐使用4.2.3利用指针进行绝对地址访问P0寄存器地址为90H即144(9×16),可否使用指针进行读写操作(比如一下所使用的形式访问P0寄存器)?DBYTE[144]=0x55或*(DBYTE+144)=0x55;指针的存储区域:databdataidatapdataxdatacodebdata:片内RAM,位寻址区,直接地址访问。data:片内RAM,128字节,直接地址访问。idata:片内RAM,256字节,间接地址访问。pdata:片外RAM,256字节,分页间址访问。xdata:片外RAM,64K字节,间接地址访问。code:片内或片外ROM,64K字节,间接地址访问。4.2.3利用指针进行绝对地址访问对于SFR寄存器的访问,比如端口寄存器P0,P1等。应使用sfr或sfr16类型定义,比如:sfrP0=0x90;上述等号表示定义而不是赋值操作,类似于sbit类型的定义。P0=0x55;将50H写入P0口的寄存器中V0=P0;从P0口读入一个字节并将其拷贝到字符变量V0中4.2.4C51程序编写示例C51源程序C51编译器列表文件浮动目标码模块连接器用户库系统库映像文件绝对定位目标码文件硬件仿真器转换器OMF51格式文件编程器写入程序存储器软件模拟器【例4-1】将30H至3FH共16个RAM单元初始化为“55H”。#includereg52.h#includeabsacc.hvoidmain(void){unsignedchari;for(i=0;i=15;i++){DBYTE[0x30+i]=0x55;}while(1);}编译系统自动连接了startup.a51生成代码一是将内部RAM的00H~7FH清0;二是设置堆栈指针SP。有全局变量赋值时编译系统会自动连接init.a51生成代码C:0x0000020011LJMPC:0011C:0x0003E4CLRAC:0x0004FFMOVR7,AC:0x00057430MOVA,#0x30C:0x00072FADDA,R7C:0x0008F8MOVR0,AC:0x00097655MOV@R0,#0x55C:0x000B0FINCR7C:0x000CBF10F6CJNER7,#0x10,C:0005C:0x000F80FESJMPC:000FC:0x0011787FMOVR0,#0x7FC:0x0013E4CLRAC:0x0
本文标题:第4章80C51单片机C语言程序设计
链接地址:https://www.777doc.com/doc-4005271 .html