基于51单片机TLV5616信号发生器论文Word格式.docx
《基于51单片机TLV5616信号发生器论文Word格式.docx》由会员分享,可在线阅读,更多相关《基于51单片机TLV5616信号发生器论文Word格式.docx(20页珍藏版)》请在冰豆网上搜索。
AT89C单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
外形及引脚排列如下图所示:
AT89C51管脚说明:
VCC:
供电电压。
GND:
接地。
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P1口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
图3AT89C51引脚图
P1口:
P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。
在FLASH编程和校验时,P1口作为第八位地址接收。
P2口:
P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流。
这是由于内部上拉的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:
P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。
当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。
作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
RST:
复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:
当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:
每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;
当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:
反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:
来自反向振荡器的输出。
我们进行实验时,需要对应好仿真芯片和89c51的引脚关系,进行合理的分配,需要注意的是,P1口无法驱动数码管显示,所以我们调整了管脚连接,让P0口进行数码管显示,P1口用于和DA芯片的数据传输。
2TLV5616介绍:
1)制作该信号发生器的核心是DA转换芯片,它将数字量的变化转换成了模拟量的变化,从而实现能够在示波器上进行显示,TLV5616是一个12位电压输出数模转换器(DAC),相对来说分辨率较高带有灵活的4线串行接口,可以无缝连接TMS320、SPI、QSPI和Microwire串行口。
数字电源和模拟电源分别供电,电压范围2.7~5.5V。
输出缓冲是2倍增益rail-to-rail输出放大器,输出放大器是AB类以提高稳定性和减少建立时间。
rail-to-rail输出和关电方式非常适宜单电源、电池供电使用。
通过控制字可以优化建立时间和功耗比。
图45616芯片引脚图
图中,VDD和AGND为电源端和接地端,DIN,OUT为数据输入端和输出端,REFIN应给予2.7-5.5v的参考电压,此电压根据所需波形的复制而定。
2)5616的十六位数据值包括两部分:
控制字(D15-D12)
新的DAC值(D11-D0)
注:
X可为1可为0.
SPD:
速度控制字。
为1时,高速模式,为0时,低速模式。
PWR:
功率控制字。
为1时,掉电模式,为0时,正常模式。
图5时序图
D15
D14
D13
D12
D11-D0
X
SPD速度控制字
PWR功率控制字
新DAC值
表15616十六位数据格式
3)硬件连接
如图5,是5616和51单片机的连接模式,5616接口方式为SPI模式,可和单片机兼容。
图65616和单片机连接图
2-3软件设计
2-3.1软件程序流程图如下:
需要明确的是,该设计最核心的部分是信号发生部分,要想完成此设计,最先应该设计的是怎样产生各种波形,只有产生了波形,才会有后续进行精确地调试,产生完波形后,需要完成单片机和5616之间的数据通信,编写程序,可以先编写该程序进行数据传送的调试。
图7程序流程图
2-3.2发送数据子程序:
DA5616是SPI总线的传送形式,在单片机和其传送过程中,初始化后,单片机逐位将数据送入,此过程受到DA芯片的选通以及时钟时序的控制。
2-3.3波形产生过程
1)方波产生过程
方波的实现只需开始的时候设置一个初值然后直接输出这个值就行了,输出一段时间后,然后再重新置一个数据,然后再输出这个数据一段时间,但是此时的时间一定要等于前面那段时间。
这样才是一个方波。
由此可以调节两个电压维持的时间,产生占空比不同的方波,相比于模拟电驴,这样的方式输出的方波占空比更加精确,且电压更加稳定。
2)齿波产生过程
锯齿波的实现过程是首先定义一个初值然后进行加法操作,加的步数的多少则根据要求的频率来进行。
然后加到某个数之后就再重新设置为初值,再重复执行刚刚的操作,如此循环下去。
这样产生的锯齿波可以通过调节循环中的延时时间调节频率,再通过加法的最大值来控制输出的最高电压。
图8DA数据发送
3)三角波产生过程
三角波的输出的基础是锯齿波,将锯齿波的产生当作是三角波的前半部分,然后再相反的举行减法,逐渐减为零,如此循环,即可产生三角波。
类似的,通过改变延时时间可以改变输出的频率,通过改变最大值,可以改变输出的电压。
输出的波形连续性好,且波形很光滑。
4)正弦波产生过程
正弦波的实现实际上是一个查表过程,所查的每一个值都对应着一个电压,并且对应着的电压汇成图形即为正弦波,然后重复这样一个过程即可产生连续的正弦波.产生的正弦波,波形光滑且频率可调。
3功能拓展
1)尝试用C语言,以及汇编语言两种语言来编辑程序,设计思路大致相同,并且能够正常运行,且输出良好波形。
2)加入按键控制,通过控制按键,即可控制波形发生器发出的波形,以及波形的频率,由于时间原因,只设计了三个频率档位。
相比较来说,通过按键控制可以更加方便的控制输出波形,以及频率。
设置的程序思路是:
通过单片机扫描按键,扫描到按下的按键K1,就切换波形发生的子程序;
扫描到按下的按键K2,就赋予波形子程序中的延时函数所选择的数值。
4调试及实验结果
输出波形图如下:
图9方波
图10三角波
图11正弦波
最终,我们将程序导入仿真芯片,经过调试后,我们得到了四种波形,并能利用按键进行频率和波形的切换并显示,很好地完成了设计任务。
得到的波形中,方波和锯齿波以及三角波的波形通过延时子程序调试后,输出比较理想的波形。
正弦波由于打入一周期的时间过长,速度太慢,出现了波形看起来像是一个点沿正弦曲线运动的现象,而该5616的快速模式又不能正常工作,所以只能先保持这样的波形,而且产生的波形的频率有所限制,无法产生较高频率的波形,再有,为了打入一个数据的速度更快,没有完全发挥12位DA的优势,只是用了它的低8位惊醒数据编码。
5实验中遇到的问题
5-1错误
1)最初用DA调试波形时,怎样改变电路都无法使DA输出波形。
后将DA的工作模式设置为慢速模式,才使芯片输出正常波形。
2)调试正弦波时,正弦波的频率太小,周期太长,及时将延时缩短,甚至消除都无法使示波器显示正常的连续的波形。
后将程序中调用的数组中的由256减少到96后,波形方能正常显示。
3)按键引入扫描程序时,无法使按键正常工作。
最后查出原因是编程时,调用子程序的问题。
4)在用数码管显示频率时,数码管部分亮部分暗,经过检测电路,发现实验台上P1口不能驱动数码管,后改为用P0口才可正常驱动。
5-2不足
1)由于对于速度的要求,没有用定时器定时输出,产生波形频率值不准确
2)没有发挥12位DA较高分辨率的优势,只用了它的低八位
3)由于写入速度的限制,产生的波形频率的范围不广,无法产生较高频率的波形
4)产生的正弦波由于写入周期较长,无法同时显示较多的波形
6心得体会
通过这次课程设计,令我们对单片机有了更好的掌握,锻炼了我们的编程能力,在课程设计中,我们遇到的最大的挑战,就是对程序的调试,我们收获最大的地方也在于此,我们需要逐条运行每一小段调试程序,逐段逐句进行编程调试,我们尝试用汇编和C语言两种语言进行编程,将课上的学习的知识进行了运用。
7参考文献
《单片机原理和使用设计》,张毅刚,电子工业出版社,2011年。
《单片微机原理及其接口技术》,胡汉才,清华大学出版社,2003年。
《单片机原理和使用》,孙亟芳,北京航空航天大学出版社,2004年。
《单片机程序设计基础》,周航慈,北京航空航天大学出版社,2001年。
8附录
程序
#include<
reg52.H>
/*端口定义*/
sbitDIN=P1^0;
sbitSCLK=P1^1;
sbitCS=P1^2;
sbitFS=P1^3;
sbits1=P3^2;
sbits2=P3^3;
sbittge=P1^4;
sbittshi=P1^5;
sbittbai=P3^1;
sbittqian=P3^4;
#defineucharunsignedchar
#defineuintunsignedint
uchark,t,x,w;
uintb,c,d,m;
uchars1num,s2num,a,ys;
ucharqian,bai,shi,ge;
ucharcodetable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
ucharcodeTAB[]={0x80,0x86,0x8d,0x99,0x9f,0xa5,0xb1,0xb7,0xbc,0xc7,0xcc,0xd1,0xda,0xdf,
0xe3,0xea,0xee,0xf1,0xf6,0xf8,0xfa,0xfd,0xff,0xff,0xff,0xff,0xff,0xfd,0xfb,0xf9,0xf5,0xf2,0xef,0xe9,0xe5,0xe1,0xd8,0xd4,0xcf,0xc5,0xbf,0xba,0xae,0xa8,0xa2,0x96,0x90,0x89,0x80,0x79,0x72,0x66,0x60,0x5a,0x4e,0x48,0x43,0x38,0x33,0x2e,0x25,0x20,0x1c,0x15,0x11,0x0e,0x09,0x07,0x05,0x02,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x06,0x0a,0x0d,0x10,0x16,0x1a,0x1e,0x27,0x2b,0x30,0x3a,0x40,0x45,0x51,0x57,0x5d,0x69,0x6f,0x80};
Delay(unsignedintn)
{
unsignedinti;
for(i=0;
i<
n;
i++);
}
voiddelay2(ucharl)
uintj,r;
for(j=l;
j>
0;
j--)
for(r=110;
r>
r--);
/*****************************************************************************
数据传送函数
*****************************************************************************/
Translate_Data(unsignedintDATA)
DATA=DATA|0x0000;
//设置为快速模式【慢速模式】DATA=DATA&
0xB000;
DATA=DATA&
0xDFFF;
//打开电源开关【关电源】DATA=DATA|0x2000;
CS=0;
FS=1;
SCLK=0;
//cs=1fs=1sclk=0
//cs=0fs=1sclk=0
16;
i++)//采样一个数据
{
FS=0;
SCLK=1;
;
//cs=0fs=0sclk=1
Delay
(1);
//延时后采集数据
//cs=0fs=0sclk=0时钟低电平时开始采样
if(DATA&
0x8000)DIN=1;
elseDIN=0;
//DIN=DATA&
0x80;
DATA=DATA<
<
1;
}
CS=1;
Delay(3);
voiddisplay(ucharqian,ucharbai,ucharshi,ucharge)
P0=table[qian];
tqian=0;
Delay
(1);
tqian=1;
P0=table[bai];
tbai=0;
tbai=1;
P0=table[shi];
tshi=0;
tshi=1;
P0=table[ge];
tge=0;
tge=1;
voidljr0()
b=0000;
c=b%1000;
d=c%100;
display(b/1000,c/100,d/10,d%10);
voidljr1()
b=0001;
voidljr2()
b=0002;
}
voidljr3()
b=0003;
voidljr4()
b=0004;
voidljr5()
b=0005;
voidljr6()
b=0006;
voidljr7()
b=0007;
voidljr10()
b=0010;
voidkeyscanf()
{
if(s1==0)
Delay(5);
if(s1==0)
while(!
s1);
s1num++;
if(s1num==3)
{
s1num=0;
}
while(!
//松手检测
if(s2==0)
s2);
s2num++;
if(s2num==3)
s2num=0;
if(s2num==0)
x=1,w=10;
if(s2num==1)
x=10,w=15;
if(s2num==2)
x=30,w=20;
//松手检测
主函数
voidmain()
while
(1)
if(s1num==0)
for(m=0;
m<
10000;
m++)//写方波
delay2(x*30);
ljr0();
ljr1();
ljr2();
keyscanf();
if(s1num==!
0)
break;
Translate_Data(0x0FF);
delay2(x*30);
keyscanf();
Translate_Data(0x000);
if(s1num==!
}
if(s1num==1)
for(m=0;
m++)//写锯齿波
for(k=250;
k>
k=k-w)
{
Translate_Data(k);
ljr3();
ljr4();
ljr5();
keyscanf();
1)
break;
if(s1num==2)
{
m++)//正弦波
for(t=0;
t<
96;
t++)
k=TAB[t];
delay2(x/10);
ljr6();