单片机基于C语言编程的基础学习教案

上传人:莉**** 文档编号:98579665 上传时间:2022-05-30 格式:PPT 页数:93 大小:3.53MB
返回 下载 相关 举报
单片机基于C语言编程的基础学习教案_第1页
第1页 / 共93页
单片机基于C语言编程的基础学习教案_第2页
第2页 / 共93页
单片机基于C语言编程的基础学习教案_第3页
第3页 / 共93页
点击查看更多>>
资源描述
会计学1单片机基于单片机基于(jy)C语言编程的基础语言编程的基础第一页,共93页。4.1 C语言与语言与MCS51 用汇编程序设计MCS51系列单片机应用程序时,必须要考虑其存储器结构,尤其必须考虑其片内数据存储器与特殊功能寄存器正确、合理的使用以及按实际地址处理端口数据。用C语言编写MCS51单片机的应用程序,虽然不像用汇编语言那样具体地组织、分配存储器资源和处理端口数据,但在C语言编程中,对数据类型与变量的定义,必须要与单片机的存储结构相关联,否则编译器不能正确地映射定位。用C语言编写单片机应用程序与编写标准(biozhn)的C语言程序的不同之处就在于根据单片机存储结构及内部资源定义相应的C语言中的数据类型和变量,其它的语法规定、程序结构及程序设计方法都与标准(biozhn)的C语言程序设计相同。 第1页/共92页第二页,共93页。 用C语言编写的应用程序必须(bx)经单片机的C语言编译器(简称C51),转换生成单片机可执行的代码程序。支持MCS51系列单片机的C语言编译器有很多种。如American Automation、Auocet、BSO/TASKING、DUNFIELD SHAREWARE、KEIL/Franklin等。其中KEIL/Franklin以它的代码紧凑和使用方便等特点优于其它编译器。本章是针对这种编译器介绍 MCS51单片机C语言程序设计。 第2页/共92页第三页,共93页。4.2 C51数据类型及在数据类型及在MCS-51中的存储中的存储(cn ch)方式方式4.2.1 C51的数据类型的数据类型 Franklin C51编译器具体编译器具体(jt)支持的数据类型有:位型支持的数据类型有:位型(bit)、无符号字符无符号字符(unsigned char)、有符号字符、有符号字符(singed char)、无符号整、无符号整型型(unsigned int )、有符号整型、有符号整型(signed int )、无符号长整型、无符号长整型(unsigned long )、有符号长整型、有符号长整型(signed long )、浮点型、浮点型(float)和指针和指针类型等。类型等。第3页/共92页第四页,共93页。表表4.1 Franklin C51的数据类型的数据类型数据类型长度(bit)长度(byte)值域bit110,1unsigned char810255signed char81128127unsigned int 162065535signed int 1623276832767unsigned long32404294967295signed long 32421474836482147483647float 3241.176E383.40E+38(6位数字)double6481.176E383.40E+38(10位数字)一般指针243存储空间065535第4页/共92页第五页,共93页。4.2.2 C51数据在数据在MCS-51中的存储中的存储(cn ch)方式方式 位变量(bit):与MCS-51硬件特性操作有关(yugun)的可以定义成位变量。位变量必须定位在MCS-51单片机片内RAM的位寻址空间中。 字符变量(char):字符变量的长度为1 byte即8位。这很合适MCS-51单片机,因为MCS-51单片机每次可处理8位数据。对于无符号变量(unsigned char)的值域范围是0255。对于有符号字符变量(signed char),最具有重要意义的位是最高位上的符号标志位(msb)。此位为1代表负,为0代表正。有符号字符变量和无符号字符变量在表示0127的数值时,其含义是一样的,都是00 x7F。负数一般用补码表示,即用11111111表示-1, 用11111110表示-2。当进行乘除法运算时,符号问题就变得十分复杂,而C51编译器会自动地将相应的库函数调入程序中来解决这个问题。第5页/共92页第六页,共93页。 整型变量(int): 整型变量的长度为16位。与8080和8086 CPU系列不同,MCS-51系列单片机将int型变量的高位字节数存放(cnfng)在低地址字节中,低位字节数存放(cnfng)在高地址字节中。有符号整型变量(signed int)也使用msb位作符号标志位,并使用二进制补码表示数值。可直接使用几种专用的机器指令来完成多字节的加、减、乘、除运算。整型变量值0 x1234以图所示的方式存放(cnfng)在内存中。第6页/共92页第七页,共93页。图图4.1 整型数的存储整型数的存储(cn ch)结构结构 0 x120 x34+0+1地址地址(dzh) 0 x120 x340 x560 x48.+0+1+2+3地址地址(dzh) 图图4.2 长整型变量的存储结构长整型变量的存储结构 第7页/共92页第八页,共93页。 浮点型变量(float): 浮点型变量为32位,占4个字节,许多复杂的数学(shxu)表达式都采用浮点变量数据类型。应用符号位表示数的符号,用阶码和尾数表示数的大小。 用它们进行任何数学(shxu)运算都需要使用由编译器决定的各种不同效率等级的库函数。Franklin C51的浮点变量数据类型的使用格式与IEEE-754标准有关,具有24位精度,尾数的高位始终为1,因而不保存,位的分布如下: 1位符号位。 8位指数位。 23位尾数。 第8页/共92页第九页,共93页。符号位是最高位,尾数为低符号位是最高位,尾数为低23位,内存中按字节存储顺序位,内存中按字节存储顺序(shnx)如下:如下:地址地址+0+1+2+3内容内容MMMMMMMMMMMMMMMMEMMMMMMMSEEEEEEE 其中,S为符号位,1表示负,0表示正;E为阶码;M为23位尾数,最高位为1。 浮点变量值 的十进制为:0 xC1480000,它按图所示方式(fngsh)存于内存中。第9页/共92页第十页,共93页。0 x000 x000 x480 xC1.+0+1+2+3地址地址(dzh) 图图4.3 浮点数的存储浮点数的存储(cn ch)结构结构 第10页/共92页第十一页,共93页。 在编程时,如果只强调运算速度而不进行负数运算时,最好采用无符号(unsigned)格式。 无符号字符类型的使用:无论何时,应尽可能使用无符号字符变量,因为它能直接被MCS-51所接受。基于(jy)同样的原因,也应尽量使用位变量。有符号字符变量虽然也只占用一个字节,但需要进行额外的操作来进行测试代码的符号位。这无疑会降低代码效率。第11页/共92页第十二页,共93页。 使用简化形式定义数据类型。其方法是在源程序开头使用#define语句自定义简化的类型标识符。例如(lr):#define uchar unsigned char #define uint unsigned int 这样,在编程中,就可以用uchar代替unsigned char,用uint代替unsigned int来定义变量。第12页/共92页第十三页,共93页。4.3 C51数据数据(shj)的存储类型与的存储类型与MCS-51存储结构存储结构表表 4.2 C51存储存储(cn ch)类型与类型与MCS-51存储存储(cn ch)空间的对应关系空间的对应关系存储类型存储类型与存储空间的对应关系与存储空间的对应关系 data 直接寻址片内数据存储区,访问速度快直接寻址片内数据存储区,访问速度快(128字节字节) bdata 可位寻址片内数据存储区,允许位与字节混合访问可位寻址片内数据存储区,允许位与字节混合访问(16字节字节) idata 间接寻址片内数据存储区,可访问片内全部间接寻址片内数据存储区,可访问片内全部RAM地址空间地址空间(256字节字节) pdata 分页寻址片外数据存储区分页寻址片外数据存储区(256字节字节)由由MOV Ri访问访问(i=0,1) xdata 片外数据存储区片外数据存储区(64 KB)由由MOVX DPTR访问访问 code 程序存储器程序存储器64 KB空间,由空间,由MOVC DPTR访问访问第13页/共92页第十四页,共93页。表表4.3 C51存储存储(cn ch)类型及其数据长度和值域类型及其数据长度和值域存储类型长度(bit)长度(byte)值域范围data810255idata810255pdata810255xdata162065 535code162065 535第14页/共92页第十五页,共93页。带存储类型带存储类型(lixng)的变量的定义的一般格式为的变量的定义的一般格式为 数据类型数据类型(lixng) 存储类型存储类型(lixng) 变量名变量名带存储类型的变量带存储类型的变量(binling)定义举例:定义举例:char data var1;bit bdata flags;float idata x,y,z;unsigned int pdata var2;unsigned char vector34;第15页/共92页第十六页,共93页。表表 4.4 存储模式存储模式(msh)说明说明存储模存储模式式说说 明明SMALL默认的存储类型是默认的存储类型是data,参数及局部变量放入可直接寻址片,参数及局部变量放入可直接寻址片内内RAM的用户区中的用户区中(最大最大128字节字节)。另外所有对象。另外所有对象(包括堆栈包括堆栈),都必须嵌入片内,都必须嵌入片内RAM。栈长很关键,因为实际栈长依赖于。栈长很关键,因为实际栈长依赖于函数嵌套调用层数函数嵌套调用层数COMPACT默认的存储类型是默认的存储类型是pdata,参数及局部变量放入分页的外部数,参数及局部变量放入分页的外部数据存储区,通过据存储区,通过R0或或R1间接访问,栈空间位于片内数据间接访问,栈空间位于片内数据存储区中存储区中LARGE默认的存储类型是默认的存储类型是xdata,参数及局部变量直接放入片外数据,参数及局部变量直接放入片外数据存储区,使用数据指针存储区,使用数据指针DPTR来进行寻址。用此数据指针进行来进行寻址。用此数据指针进行访问效率较低,尤其对两个或多个字节的变量,这种数据类访问效率较低,尤其对两个或多个字节的变量,这种数据类型的访问机制直接影响代码的长度型的访问机制直接影响代码的长度第16页/共92页第十七页,共93页。4.4 MCS-51特殊特殊(tsh)功能寄存器功能寄存器(SFR)的的C51定义定义 MCS-51单片机中,除了程序计数器PC和4组工作寄存器组外,其它所有的寄存器均为特殊功能寄存器(SFR),分散在片内RAM区的高128字节中,地址范围为80H0FFH。SFR中有11个寄存器具有位寻址能力,它们的字节地址都能被8整除,即字节地址是以8或0为尾数的。 为了能直接访问这些SFR,Franklin C51提供了一种自主形式的定义方法,这种定义方法与标准C语言不兼容,只适用(shyng)于对MCS-51系列单片机进行C语言编程。特殊功能寄存器C51定义的一般语法格式如下:sfr sfr-name = int constant;第17页/共92页第十八页,共93页。 sfr是定义语句的关键字,其后必须跟一个MSC-51单片机真实存在的特殊功能寄存器名,=后面必须是一个整型常数,不允许带有运算符的表达式,是特殊功能寄存器sfr-name的字节地址(dzh),这个常数值的范围必须在SFR地址(dzh)范围内,位于0 x800 xFF。例如:sfr SCON=0 x98; /* 串口控制寄存器地址(dzh)98H */sfr TMOD=0 x89;/* 定时器/计数器方式控制寄存器地址(dzh)89H */第18页/共92页第十九页,共93页。 MCS-51系列单片机的特殊功能寄存器的数量与类型不尽相同,因此建议将所有特殊的sfr定义放入一个头文件中,该文件应包括MCS-51单片机系列机型中的SFR定义。C51编译器的reg51.h头文件就是这样一个文件。 在新的MCS-51系列产品中,SFR在功能上经常组合为16位值,当SFR的高字节地址直接位于低字节之后时,对16位SFR的值可以直接进行访问(fngwn)。例如52子系列的定时器/计数器2就是这种情况。为了有效地访问(fngwn)这类SFR,可使用关键字sfr16来定义,其定义语句的语法格式与8位SFR相同,只是=后面的地址必须用16位SFR的低字节地址,即低字节地址作为sfr16的定义地址。第19页/共92页第二十页,共93页。例如:例如: sfr16 T2 = 0 xCC /*定时器定时器/计数器计数器2:T2低低8位地址为位地址为0CCH,T2高高8位位地址为地址为0CDH*/ 这种定义适用于所有新的这种定义适用于所有新的16位位SFR,但不能用于定时器,但不能用于定时器/计数器计数器0和和1。 对于位寻址的对于位寻址的SFR中的位,中的位,C51的扩充的扩充(kuchng)功能支持特殊位的定功能支持特殊位的定义,像义,像SFR一样不与标准一样不与标准C兼容,使用兼容,使用sbit来定义位寻址单元。来定义位寻址单元。第20页/共92页第二十一页,共93页。 第一种格式: sbit bit-name = sfr-nameint constant; sbit是定义语句的关键字,后跟一个寻址位符号名(该位符号名必须是MCS-51单片机中规定的位名称),=后的sfr-name必须是已定义过的SFR的名字,后的整常数是寻址位在特殊功能寄存器sfr-name中的位号,必须是07范围中的数。例如(lr): sfr PSW=0 xD0 ; /* 定义PSW寄存器地址为D0H */ sbit OV=PSW2 ; /* 定义OV位为,地址为D2H */ sbit CY=PSW7 ; /* 定义CY位为,地址为D7H */第21页/共92页第二十二页,共93页。 第二种格式:sbit bit-name = int constantint constant; =后的int constant为寻址地址位所在的特殊功能(gngnng)寄存器的字节地址,符号后的int constant为寻址位在特殊功能(gngnng)寄存器中的位号。例如: sbit OV=0XD02 ;/* 定义OV位地址是D0H字节中的第2位 */ sbit CY=0XD07 ;/* 定义CY位地址是D0H字节中的第7位 */第22页/共92页第二十三页,共93页。 第三种格式(g shi):sbit bit-name = int constant; =后的int constant为寻址位的绝对位地址。例如: sbit OV=0XD2 ;/* 定义OV位地址为D2H */ sbit CY=0XD7 ;/* 定义CY位地址为D7H */ 特殊功能位代表了一个独立的定义类,不能与其它位定义和位域互换。第23页/共92页第二十四页,共93页。4.5 MCS-51并行接口的并行接口的C51定义定义(dngy) MCS-51系列单片机并行I/O接口除了芯片上的4个I/O口(P0 P3)外,还可以在片外扩展I/O口。MCS-51单片机I/O口与数据存储器统一编址,即把一个I/O口当作数据存储器中的一个单元来看待。 使用C51进行编程时,MCS-51片内的I/O口与片外扩展的I/O可以统一在一个头文件中定义,也可以在程序(chngx)中(一般在开始的位置)进行定义,其定义方法如下: 对于MCS-51片内I/O口按特殊功能寄存器方法定义。例如:sfr P0=0 x80 ; /* 定义P0口,地址为80H */sfr P1=0 x90 ; /* 定义P1口,地址为90H */第24页/共92页第二十五页,共93页。 对于片外扩展I/O口,则根据硬件译码地址,将其视作为片外数据存储器的一个单元,使用#define语句(yj)进行定义。例如#include #define PORTA XBYTE 0 xFFC0 是C51中绝对地址访问函数的头文件,将PORTA定义为外部I/O口,地址为 FFC0H,长度为8位。 一旦在头文件或程序中对这些片外I/O口进行定义后,在程序中就可以自由使用变量名与其实际地址的联系,以便使程序员能用软件模拟MCS-51的硬件操作。第25页/共92页第二十六页,共93页。 (1) 位变量C51定义。使用C51编程时,定义了位变量后,就可以用定义了的变量来表示MCS-51的位寻址单元。 位变量的C51定义的一般语法(yf)格式如下: 位类型标识符(bit) 位变量名; 例如:bit direction_bit ; /* 把direction_bit定义为位变量 */bit look_pointer ; /* 把look_pointer定义为位变量 */4.6 位变量位变量(binling)的的C51定义定义第26页/共92页第二十七页,共93页。 (2) 函数可包含类型为bit的参数,也可以将其作为返回值。例如: bit func(bit b0, bit b1) /* 变量b0,b1作为函数的参数 */ return (b1); /* 变量b1作为函数的返回值 */ 注意,使用(shyng)(#pragma disable)或包含明确的寄存器组切换(using n)的函数不能返回位值,否则编辑器将会给出一个错误信息。第27页/共92页第二十八页,共93页。 (3) 对位(du wi)变量定义的限制。位变量不能定义成一个指针,如不能定义:bit * bit_pointer。不存在位数组,如不能定义:bit b_array 。 在位定义中,允许定义存储类型,位变量都被放入一个位段,此段总位于MCS-51片内的RAM区中。因此,存储类型限制为data和idata,如果将位变量的存储类型定义成其它存储类型都将编译出错。第28页/共92页第二十九页,共93页。例例1 先定义先定义(dngy)变量的数据类型和存储类型:变量的数据类型和存储类型:bdata int ibase; /* 定义定义(dngy)ibase为为bdata整型变量整型变量 */bdata char bary4;/* bary4定义定义(dngy)为为bdata字符型数组字符型数组 */然后可使用然后可使用sbit定义定义(dngy)可独立寻址访问的对象位:可独立寻址访问的对象位:sbit mybit0 = ibase0 ;/* mybit0定义定义(dngy)为为ibase的第的第0位位 */sbit mybit15 = ibase15;/* mybit0定义定义(dngy)为为ibase的第的第15位位 */sbit Ary07 = bary07 ;/* Ary07定义定义(dngy)为为abry0的第的第7位位 */sbit Ary37 = bary37 ;/* Ary37定义定义(dngy)为为abry3的第的第7位位 */第29页/共92页第三十页,共93页。 对象ibase和bary也可以字节寻址: ary37=0; /* bary3的第7位赋值为0 */ bary3=a; /* 字节寻址,bary3 赋值为a */ sbit定义要位寻址对象所在字节基址对象的存储类型为bdata,否则只有绝对的特殊位定义(sbit)是合法的。操作符后的最大值依赖于指定(zhdng)的基类型,对于char/uchar而言是07,对于int/uint而言是015,对于long/ulong而言是031。第30页/共92页第三十一页,共93页。4.7 C51构造构造(guzo)数据类型数据类型 1基于存储器的指针基于存储器的指针(zhzhn) 基于存储器的指针基于存储器的指针(zhzhn)以存储器类型为参量,它在编译时以存储器类型为参量,它在编译时才被确定。因此,为指针才被确定。因此,为指针(zhzhn)选择存储器的方法可以省掉,选择存储器的方法可以省掉,以便这些指针以便这些指针(zhzhn)的长度为一个字节的长度为一个字节(idata *,data *,pdata *)或或2个字节个字节(code *,xdata *)。编译时,这类操作一般被。编译时,这类操作一般被行内行内(inline)编码,而无需进行库调用。编码,而无需进行库调用。 基于存储器的指针基于存储器的指针(zhzhn)定义举例:定义举例: char xdata *px;第31页/共92页第三十二页,共93页。 在xdata存储器中定义了一个指向字符型(char)的指针变量px。指针自身在默认存储区(决定于编译模式),长度为2个字节(值为00 xFFFF)。 char xdata *data pdx; 除了明确(mngqu)定义指针位于MCS-51内部存储区(data)外,其它与上例相同,它与编译模式无关。 data char xdata *pdx;第32页/共92页第三十三页,共93页。struct time char hour ; char min; char sec; struct time xdata *pxtime; 在结构在结构(jigu)struct time中,除了其它结构中,除了其它结构(jigu)成员外,还成员外,还包含有一个具有和包含有一个具有和struct time相同的指针相同的指针pxtime,time位于外部数据位于外部数据存储器存储器(xdata),指针,指针pxtime具有两个字节长度。具有两个字节长度。第33页/共92页第三十四页,共93页。 struct time idata *ptime ; 这个声明定义了一个位于默认存储器中的指针,它指向结构time,time位于idata存储器中,结构成员可以通过MCS-51的R0或R1 进行间接访问,指针ptime为1个字节长。 ptimepxtimehour = 12; 使用(shyng)上面的关于struct time和struct idata *ptime的定义,指针pxtime被从结构中间接调用,它指向位于xdata存储器中的time结构。结构成员hour被赋值为12。第34页/共92页第三十五页,共93页。 2一般指针一般指针 一般指针包括一般指针包括3个字节:个字节:1个字节存储类型个字节存储类型(lixng)和和2个字节偏移地个字节偏移地址,即址,即地址地址+0+1+2内容内容存储器类型存储器类型偏移地址高位字偏移地址高位字节节偏移地址低位字偏移地址低位字节节其中其中(qzhng),第一字节代表了指针的存储器类型,存储器类型编码如下:,第一字节代表了指针的存储器类型,存储器类型编码如下:存储器存储器类型类型idataxdatapdatadatacode值12345第35页/共92页第三十六页,共93页。例如,以例如,以xdata类型的类型的0 x1234地址为指针可以表示地址为指针可以表示(biosh)如下:如下:地址+0+1+2内容0 x020 x120 x34 当用常数作指针(zhzhn)时,必须注意正确定义存储器类型和偏移量。 例如,将常数值0 x41写入地址为0 x8000的外部数据存储器。 #define XBYTE ( (char *) 0 x20000L) XBYTE0 x8000 = 0 x41 ; 其中,XBYTE被定义为(char *)0 x20000L,0 x20000L为一般指针(zhzhn),其存储类型为2,偏移量为0000H,这样XBYTE成为指向xdata零地址的指针(zhzhn)。而XBYTE8000则是外部数据存储器的0 x8000绝对地址。第36页/共92页第三十七页,共93页。4.8 模块化程序开发过程模块化程序开发过程(guchng)图图4.4 程序开发过程程序开发过程(guchng) 第37页/共92页第三十八页,共93页。4.8.1 混合混合(hnh)编程编程1命名命名(mng mng)规则规则表表4.5 函数函数(hnsh)名的转换名的转换说 明符号名转 换 规 则void func(void)FUNC无参数传递或不含寄存器参数的函数名不作改变转入目标文件中,名字只是简单地转换为大写形式void func(void)_FUNC带寄存器参数的函数名加入“_”字符前缀,表明这类函数包含寄存器的参数传递void func(void)reentrant_?FUNC对于重入函数加上“_?”字符串前缀,表明这类函数包含栈内的参数传递第38页/共92页第三十九页,共93页。例例2 用汇编语言编写用汇编语言编写(binxi)函数函数toupper,参数传递发生在寄存器,参数传递发生在寄存器R7中。中。UPPER SEGMENT CODE ;程序段;程序段PUBLIC _TOUPPER ;入口地址;入口地址PSEG UPPER ; 程序段程序段_TOUPPER: MOV A,R7 ;从;从R7中取参数中取参数 CJNE A,# a,$+3 JC UPPERET CJNE A, # z+1 ,$+3 JNC UPPERET CLR ACC ,5 UPPERET: MOV R7 ,A ;返回值放在;返回值放在R7中中 RET ;返回到;返回到C第39页/共92页第四十页,共93页。2参数传递规则参数传递规则(guz)表表4.6 参数传递的寄存器选择参数传递的寄存器选择(xunz)参数类型charintlong ,float一般指针第1个参数R7R6, R7R4R7R1,R2,R3第2个参数R5R4, R5R4R7R1,R2,R3第3个参数R3R2, R3无R1,R2,R3第40页/共92页第四十一页,共93页。 func1(int a) a是第一个参数,在R6,R7中传递。 func2 (int b, int c, int *d ) b是第一个参数,在R6,R7中传递;c是第二个参数,在R4,R5中传递;d是第三个参数,在R1,R2,R3中传递。 func3(long e , long f ) e是第一个参数,在R4R7中传递;f是第二个参数,不能在寄存器中传递,只能(zh nn)在参数传递段中传递。 func4(float g , char h ) g是第一个参数,在R4R7中传递;h是第二个参数,必须在参数传递段中传递。第41页/共92页第四十二页,共93页。表表4.7 函数函数(hnsh)返回值的寄存器返回值的寄存器返 回 值寄 存 器说 明bitC进位标位(unsigned) charR7 (unsigned) intR6,R7高位字节在R6,低位字节在R7(unsigned) longR4R7高位字节在R4,低位字节在R7floatR4R732位IEEE格式,指数和符号位在R7指针R1,R2,R3R3放存储器类型,高位在R2,低位在R1第42页/共92页第四十三页,共93页。 在汇编子程序中,当前选择的寄存器组及寄存器ACC、B、DPTR和PSW都可能(knng)改变。当被C调用时,必须无条件地假设这些寄存器的内容已被破坏。如果已在连接/定位程序时选择了覆盖,那么每个汇编子程序包含一个单独的程序段是必要的,因为在覆盖过程中,函数间参量通过子程序各自的段参量计算。汇编子程序的数据区甚至可包含在覆盖部分中,但应注意下面两点: (1) 所有段名必须以C51类似的方法建立。 (2) 每个有局部变量的汇编程序必须指定自己的数据段,这个数据段只能为其它函数访问作参数传递用。所有参数一个接一个被传递,由其它函数计算的结果保存入栈。 第43页/共92页第四十四页,共93页。4.8.2 覆盖覆盖(fgi)和共享和共享 1覆盖覆盖 单片机片内存储空间有限,连接器单片机片内存储空间有限,连接器/定位器通常重新启用程序不再用的位定位器通常重新启用程序不再用的位置。这就是说,若一个程序不再调用,也不由其它程序调用置。这就是说,若一个程序不再调用,也不由其它程序调用(甚至间接调用甚至间接调用),那么在其它程序执行完之前,这个程序不再运行。这个程序的变量可以放,那么在其它程序执行完之前,这个程序不再运行。这个程序的变量可以放在与其它程序完全相同的在与其它程序完全相同的RAM空间,很像可重用的寄存器。这种技术就是覆空间,很像可重用的寄存器。这种技术就是覆盖。在汇编中直接通过手工完成盖。在汇编中直接通过手工完成(wn chng)的这些空间分配,的这些空间分配,C语言中可以语言中可以由连接器自动管理。若有几个不相关联的程序时,它可以使由连接器自动管理。若有几个不相关联的程序时,它可以使RAM单元比手工单元比手工考虑要用的少。考虑要用的少。第44页/共92页第四十五页,共93页。2共享共享1) 共享变量共享变量(binling)类 型汇 编 语 言C 语 言动态变量 y( )int x;静态变量 static int x;公用变量PUBLIC XX:ds 2Int x;外部变量EXTERN DATA(X)MOV DPTR,# Xextern int;静态子程序/函数Y:static y( ) ;公共子程序/函数PUBLIC YY:y( ) ;外部子程序/函数EXTERN CODE(Y)LCALL Yy( )第45页/共92页第四十六页,共93页。 2) 共享函数/子程序 C中函数若是全局的(公用的),可以放在调用的函数之后。若函数是模块专用的,它可以定义为静态函数,这样它不能被其它模块调用。C语言的ANSI标准建议所有函数在主函数前要有原型(进行说明),然后实际函数可在主函数之后或其它模块中。这符合自顶向下编程的概念。 汇编语言中,子程序使用标号(bioho)可在给定模块的任何位置。汇编器首先扫描得到所有的符号名,然后值就可填入LCALL或LJMP。一个模块或另一模块共享子程序,一个使用PUBLIC而另一个使用EXTERN。当指定为EXTERN,符号类型(CODE,DATA,XDATA,IDATA,BIT或NUMBER)必须特别加以指定,以便连接器可以确定放在一起的正确类型。第46页/共92页第四十七页,共93页。4.8.3 库和连接器库和连接器/定位器定位器 1. 库库表表4.9 Franklin C51的编译的编译(biny)库库库说 明C51S.LIBSMALL模式,无浮点运算C51FPS.LIB浮点数学运算库(SMALL模式)C51C.LIBCOMPACT模式,无浮点运算C51FPC.LIB浮点运算库(COMPACT模式)C51L.LIBLARGE模式,无浮点运算C51FPL.LIB浮点运算库(LARGE模式)第47页/共92页第四十八页,共93页。 2连接器连接器/定位器定位器 1) 组合程序模块组合程序模块 将几个不同程序模块组合为一个模块,并自动从库中挑选将几个不同程序模块组合为一个模块,并自动从库中挑选(tioxun)模模块嵌入目标文件。输入文件按命令行中出现的顺序处理。通常的程序模块块嵌入目标文件。输入文件按命令行中出现的顺序处理。通常的程序模块是由是由C51编译器或编译器或A51宏汇编生成的可重入的目标文件。宏汇编生成的可重入的目标文件。第48页/共92页第四十九页,共93页。 2) 组合段 将具有相同段名的可重定位段组合成单一的段。在一个程序模块中定义的一个段成为(chngwi)部分段。一个部分段在源文件中以下列形式指定: (1) 名字 每个重定位段有一个名字,它可与来自其它模块的同名的可重定位段组合。绝对段没有名字。 (2) 类型 类型表明段所属的地址空间CODE,XDATA,DATA或BIT。 第49页/共92页第五十页,共93页。 (3) 定位方式 可重定位段的定位方式有PAGE,INPAGE,INBLOCK,BITADD RESSABLE或UNIT。INPAGE表明段必须放入一页(高8位地址相同)中以使用短转移和调用指令。INBLOCK段应使用ACALL,必须放在2048字节块中。因为没有连接器可以灵活(ln hu)地判知调用和转移是否在块内。可重定位的其它限制是:PAGE-不能超过256字节;BITADDRESSABLE-必须放在可位寻址的内部RAM空间;UNIT-允许段从任意字节开始(对位变量是位)。 (4) 长度 一个段的长度。第50页/共92页第五十一页,共93页。 (5) 基址 段的首址。对于绝对段,地址由汇编器赋予,对于可重定位段,地址由L51决定。在处理程序模块时,L51自动产生段表(MAP),该表包含了每个段的类型、基址、长度、可重定位性和名字。 L51自动将所具有相同名字的所有部分段组合到单一可重定位段中。例如,三个程序模块包含字段VAR,在组合时,三个段的长度相加,从而(cng r)组合段的长度也增加了。对组合段有下列规则: 所有具有相同名的部分段必须有相同类型(CODE,DATA,IDATA,XDATA或BIT)。 组合段的长度不能超过存储区的物理长度。 每个组合的部分段的定位方法也必须相同。 绝对段相互不组合,它们被直接拷贝到输出文件。第51页/共92页第五十二页,共93页。3) 存储器分配存储器分配(fnpi)物理存储区最大长度地址区段类型程序64 KB00FFFFHCODE外部数据64 KB00FFFFHXDATA直接寻址片内数据128字节07FHDATA间接寻址片内数据256字节00FFHIDATA片内数据的位空间128位07FHBIT表4.10 MCS-51系列的物理(wl)存储区第52页/共92页第五十三页,共93页。 4) 采用覆盖技术使用数据存储器 通过采用一定的覆盖技术,MCS-51系列少量的片内数据存储器可由L51有效地使用。由C51编译器或是A51汇编器生成的参数和局部变量(若使用它们的函数不相互调用)可在存储器中覆盖。这样,所用的存储器得到(d do)相当程度地减少。 为完成数据覆盖,L51分析所有不同函数间的调用,使用该信息可以确定哪个数据和位段可被覆盖。使用控制参数OVERLAY和NOOVERLAY可允许或禁止覆盖。OVERLAY是默认值,用它可产生非常紧凑的数据区。 第53页/共92页第五十四页,共93页。 5) 决定外部参考(cnko)地址 具有相同名的外部符号(EXTERN)和公用符号(PUBLIC)被确定后,外部符号指向其它模块中的地址。一个已声明的外部符号用具有相同名字的功用符号确定,外部参考(cnko)地址由其公共参考(cnko)地址确定。这还与类型(DATA,IDATA,XDATA,CODE,BIT或NUMBER)有关,如果类型不符或未发现外部符号参考(cnko)地址的公用符号,则会产生错误。公用符号的绝对地址在段定位后决定。第54页/共92页第五十五页,共93页。 6) 绝对地址计算 定义绝对地址并计算可重定位段的地址。在段分配和外部(wib)公用参考地址处理完后,程序模块中所有可重定位地址和外部(wib)地址要进行计算,此时生成的目标文件中的符号信息(DEBUG)被改变以反映新的值。第55页/共92页第五十六页,共93页。 7) 产生绝对目标文件 可执行程序以绝对目标格式产生。该绝对目标文件可包含附加的符号(fho)信息(DEBUG),从而使符号(fho)调试成为可能。符号(fho)信息可用参数NODEBUGSYMBOLS,NODEBUGPUBLICS和NODEBUGLINES禁止。输出文件是可执行的,并可由仿真器装入调试或被OHS51翻译为Intel HEX格式文件以供EPROM固化。第56页/共92页第五十七页,共93页。 8) 产生映像文件 产生一个反映每个处理步骤的映像文件,它显示(xinsh)有关连接/定位过程的信息和程序符号,并包含一个公用和外部符号的交叉参考报告。映像文件包含下列信息: 文件名和命令行参数。 模块的文件名和模块名。 一个包含段地址、类型、定位方法和名字的存储器分配表。该表可在命令行中用NOMAP参考禁止。第57页/共92页第五十八页,共93页。 段和符号的所有错误列表。列表文件末尾显示出所有出错的原因。 一个包含输入文件中符号信息的符号表。该信息由MODULES,SYMBOLS,PUBLICS和LINES名组成,LINES是C编译器产生的行号。符号信息可用参数NOSYMBOLS,NOPUBLICS和NOLINES完全或部分禁止。 一个按字母顺序排列的有关所有PUBLIC和EXTERN符号的交叉参考报告,其中显示出符号类型和模块名。第一个显示的模块名是定义了PUBLIC符号的模块,后面的模块名是定义了EXTERN符号的模块。在命令行输入参数IXREF可产生此报告。 在连接器/定位器运行(ynxng)期间检测到的错误同时显示在屏幕和文件尾部。第58页/共92页第五十九页,共93页。4.8.4 程序程序(chngx)优化优化 以下选择对提高程序效率有很大影响: (1) 尽量选择小存储模式以避免使用MOVX指令。 (2) 使用大模式(COMPACT/LARGE)应仔细考虑要放在内部(nib)数据存储器的变量要求是经常用的或是用于中间结果的。访问内部(nib)数据存储器要比访问外部数据存储器快得多。内部(nib)RAM由寄存器组、位数据区和其它用户用“data”类型定义的变量共享。由于内部(nib)RAM容量的限制(128256字节,由使用的单片机决定),必须权衡利弊以解决访问效率和这些对象的数量之间的矛盾。第59页/共92页第六十页,共93页。 (3) 要考虑操作顺序,完成一件事后再做一件事。 (4) 注意程序编写细则。例如,若使用for(;)循环,DJNZ指令比CJNE指令更有效,可减少重复循环次数。 (5) 若编译器不能使用左移和右移完成乘除法,应立即修改,例如,左移为乘2。 (6) 用逻辑AND/&取模比用MOD / %操作更有效。 (7) 因计算机基于二进制,仔细选择数据存储器和数组大小(dxio)可节省操作。第60页/共92页第六十一页,共93页。 (8) 尽可能使用最小的数据类型,MCS-51系列是8位机,显然对具有char类型的对象的操作比int或long类型的对象的操作要方便得多。 (9) 尽可能使用unsigned数据类型。MCS-51系列CPU并不直接支持有符号数的运算。因而C51编译器必须产生与之相关的更多的程序代码以解决(jiju)这个问题。 (10) 尽可能使用局部函数变量。编译器总是尝试在寄存器里保持局部变量。这样,将循环变量(如for和while循环中的计数变量)说明为局部变量是最好的。使用unsigned char/int的对象通常能获得最好的结果。第61页/共92页第六十二页,共93页。第62页/共92页第六十三页,共93页。第63页/共92页第六十四页,共93页。1.双击 “Keil c51v808a.rar”第64页/共92页第六十五页,共93页。第65页/共92页第六十六页,共93页。第66页/共92页第六十七页,共93页。第67页/共92页第六十八页,共93页。第68页/共92页第六十九页,共93页。第69页/共92页第七十页,共93页。第70页/共92页第七十一页,共93页。第71页/共92页第七十二页,共93页。第72页/共92页第七十三页,共93页。第73页/共92页第七十四页,共93页。第74页/共92页第七十五页,共93页。第75页/共92页第七十六页,共93页。第76页/共92页第七十七页,共93页。保存工程的文件夹保存工程的文件夹也可以新建文件夹也可以新建文件夹工程名工程名第77页/共92页第七十八页,共93页。第78页/共92页第七十九页,共93页。第79页/共92页第八十页,共93页。第80页/共92页第八十一页,共93页。第81页/共92页第八十二页,共93页。第82页/共92页第八十三页,共93页。第83页/共92页第八十四页,共93页。第84页/共92页第八十五页,共93页。1.编译按钮源代码窗源代码窗2.消息窗,显示编译结果,编译成功,可以开始调试;3.点击“调试”第85页/共92页第八十六页,共93页。1.编译按钮源代码窗源代码窗2.消息窗,显示编译结果,编译成功,可以开始调试;3.点击“调试”第86页/共92页第八十七页,共93页。1.编译按钮源代码窗源代码窗2.消息窗,显示编译结果,编译成功,可以开始调试;3.点击“调试”第87页/共92页第八十八页,共93页。第88页/共92页第八十九页,共93页。第89页/共92页第九十页,共93页。第90页/共92页第九十一页,共93页。第91页/共92页第九十二页,共93页。NoImage内容(nirng)总结会计学。间接寻址片内数据存储区,可访问片内全部RAM地址空间(256字节)。bary3=a。void func(void)。当被C调用时,必须无条件地假设这些寄存器的内容已被破坏。将几个不同程序模块组合为一个模块,并自动从库中挑选模块嵌入目标文件。输出文件是可执行的,并可由仿真器装入调试或被OHS51翻译为Intel HEX格式文件以供EPROM固化。下载以上(yshng)文件到本地硬盘(D:或E:)。谢谢第九十三页,共93页。
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


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

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


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