任务16制作波形发生器_第1页
任务16制作波形发生器_第2页
任务16制作波形发生器_第3页
任务16制作波形发生器_第4页
任务16制作波形发生器_第5页
已阅读5页,还剩17页未读 继续免费阅读

下载本文档

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

文档简介

1、任务16 制作三角波发生器2011年2月11日整理完毕任务16制作波形发生器【任务要求】单片机的fosc=11.0592MHz,用P1.0、P1.1、P1.2三根I/O口线分别充当SPI总线的数据线、时钟线和片选线,外接带有SPI总线接口的串行D/A转换芯片MAX515,用单片机控制MAX515产生周期为1s、幅度为5V的等腰三角波。【相关知识】 任务16所涉及的新知识主要有D/A转换器的基础知识、带有SPI总线接口的D/A转换芯片MAX515的应用特性等。1 D/A转换器的基础知识D/A转换器的功能是将数字量转换成与数字量成比例的模拟量,常用DAC表示。按照待转换数字的位数可分为8位、10位

2、、12位等几种类型;按照输出模拟量的类型可分为电流输出型和电压输出型;按照DAC与微处理器的接口形式可分为串行DAC和并行DAC。并行DAC占用的数据线多,输出速度快,但价格高;串行DAC占用的数据线少,方便隔离,性价比高,速度相对慢一些。就目前的使用情况来看,工程上偏向于选用串行DAC。在选择DAC芯片时,常涉及到以下3个技术参数:分辨率:输入数字量变化1时,对应的输出模拟量的变化量。分辨率反映了输出模拟量的最小变化值。设DAC的数字量的位数为n,则DAC的分辨率=满量程电压/(2n-1)。对于同等的满量程电压,DAC的位数越多,则分辨率越高。因此,分辨率也常用DAC的数字量的位数来表示。转

3、换时间:从数字量输入至DAC开始到DAC完成转换并输出对应的模拟量所需要的时间。转换时间反映了DAC的转换速度。满刻度误差:数字量输入为满刻度(全1时),实际输出的模拟量与理论值的偏差。2 带有SPI接口的D/A转换器MAX515的使用特性MAX515是Maxin公司生产的10位串行电压输出型D/A转换器,转换建立时间为25µs,采用+5V单电源供电,供电流为140µA,具有简化的SPI总线接口,转换结果采用缓冲电压输出,可变输出电压为05V,最大线性误差为±1/2LSB。MAX515的引脚功能及其与单片机的接口电路MAX515有DIP8和SOP8两种封装形式,其

4、引脚分布如图7-34所示。各引脚的功能如表7-11所示,MAX515与单片机的接口电路如图7-35所示。表7-11MAX515的引脚功能引脚符号功能1DIN串行数据输入脚2SCLK时钟输入脚3片选引脚。低电平时,对MAX515访问有效,上升沿更新内部DAC4DOUT串行级联数据输出脚。5AGND模拟信号地6REFIN参考电压输入脚7VOUTDA转换电压输出8VDD+5V电源输入图7-34MAX515引脚分布图7-35MAX515与单片机的接口电路应用特性MAX515的内部结构如图7-36所示、工作时序如图7-37所示。图7-36MAX515内部结构图7-37MAX515的工作时序图7-37中各

5、参数的含义如表7-12所示。表7-12MAX515时序参数参数含义参数值单位最小典型最大tCSS片选建立时间20nstCSH0SCLK下降沿到片选下降沿保持时间15nstCSH1SCLK下降沿到片选上升沿保持时间0nstCHSCLK高电平宽度35nstCLSCLK低电平宽度35nstDSDIN建立时间45nstDHDIN保持时间0nstDODOUT(级联输出)传输延时间50nstCSW片选高电平宽度20nstCS1片选上升沿到SCLK上升沿建立的时间间隔50ns从图7-36、7-37中可以看出,MAX515的应用特性如下:在、SCLK的作用下,DIN引脚输入的数据被移入MAX515内部的16位

