任务16制作波形发生器.docx
《任务16制作波形发生器.docx》由会员分享,可在线阅读,更多相关《任务16制作波形发生器.docx(33页珍藏版)》请在冰点文库上搜索。
任务16制作波形发生器
任务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位、12位等几种类型;按照输出模拟量的类型可分为电流输出型和电压输出型;按照DAC与微处理器的接口形式可分为串行DAC和并行DAC。
并行DAC占用的数据线多,输出速度快,但价格高;串行DAC占用的数据线少,方便隔离,性价比高,速度相对慢一些。
就目前的使用情况来看,工程上偏向于选用串行DAC。
在选择DAC芯片时,常涉及到以下3个技术参数:
⑴分辨率:
输入数字量变化1时,对应的输出模拟量的变化量。
分辨率反映了输出模拟量的最小变化值。
设DAC的数字量的位数为n,则DAC的分辨率=满量程电压/(2n-1)。
对于同等的满量程电压,DAC的位数越多,则分辨率越高。
因此,分辨率也常用DAC的数字量的位数来表示。
⑵转换时间:
从数字量输入至DAC开始到DAC完成转换并输出对应的模拟量所需要的时间。
转换时间反映了DAC的转换速度。
⑶满刻度误差:
数字量输入为满刻度(全1时),实际输出的模拟量与理论值的偏差。
2.带有SPI接口的D/A转换器MAX515的使用特性
MAX515是Maxin公司生产的10位串行电压输出型D/A转换器,转换建立时间为25µs,采用+5V单电源供电,供电流为140µA,具有简化的SPI总线接口,转换结果采用缓冲电压输出,可变输出电压为0~5V,最大线性误差为±1/2LSB。
⑴MAX515的引脚功能及其与单片机的接口电路
MAX515有DIP8和SOP8两种封装形式,其引脚分布如图7-34所示。
各引脚的功能如表7-11所示,MAX515与单片机的接口电路如图7-35所示。
⑵应用特性
MAX515的内部结构如图7-36所示、工作时序如图7-37所示。
图7-36MAX515内部结构
图7-37MAX515的工作时序
图7-37中各参数的含义如表7-12所示。
表7-12MAX515时序参数
参数
含义
参数值
单位
最小
典型
最大
tCSS
片选建立时间
20
ns
tCSH0
SCLK下降沿到片选下降沿保持时间
15
ns
tCSH1
SCLK下降沿到片选上升沿保持时间
0
ns
tCH
SCLK高电平宽度
35
ns
tCL
SCLK低电平宽度
35
ns
tDS
DIN建立时间
45
ns
tDH
DIN保持时间
0
ns
tDO
DOUT(级联输出)传输延时间
50
ns
tCSW
片选高电平宽度
20
ns
tCS1
片选上升沿到SCLK上升沿建立的时间间隔
50
ns
从图7-36、7-37中可以看出,MAX515的应用特性如下:
①在
、SCLK的作用下,DIN引脚输入的数据被移入MAX515内部的16位移位寄存器,每次输入的数据为16位。
这16位数据的格式如下:
D15~D12
D11~D2
D1D0
××××
C9~C0
00
其中,
D15~D12:
4位无效位,可为任意值。
D1D0:
固定为00。
D11~D2:
10位的DAC转换代码。
②设10位转换代码的对应值为daval,则将daval左移2位,即得到待写入MAX515的16位数据,其实现代码如下:
daval=daval<<2;
③MAX515的转换输出电压VOUT为:
式中,VREF为REFIN引脚输入的参考电压,此值一般不高于2.5V。
daval为10位的DAC转换代码值,其值为0~1023。
④
=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位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的条件下设计的,如果单片机的指令周期小于50ns,则需要在上述流程图的各框之间适当地插入若干个“_nop_();”语句进行延时,以满足表7-12中各时序参数的时间要求。
采用图7-35所示的接口电路时,MAX515各引脚口线的定义如下:
sbitDIN=P1^0;
sbitSCLK=P1^1;
sbitCS=P1^2;
MAX515的访问程序如下:
voidmax515(uintm)//1max515访问函数。
m为DA转换代码值
{uchari;//2定义局部变量。
i为循环次数计数器
m=m<<2;//3m左移2位形成写入max515的16位移位数据(低2位为00)
CS=1;//4片选置高电平
SCLK=0;//5时钟清0
CS=0;//6产生片选下降沿
for(i=0;i<16;i++)//7循环16次。
循环体为语句8~语句11
{DIN=(bit)(m&0x8000);//8m的最高位传送至数据线DIN上
SCLK=1;//9产生时钟上升沿
SCLK=0;//10产生时钟下降沿,形成一个完整的时钟信号
m=m<<1;//11m左移1位,准备写下一位数
}//12循环体结束
CS=1;//13产生片选上升沿,更新DAC
}//14函数结束
【任务实施】
1.搭建硬件电路
由MAX515的输出电压关系式得,任务16中MAX515的参考电压应选择2.5V,这样才能保证MAX515输出的最大电压为5V。
我们选用AD780作2.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,递减的时间间隔为T2,三角波上升阶段持续的时间为(TOP-BOTTOM)×T1,下降阶段持续时间为(TOP-BOTTOM)×T2,三角波的周期T=(TOP-BOTTOM)×(T1+T2)。
三角波发生器的流程图如图7-41所示。
图7-41三角波发生器的流程图
按图7-41所示的流程图编写的程序可以产生三角波,程序比较简单,也很好理解,但程序并不实用。
其主要的缺陷是,程序不能放在定时中断服务程序中,不能用定时中断实现程序的延时。
对图7-41所示流程图进行改进方法是,引入一个标志位updown,用updown标识程序的状态。
其中,updown=0表示是产生三角波的上升线阶段,updown=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所示。
图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时间时,将timcnt的计数值清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的定时中断服务函数中的方法是,将延时T0时间框去掉,把循环体中的其他部分放在定时中断服务程序中。
任务16所要产生的三角波为等腰三角波,我们采用图7-42所示的流程图,并将图中的延时T1时间框和延时T2时间框合并成一个框。
其中TOP=0,BOTTOM=1023,当T1=T0=488µs时,三角波的周期T=2046×488µs≈1s。
⑵程序代码
任务16的程序代码如下:
//任务16制作等腰三角波发生器
#include//1包含特殊功能寄存器定义头文件reg51.h
#defineucharunsignedchar//2宏定义:
uchar代表unsignedchar
#defineuintunsignedint//3宏定义:
uint代表unsignedint
#defineTOP1023//4宏定义:
TOP代表1023(峰值)
#defineBOTTOM0//5宏定义:
BOTTOM代表0(谷值)
sbitDIN=P1^0;//6定义MAX515的引脚线:
DIN接P1.0
sbitSCLK=P1^1;//7SCLK接P1.1
sbitCS=P1^2;//8CS接P1.2
voiddelay();//9delay函数说明
voidmax515(uint);//10max515函数说明
//----------------------------------
voidmain(void)//11main函数
{bitupdown=0;//12定义位变量updown。
0:
三角波的上升阶段
uintdaval=BOTTOM;//13定义变量daval(DA转换代码),初值为波谷值
while
(1)//14死循环,循环体为语句15~语句24
{max515(daval);//15调用max515函数进行D/A转换输出
if(updown)//16判断波形所处阶段,若为下降阶段,则处理语句17~语句19
{daval--;//17待转换值减1
if(daval}//19下降期处理结束
else//20若为上升阶段,则处理语句21~语句22
{daval++;//21待转换值加1
if(daval>TOP-1)updown=1;//22若达到峰值,则updown位置1
}//23上升期处理结束
delay();//24延时488μs
}//25死循环的循环体结束
}//26main函数结束
//----------------------------------
//max515函数
//功能:
向MAX515输入待转换的数字量m,并进行DAC转换更新
voidmax515(uintm)//27
{uchari;//28定义局部变量。
i为循环次数计数器
m=m<<2;//29m左移2位形成写入max515的16位移位数据(低2位为00)
CS=1;//30片选置高电平
SCLK=0;//31时钟清0
CS=0;//32产生片选下降沿
for(i=0;i<16;i++)//33循环16次。
循环体为语句34~语句37
{DIN=(bit)(m&0x8000);//34m的最高位传送至数据线DIN上
SCLK=1;//35产生时钟上升沿
SCLK=0;//36产生时钟下降沿,形成一个完整的时钟信号
m=m<<1;//37m左移1位,准备写下一位数
}//38循环体结束
CS=1;//39产生片选上升沿,更新DAC
}//40函数结束
//----------------------------------
//delay函数:
延时488μs
voiddelay(void)//41
{uchari;//42
for(i=27;i>0;i--);//43
}//44
【应用总结与拓展】
C51与汇编语言混合编程
单片机的应用程序一般采用C51编写,当程序中有对时间要求比较苛刻的程序时,例如要求精确延时的程序、时序苛刻的硬件控制程序等,可采用C51与汇编语言混合编程,用汇编语言编写对时间要求苛刻的程序,程序中的其他部分则用C51编写。
C51与汇编语言混合编程时,汇编代码可以直接嵌入在C51程序中,也可以放在单独的汇编程序模块文件中(后缀为asm或者SRC的文件)。
下面要介绍的编合编程是指汇编程序单独放在汇编程序模块文件中的混合编程(以下简称为混合编程),有关在C51程序中嵌入汇编程序代码的混合编程,我们已在任务4中作了详细介绍,在此不再赘述。
C51中,程序的调用分为无参数传递的调用、有参数传递的调用和有返回值的调用3种。
C51与汇编语言混合编程的最简便方法是,先编制被调汇编程序的哑函数,利用KeiC51生成哑函数对应的汇编程序框架结构,再在汇编程序框架结构中添加汇编程序代码,最后将C51程序与被调的汇编程序添加到工程中进行编译连接,生成所需要的目标程序。
采用这种方法进行混合编程时,可以避免汇编程序中复杂的段定义问题,用户只需掌握C51程序与汇编程序之间的参数传递方法和程序值返回的方法。
下面用实例介绍混合编程的具体方法。
1.无参数传递的混合编程
假定C51程序保存在c51.c文件中,C51程序中需要调用保存在a51.asm文件中的汇编程序delay,调用时无参数传递。
采用混合编程的方法如下:
⑴创建被调程序的哑函数
所谓哑函数是指只有函数参数定义、函数返回值定义、无函数体说明的函数。
创建哑函数的目的是为了生成被调汇编程序的框架结构。
本例中的哑函数如下:
voiddelay(void)
{}
创建被调程序的哑函数的方法如下:
第1步:
按照项目一中所介绍的方法,在KeiluVision2中新建工程名为mix的工程文件。
第2步:
新建2个不同名的C51程序文件c51.c和a51.c,并将这2个文件添加至mix工程中。
其中,c51.c为C51主调程序文件,a51.c为被调哑函数程序文件。
第3步:
在c51.c文件中录入所编制的C51程序代码,在a51.c文件中录入哑函数,如图7-44所示。
图7-44C51程序与哑函数
【说明】
由于被调程序delay与主调的C51程序不在同一个文件中,编写C51程序时,必须在主调文件的函数说明处用关键字“extern”对被调函数delay()进行说明。
其含义是,delay()是其他模块文件中定义的外部函数。
⑵产生哑函数对应的汇程序代码
操作步骤如下:
第1步:
用鼠标右键点击项目窗口中的被调函数的文件名a51.c,这时窗口中会弹出如图7-45所示的文件选项快捷菜单。
图7-45文件选项快捷菜单
第2步:
在快捷菜单中用鼠标左键点击“OptionsforFile’a51.c’”菜单项,这时窗口中会弹出如图7-46所示的文件选项对话框。
图7-46文件选项对话框
第3步:
在图7-46所示的文件选项对话框中,用鼠标左键点击“GenerateAssemblerSRCFile”(产生汇编SCR文件)和“AssembleSRCFile”(汇编SRC文件)前面的复选钮,使其由灰色状态变成白底黑勾的选中状态,然后点击“确定”按钮。
第4步:
在KeiluVision2的主窗口中点击编译图标按钮或者编译菜单命令,对mix工程中的源程序进行编译。
这时,KeilC51会产生一个与a51.c同名,但后缀名为SRC的a51.SRC文件。
a51.SRC文件的内容是a51.c中的哑函数对应的汇编程序,用KeiluVision2打开a51.SRC,我们可以看到其内容只是汇编程序delay的框架结构,如图7-47所示。
图7-47delay程序的框架结构
在图7-47中,我们可以看到,分号“;”后面的字符是绿色的,这一部分是汇编程序的注释,可以连分号一并删去,这样我们可以很直观地观察到哑函数delay()的汇编程序结构。
⑶编写汇编程序代码
操作步骤如下:
第1步:
关闭a51.SRC文件,将其后缀名改为asm,改名后的文件名为a51.asm,它与哑函数的主文件名同名,但文件类型为asm,表示是汇编程序文件。
【说明】
KeilC51支持对SRC文件的编译,但a51.SRC文件是KeilC51直接产生的汇编源程序。
在操作的过程中,如果没有把图7-46中的“GenerateAssemblerSRCFile”多选钮改成灰色不可用状态,重新编译时会将原来的a51.SRC文件覆盖掉,所以笔者建议读者最好是将其改为asm文件。
第2步:
添加汇编程序代码。
在KeiluVision2中打开被调程序文件a51.asm,删除其注释部分。
我们可以看到KeilC51生成的被调汇编程序的结构如下:
NAMEA51;1为模块命名,模块名为A51
?
PR?
delay?
A51SEGMENTCODE;2定义代码段,段名为?
PR?
delay?
A51
PUBLICdelay;3指定标识符(程序名)可在其他模块中使用
RSEG?
PR?
delay?
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;2R3赋初值4
DL1:
MOVR2,#250;3R2赋初值250,DL1为标号
DL2:
MOVR1,#250;4R1赋初值250,DL2为标号
DJNZR1,$;5R1减1后若不为0,则再执行本指令
DJNZR2,DL2;6R2减1后若不为0,则转至DL2处循环
DJNZR3,DL1;7R3减1后若不为0,则转至DL1处循环
RET;8程序返回
将上述汇编程序的第2行~第7行(去头去尾后的代码)添加至KeilC51生成的汇编框架结构的第6行中,保存文件,到此为止,混合编程的汇编程序已经编制完毕。
添加了汇编代码的delay程序如图7-48所示。
图7-48添加了汇编代码的delay程序
⑶编译混合程序
操作步骤如下:
第1步:
从mix工程中移除哑函数文件a51.c。
用鼠标右键点击项目窗口中的哑函数的文件名a51.c,在弹出的快捷菜单中用鼠标左键点击“RemoveFile‘a51.c’”菜单项,如图7-49所示。
图7-49移除文件快捷菜单
第2步:
将汇编程序文件a51.asm添加至mix工程中。
至此,mix工程由一个C51程序文件c51.c和一个被调的汇编程序文件a51.asm组成。
第3步:
设置输出文件。
用鼠标右键点击工程管理窗口中的“Target1”,在弹出的快捷菜单中点击“OptionforTarget‘Target1’”。
这时系统会出现“OptionforTarget‘Target1’”对话框。
在“OptionforTarget‘Target1’”对话框中点击Output标签。
在Output页面中勾选“CreateHEXFile”多选钮,如图7-50所示。
(详见项目1的任务实施中“第3步配置