6、移位寄存器,每次输入的数据为16位。这16位数据的格式如下:D15D12D11 D2D1 D0××××C9 C00 0其中,D15D12:4位无效位,可为任意值。D1D0:固定为00。D11D2:10位的DAC转换代码。设10位转换代码的对应值为daval,则将daval左移2位,即得到待写入MAX515的16位数据,其实现代码如下:daval=daval<<2;MAX515的转换输出电压VOUT为下面的公式修改过:式中,VREF为REFIN引脚输入的参考电压,此值一般不高于2.5V。daval为10位的DAC转换代码值,其值为01023。=

7、1时,DIN引脚上的数据不能移入MAX515,只有=0时,数据才能移入MAX515;出现上升沿时,10位的转换代码传输至10位的DAC寄存器,并更新DAC。在=0的条件下,在SCLK的上升沿,MAX515将DIN引脚上的数据移入到内部移位寄存器中。所以,向MAX515写数时,应先将数位写入DIN引脚上,然后产生时钟的上升沿。移位的次序为高位在先低位在后。下沿之前,SCLK应为低电平,上沿之前SCLK也为低电平。MAX515的最高时钟频率由1/(tCH+tCL)决定,大约是14MHz,数据更新率受到片选周期的限制,其周期为16(tCH+tCL)+ tCSW,相当于1.14µs。由于10

8、位D/A转换器的建立时间为25µs,实际使用时,MAX515的输出更新率不高于40KHz。MAX515的访问编程对MAX515编程访问主要是用软件模拟MAX515的工作时序,在编写程序时要注意以下问题:每次写数为16位;高位先发送(数据移位的方向为左移);先将数位写入DIN引脚,然后产SCLK的上升沿;SCLK高低电平持续时间、片选与SCLK上升沿或下降沿之间的间隔必须符合表7-12中的规定。按照MAX515的工作时序图,MAX515的访问程序的流程图如图7-38所示。图7-38MAX515访问程序流程图【说明】图7-38所示的流程图是在单片机的指令周期大于50ns的条件下设计的,如

9、果单片机的指令周期小于50ns,则需要在上述流程图的各框之间适当地插入若干个“_nop_();”语句进行延时,以满足表7-12中各时序参数的时间要求。采用图7-35所示的接口电路时,MAX515各引脚口线的定义如下:sbitDIN=P10;sbitSCLK=P11;sbitCS=P12;MAX515的访问程序如下:voidmax515(uintm)/1 max515访问函数。m为DA转换代码值uchari;/2 定义局部变量。i为循环次数计数器m=m<<2;/3 m左移2位形成写入max515的16位移位数据(低2位为00)CS=1;/4 片选置高电平SCLK=0;/5 时钟清0C

10、S=0;/6 产生片选下降沿for(i=0;i<16;i+)/7 循环16次。循环体为语句8语句11DIN=(bit)(m&0x8000);/8 m的最高位传送至数据线DIN上SCLK=1;/9 产生时钟上升沿SCLK=0;/10 产生时钟下降沿,形成一个完整的时钟信号m=m<<1;/11 m左移1位,准备写下一位数/12 循环体结束CS=1;/13 产生片选上升沿,更新DAC/14 函数结束【任务实施】1 搭建硬件电路由MAX515的输出电压关系式得,任务16中MAX515的参考电压应选择2.5V,这样才能保证MAX515输出的最大电压为5V。我们选用AD780作2

11、.5V稳压电源,给MAX515提供精准的2.5V参考电压。任务16的硬件电路如图7-39所示。图7-39 任务16硬件电路2 编写软件程序流程图等腰三角波的波形图如图7-40所示。图7-40等腰三角波的波形图一个周期的三角波可分为2个阶段,一是从波谷到波峰的线性上升阶段,二是从波峰到波谷的线性下降阶段。设波谷对应的D/A转换值为BOTTOM,波峰对应的D/A转换值为TOP。D/A转换值daval由BOTTOM线性递增至TOP就产生了三角波的上升阶段波形,当D/A转换值daval增加至TOP后线性递减至BOTTOM就产生了三角波的下降阶段波形。若D/A转换值daval递增的时间间隔为T1,递减的

12、时间间隔为T2,三角波上升阶段持续的时间为(TOP-BOTTOM)×T1,下降阶段持续时间为(TOP-BOTTOM)×T2,三角波的周期T=(TOP-BOTTOM)×(T1+T2)。三角波发生器的流程图如图7-41所示。图7-41三角波发生器的流程图按图7-41所示的流程图编写的程序可以产生三角波,程序比较简单,也很好理解,但程序并不实用。其主要的缺陷是,程序不能放在定时中断服务程序中,不能用定时中断实现程序的延时。对图7-41所示流程图进行改进方法是,引入一个标志位updown,用updown标识程序的状态。其中,updown=0表示是产生三角波的上升线阶段,u

13、pdown=1表示是产生三角波的下降线阶段。在初始化程序中将updown的值设置为0,表示程序先产生三角波的上升线。在循环体中对updown进行判断,updown=0 (产生上升线阶段) 时,对D/A转换值daval作线性递增的转换输出,并延时T1时间,当daval达到峰值TOP时,将标志位updown置1,表示下次进行循环体时,进入产生三角波的下降线阶段。updown=1(产生下降线阶段)时,对D/A转换值daval作线性递减的转换输出,并延时T2时间,当daval达到谷值BOTTOM时,将标志位updown清0,表示下次进行循环体时,进入产生三角波的上升线阶段。改进后的流程图如图7-42所

14、示。图7-42三角波发生器的改进后流程图对于等腰三角波发生器,T1时间与T2时间相等。将图7-42所示流程图中的延时T1时间与延时T2时间2个框去掉,把循环体中的其他部分放在定时时长为T1的定时中断服务函数中就可以用2次中断服务之间的时间间隔来实现延时。如果T1时间与T2时间不相等,可以按以下方法对图7-42所示的流程图作进一步的改造:设T1、T2的最大公约数为T0,将程序设计成时间间隔为T0时间的循环程序,引入一个软件计数器timcnt,用timcnt对T0时间的循环次数进行计数。在产生上升线阶段,当timcnt计时不满T1时间时,只作T0时间的延时处理。当timcnt计时满T1时间时,将t

15、imcnt的计数值清0,然后作daval递增的转换输出,延时T0时间后再次进入循环体。在产生下降线阶段,当timcnt计时不满T2时间时,只作T0时间的延时处理。当timcnt计时满T2时间时,将timcnt的计数值清0,然后作daval递减的转换输出,延时T0时间后再次进入循环体。其流程图如图7-43所示。图7-43循环周期为T0时间的三角发生器流程图图7-43与图7-41相比,两者功能一样,但按图7-43所示的流程图编写的程序可以用定时中断实现软件延时,一方面可以减轻CPU的负担,另一方面可以方便使用CPU睡眠技术提高程序的抗干扰性。将图7-43所示流程图对应的程序放在定时时长为T0的定时

16、中断服务函数中的方法是,将延时T0时间框去掉,把循环体中的其他部分放在定时中断服务程序中。任务16所要产生的三角波为等腰三角波,我们采用图7-42所示的流程图,并将图中的延时T1时间框和延时T2时间框合并成一个框。其中TOP=0,BOTTOM=1023,当T1=T0=488µs时,三角波的周期T=2046×488µs1s。程序代码任务16的程序代码如下:/任务16制作等腰三角波发生器#include<reg51.h>/1 包含特殊功能寄存器定义头文件reg51.h#defineucharunsignedchar/2 宏定义:uchar代表unsigne

17、d char#defineuintunsignedint/3 宏定义:uint代表unsigned int#defineTOP1023/4 宏定义:TOP代表1023(峰值)#defineBOTTOM0/5 宏定义:BOTTOM代表0(谷值)sbitDIN=P10;/6 定义MAX515的引脚线:DIN接P1.0sbitSCLK=P11;/7 SCLK接P1.1sbitCS=P12;/8 CS接P1.2voiddelay();/9 delay函数说明voidmax515(uint);/10 max515函数说明/-voidmain(void)/11 main函数bitupdown=0;/12

18、定义位变量updown。0:三角波的上升阶段uintdaval=BOTTOM;/13 定义变量daval(DA转换代码),初值为波谷值while(1)/14 死循环,循环体为语句15语句24max515(daval);/15 调用max515函数进行D/A转换输出if(updown)/16 判断波形所处阶段,若为下降阶段,则处理语句17语句19daval-;/17 待转换值减1if(daval<BOTTOM+1)updown=0;/18 若达到谷值,则updown位清0/19 下降期处理结束else/20 若为上升阶段,则处理语句21语句22daval+;/21 待转换值加1if(dav

19、al>TOP-1)updown=1;/22 若达到峰值,则updown位置1/23 上升期处理结束delay();/24 延时488s/25 死循环的循环体结束/26 main函数结束/-/max515函数/功能:向MAX515输入待转换的数字量m,并进行DAC转换更新voidmax515(uintm)/27 uchari;/28 定义局部变量。i为循环次数计数器m=m<<2;/29 m左移2位形成写入max515的16位移位数据(低2位为00)CS=1;/30 片选置高电平SCLK=0;/31 时钟清0CS=0;/32 产生片选下降沿for(i=0;i<16;i+)/

20、33 循环16次。循环体为语句34语句37DIN=(bit)(m&0x8000);/34 m的最高位传送至数据线DIN上SCLK=1;/35 产生时钟上升沿SCLK=0;/36 产生时钟下降沿,形成一个完整的时钟信号m=m<<1;/37 m左移1位,准备写下一位数/38 循环体结束CS=1;/39 产生片选上升沿,更新DAC/40 函数结束/-/delay函数:延时488svoiddelay(void)/41 uchari;/42 for(i=27;i>0;i-);/43 /44 【应用总结与拓展】C51与汇编语言混合编程单片机的应用程序一般采用C51编写,当程序中有

21、对时间要求比较苛刻的程序时,例如要求精确延时的程序、时序苛刻的硬件控制程序等,可采用C51与汇编语言混合编程,用汇编语言编写对时间要求苛刻的程序,程序中的其他部分则用C51编写。C51与汇编语言混合编程时,汇编代码可以直接嵌入在C51程序中,也可以放在单独的汇编程序模块文件中(后缀为asm或者SRC的文件)。下面要介绍的编合编程是指汇编程序单独放在汇编程序模块文件中的混合编程(以下简称为混合编程),有关在C51程序中嵌入汇编程序代码的混合编程,我们已在任务4中作了详细介绍,在此不再赘述。C51中,程序的调用分为无参数传递的调用、有参数传递的调用和有返回值的调用3种。C51与汇编语言混合编程的最

22、简便方法是,先编制被调汇编程序的哑函数,利用Kei C51生成哑函数对应的汇编程序框架结构,再在汇编程序框架结构中添加汇编程序代码,最后将C51程序与被调的汇编程序添加到工程中进行编译连接,生成所需要的目标程序。采用这种方法进行混合编程时,可以避免汇编程序中复杂的段定义问题,用户只需掌握C51程序与汇编程序之间的参数传递方法和程序值返回的方法。下面用实例介绍混合编程的具体方法。1 无参数传递的混合编程假定C51程序保存在c51.c文件中,C51程序中需要调用保存在a51.asm文件中的汇编程序delay,调用时无参数传递。采用混合编程的方法如下:创建被调程序的哑函数所谓哑函数是指只有函数参数定

23、义、函数返回值定义、无函数体说明的函数。创建哑函数的目的是为了生成被调汇编程序的框架结构。本例中的哑函数如下:voiddelay(void)创建被调程序的哑函数的方法如下:第1步:按照项目一中所介绍的方法,在Keil uVision2中新建工程名为mix的工程文件。第2步:新建2个不同名的C51程序文件c51.c和a51.c,并将这2个文件添加至mix工程中。其中,c51.c为C51主调程序文件,a51.c为被调哑函数程序文件。第3步:在c51.c文件中录入所编制的C51程序代码,在a51.c文件中录入哑函数,如图7-44所示。c51.c文件中的程序要调用a51.c中的delay函数,在c51

24、.c文件中要用extern将delay说明成外部函数。图7-44C51程序与哑函数【说明】由于被调程序delay与主调的C51程序不在同一个文件中,编写C51程序时,必须在主调文件的函数说明处用关键字“extern”对被调函数delay()进行说明。其含义是,delay()是其他模块文件中定义的外部函数。产生哑函数对应的汇程序代码操作步骤如下:第1步:用鼠标右键点击项目窗口中的被调函数的文件名a51.c,这时窗口中会弹出如图7-45所示的文件选项快捷菜单。图7-45文件选项快捷菜单第2步:在快捷菜单中用鼠标左键点击“Options for Filea51.c”菜单项,这时窗口中会弹出如图7-4

25、6所示的文件选项对话框。图7-46文件选项对话框第3步:在图7-46所示的文件选项对话框中,用鼠标左键点击“Generate Assembler SRC File”(产生汇编SCR文件)和“Assemble SRC File”(汇编SRC文件)前面的复选钮,使其由灰色状态变成白底黑勾的选中状态,然后点击“确定”按钮。第4步:在Keil uVision2的主窗口中点击编译图标按钮或者编译菜单命令,对mix工程中的源程序进行编译。这时,Keil C51会产生一个与a51.c同名,但后缀名为SRC的a51.SRC文件。a51.SRC文件的内容是a51.c中的哑函数对应的汇编程序,用Keil uVis

26、ion2打开a51.SRC,我们可以看到其内容只是汇编程序delay的框架结构,如图7-47所示。图7-47delay程序的框架结构在图7-47中,我们可以看到,分号“;”后面的字符是绿色的,这一部分是汇编程序的注释,可以连分号一并删去,这样我们可以很直观地观察到哑函数delay()的汇编程序结构。编写汇编程序代码操作步骤如下:第1步:关闭a51.SRC文件,将其后缀名改为asm,改名后的文件名为a51.asm,它与哑函数的主文件名同名,但文件类型为asm,表示是汇编程序文件。【说明】Keil C51支持对SRC文件的编译,但a51.SRC文件是Keil C51直接产生的汇编源程序。在操作的过

27、程中,如果没有把图7-46中的“Generate Assembler SRC File”多选钮改成灰色不可用状态,重新编译时会将原来的a51.SRC文件覆盖掉,所以笔者建议读者最好是将其改为asm文件。第2步:添加汇编程序代码。在Keil uVision2中打开被调程序文件a51.asm,删除其注释部分。我们可以看到Keil C51生成的被调汇编程序的结构如下:NAMEA51;1 为模块命名,模块名为A51?PR?delay?A51SEGMENT CODE;2 定义代码段,段名为?PR?delay?A51PUBLICdelay;3 指定标识符(程序名)可在其他模块中使用RSEG ?PR?del

28、ay?A51;4 为段?PR?delay?A51选择一个可重新定位的段delay:;5 程序开始,delay为程序名,冒号不可省;6 在这里添加汇编程序代码RET;7 程序返回指令END;8 模块结束程序中,第5行是汇编程序的程序名,它与哑函数的名字相同,其后有冒号,为汇编程序的开始处。第7行是程序的返回指令,第6行是空白行,是程序delay的指令行,供我们在这里添加程序代码。假定delay程序是500ms的延时程序,单片机的fosc=12MHz,则500ms延时程序代码如下:delay:;1 程序开始,delay为程序名MOVR3,#4;2 R3赋初值4DL1:MOVR2,#250;3 R2

29、赋初值250,DL1为标号DL2:MOVR1,#250;4 R1赋初值250,DL2为标号DJNZR1,$;5 R1减1后若不为0,则再执行本指令DJNZR2,DL2;6 R2减1后若不为0,则转至DL2处循环DJNZR3,DL1;7 R3减1后若不为0,则转至DL1处循环RET;8 程序返回将上述汇编程序的第2行第7行(去头去尾后的代码)添加至Keil C51生成的汇编框架结构的第6行中,保存文件,到此为止,混合编程的汇编程序已经编制完毕。添加了汇编代码的delay程序如图7-48所示。图7-48添加了汇编代码的delay程序编译混合程序操作步骤如下:第1步:从mix工程中移除哑函数文件a5

30、1.c。用鼠标右键点击项目窗口中的哑函数的文件名a51.c,在弹出的快捷菜单中用鼠标左键点击“Remove File a51.c”菜单项,如图7-49所示。图7-49移除文件快捷菜单第2步:将汇编程序文件a51.asm添加至mix工程中。至此,mix工程由一个C51程序文件c51.c和一个被调的汇编程序文件a51.asm组成。第3步:设置输出文件。用鼠标右键点击工程管理窗口中的“Target 1”,在弹出的快捷菜单中点击“Option for Target Target 1”。这时系统会出现 “Option for Target Target 1”对话框。在“Option for Target

31、 Target 1”对话框中点击Output标签。在Output页面中勾选“Create HEX File”多选钮,如图7-50所示。(详见项目1的任务实施中“第3步 配置工程”)勾选此项,编译、连接后会生成HEX文件图7-50设置输出文件第4步:编译、连接。在Keil uVision2的主窗口中点击重新编译图标按钮“”或者点击菜单栏上的“Project”“Reuild all target files”菜单命令,对mix工程中的源程序进行编译、连接。这时,Keil uVision2会生成目标文件mix.hex。2 有参数传递的混合编程有参数传递的混合编程的过程与无参数传递的混合编程的过程完全

32、相同,在此不再赘述。但是,由于C51程序调用汇编程序时存在参数传递,编写汇编程序时必须找到参数存放的位置和存放的格式,并且正确地接收这些参数,才能编写出正确的汇编程序。C51程序是用当前工作寄存器R7R1或者单片机的存储器传递参数的,其中存储器是汇编程序中定义的位段或者字节段。函数名变换规则C51函数编译时,Keil C51会根据函数的类型按表7-13所示的规则将函数名转换成汇编程序名:表7-13函数名转换规则函数类型C51函数汇编程序转换规则无参数传递func(void)func:名字不变有参数传递第1个参数为bit型func(bit,char)func:名字不变第1个参数为非bit型fun

33、c(char,bit)_func:名字前加下划线Keil C51生成的位段函数的参数中含有位参数时,Keil C51会在所生成的汇编程序中自动地定义位段,并且按照位参数在参数表中出现的顺序在位段中依次为各位参数分配存储空间。Keil C51生成的位段的格式如下:?BI?程序名?模块名 SEGMENT BIT OVERLAYABLE ;1 位段的段名为“?BI?程序名?模块名”PUBLIC?程序名?BIT;2 指明符号地址“?程序名? BIT”可在其他模块中访问RSEG ?BI?程序名?模块名;3 重定位位段“?BI?程序名?模块名”?程序名?BIT:;4 位参数表的首地址,供模块外的程序访问位

34、参数之用位名1: DBIT 1;5 第1个位参数的定义,“位名1”是访问的符号地址位名2: DBIT 1;6 第2个位参数的定义,“位名2”是访问的符号地址位名n: DBIT 1;7 第n个位参数的定义,“位名n”是访问的符号地址程序中,第1行第3行主要是位段的说明,供Keil C51使用,用户不必关心,只要不修改就可以了。第4行中的“?程序名?BIT”是符号地址,代表的是位参数表的首地址,C51程序调用汇编程序时,通过该地址给各位参数赋值,第4行决不可修改。第5行第7行依次是哑函数中各位参数的存储空间的定义说明。第5行(第1个DBIT定义)对应第1个位参数,第6行(第2个DBIT定义)对应第

35、2个位参数,依次类推。其中,冒号(:)前面的符号是位参数的符号位地址,供汇编程序中访问位参数之用。DBIT是汇编伪指令,其含义是保留若干位,即分配若位的存储空间。“DBIT 1”的含义是在位段中为位参数分配1位的存储空间。Keil C51生成的字节段函数的参数中含有非bit型的参数时,Keil C51会在所生成的汇编程序中自动地定义字节段,并且按照非bit型参数的类型及其在参数表中出现的顺序在字节段中依次为各非bit型参数分配存储空间。Keil C51生成的字节段的格式如下:?DT?程序名?模块名SEGMENT DATA OVERLAYABLE ;1 字节段的段名为“?DT?程序名?模块名”P

36、UBLIC?程序名?BYTE;2 指明符号地址“?程序名?BYTE”可在其他模块中访问RSEG ?DT?程序名?模块名;3 重定位字节段“?DT?程序名?模块名”?程序名?BYTE:;4 符号地址“?程序名?BYTE”,供C51程序访问名字1:DSn1;5 第1个非bit型参数的存储空间名字2:DSn2;6 第2个非bit型参数的存储空间名字n:DSk;7 第n个非bit型参数的存储空间程序中,第1行第3行主要是字节段的说明,供Keil C51使用,用户不必关心,只要不修改就可以了。第4行中的“?程序名?BYTE”是符号地址,代表的是非bit型参数表的首地址,C51程序调用汇编程序时,若需要通

37、过存储器传递非bit型参数,则通过引用该符号地址给对应的非bit型参数赋值。所以,第4行决不能修改。第5行第7行依次是哑函数中各非bit型参数的存储空间的定义说明。第5行(第1个DS定义)对应第1个非bit型参数,第6行(第2个DS定义)对应第2个非bit型参数,依次类推。其中,冒号(:)前面的符号是非bit型参数的首字节的符号地址,供汇编程序中访问非bit型参数之用。DS是汇编伪指令,其含义是保留若干个字节,即在字节段中为非bit型参数分配若干个字节的存储空间,DS后面的常数是所分配的字节数。若用label表示非bit型参数的首字节的符号地址,各类参数分配的存储空间以及各字节的作用如表7-1

38、4所示。表7-14各类参数分配的存储空间及其含义参数类型字节数各字节的作用char1int2高字节在label中,低字节在label+1中long4最高字节在label中,最低字节在label+3中float432位IEEE格式,指数和符号位在label+3中基于存储器的指针data *1地址在label中idata *pdata *xdata *2地址的高字节在label中,地址的低字节在label+1中code *一般指针3存储类型在label中,地址的高字节在label+1中,地址的低字节在label+2中例如,哑函数“voidfunc(longx,inty,charz)”编译后,各参数

39、的存储空间的定义如下:RSEG ?DT?_func?A51?_func?BYTE: x?040: DS 4 y?041: DS 2 z?042: DS 1x?040是第1个参数x的首字节地址,x分配有4个字节的存储空间,x?040单元用于存放x的最高字节数,x?040+3单元用于存放x的最低字节数。若x=0x12345678,则x?040单元中存放的是0x12,x?040+1单元中存放的是0x34,x?040+2单元中存放的是0x56,x?040+3单元中存放的是0x78。将参数x的值传送到R4R5R6R7(R4中存放高字节数)中的程序代码如下:MOVR4,x?040MOVR5,x?040+1

40、 MOVR6,x?040+2MOVR7,x?040+3y?041是第2个参数y的首字节地址,y分配有2个字节的存储空间,y?041单元用于存放参数y的高字节数,y?041+1单元用于存放y的低字节数。若y=0x1234,则y?041单元中存放的是0x12,y?041+1单元中存放的是0x34。将参数y的值传送到R6R7(R6存入高字节数)中的程序代码如下:MOVR6,y?041MOVR7,y?041+1z?042是第3个参数z的首字节地址,z分配有1个字节。参数传递的规则Keil C51中,C51程序调用汇编程序时,按以下规则进行参数传递:依据参数在参数表中出现的顺序,优先选用当前工作寄存器组

41、中的R7R1进行参数传递,并且各个参数传递所使用的寄存器为固定的寄存器。参数传递所使用的寄存器如表7-15所示。表7-15参数传递所使用的寄存器参数类型第1个参数第2个参数第3个参数说明bit位存储器位存储器位存储器charR7R5R3intR6R7R4R5R2R3R6、R4、R2为高字节longR4R5R6R7R4R5R6R7R4R5R6R7R4为最高字节,R7为最低字节floatR4R5R6R7R4R5R6R7R4R5R6R732位IEEE格式,指数和符号位在R7 基于存储器的指针data *R7R5R3idata *pdata *xdata *R6R7R4R5R2R3R6、R4、R2为所

42、指向地址的高字节内容code *一般指针R1R2R3R1R2R3R1R2R3R3存放存储类型,R1存放地址的高字节内容,R1存放地址的低字节内容。例如,函数func(char x,char y,int z)中,x用R7传递,y用R5传递,z用R2R3传递,其中R2传递z的高字节内容,R3传递z的低字节内容。函数func(int x,char y,char data * z)中,x用R6R7传递,其中R6传递x的高字节内容,R7传递x的低字节内容。y用R5传递,z用R3传递。位参数以及位参数以后的参数均使用存储器传递。其中,位参数采用位段中的对应位进行传递,其他参数采用字节段中的对应的存储单元进

43、行传递。例如,函数func(int x,bit y,char z) 编译后,位段和字节段中各参数的存储空间的定义如下:RSEG ?DT?_func?A51?_func?BYTE: x?040: DS 2 z?042: DS 1RSEG ?BI?_func?A51?_func?BIT: y?041: DBIT 1x用R6R7传递,其中,R6传递x的高字节,R7传递x的低字节。y用y?041位传递,z用z?042字节传递。x?040和x?040+1两个字节并没有用作参数传递。C51程序中,调用函数的语句“func(5,1,2);”所对应的汇编程序如下:SETB ?_func?BIT;y用位存储器传

44、递,位参数y置1MOV ?_func?BYTE+02H,#02H;z用存储器传递,参数z赋数2MOV R7,#05H;x用R6R7传递,x的低字节赋数5MOV R6,#00H;x的高字节赋数0LCALL_func;调用子程序_func哑函数func(int x,bit y,char z)的汇编代码如下:RSEG ?PR?_func?A51_func:MOV x?040,R6;将x参数的值保存至存储单元中(函数调用时,x参数用R6R7传递,MOV x?040+01H,R7;其他参数用存储器传递,x?040、x?040+1为存放x参数的地址); ; SOURCE LINE # 3RET某个参数对应的寄存器被前面的参数传递占用时,该参数以及该参数以后的所有参数均用存储器传递。存储器的选择与规则2中的存储器选择相同。例如,函数func(char *fp,long y,char z)中,fp用R1R2R3传递,y用R4R5R6R7传递,x的传递占用了z传递所用的寄存器R3,所以,z使用存储器传递。函数func(float x,long y,char z)中,x用R4R5R6R7传递,它占用了参数y传递所用的寄存器,所以,y、z都用存储器传递。3 有返回值的混合编程有返回值的混合编程的过程与

温馨提示

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

评论

0/150

提交评论