应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx

上传人:b****4 文档编号:27144097 上传时间:2023-06-27 格式:DOCX 页数:14 大小:374.14KB
下载 相关 举报
应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx_第1页
第1页 / 共14页
应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx_第2页
第2页 / 共14页
应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx_第3页
第3页 / 共14页
应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx_第4页
第4页 / 共14页
应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx

《应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx》由会员分享,可在线阅读,更多相关《应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx(14页珍藏版)》请在冰豆网上搜索。

应用89S52单片机和DAC0832进行低频函数信号发生器的设计.docx

应用89S52单片机和DAC0832进行低频函数信号发生器的设计

51单片机设计多功能低频函数信号发生器

应用89S52单片机和DAC0832进行低频函数信号发生器的设计。

本设计能产生正弦波、锯齿波、三角波和方波。

这里着重介绍正弦波和锯齿波的生成原理。

ADC0832的介绍

DAC0832是8分辨率的D/A转换集成芯片。

与微处理器完全兼容。

这个DA芯片以其价格低廉、接口简单、转换控制容易等优点,在单片机应用系统中得到广泛的应用。

D/A转换器由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路构成。

D0~D7:

八位数据输入端

ILE:

数据允许锁存信号

/CS:

输入寄存器选择信号

/WR1:

输入寄存器选择信号

/XFER:

数据传送信号

/WR2:

DAC寄存器的写通选择信号

Vref:

基准电源输入端

Rfb:

反馈信号输入端

Iout1:

电流输出1

Iout2:

电流输出2

Vcc:

电源输入端

AGND:

模拟地

DGND:

数字地

DAC0832结构:

  D0~D7:

8位数据输入线,TTL电平,有效时间应大于90ns(否则锁存器的数据会出错);

  ILE:

数据锁存允许控制信号输入线,高电平有效;

  CS:

片选信号输入线(选通数据锁存器),低电平有效;

  WR1:

数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。

由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变换,LE1的负跳变时将输入数据锁存;

  XFER:

数据传输控制信号输入线,低电平有效,负脉冲(脉宽应大于500ns)有效;

  WR2:

DAC寄存器选通输入线,负脉冲(脉宽应大于500ns)有效。

由WR1、XFER的逻辑组合产生LE2,当LE2为高电平时,DAC寄存器的输出随寄存器的输入而变化,LE2的负跳变时将数据锁存器的内容打入DAC寄存器并开始D/A转换。

  IOUT1:

电流输出端1,其值随DAC寄存器的内容线性变化;

  IOUT2:

电流输出端2,其值与IOUT1值之和为一常数;

  Rfb:

反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度;

  Vcc:

电源输入端,Vcc的范围为+5V~+15V;

VREF:

基准电压输入线,VREF的范围为-10V~+10V;

AGND:

模拟信号地

DGND:

数字信号地

DAC0832的工作方式:

根据对DAC0832的数据锁存器和DAC寄存器的不同的控制方式,DAC0832有三种工作方式:

直通方式、单缓冲方式和双缓冲方式。

本设计选用直通方式。

DAC0832工作时序:

DAC0832内部结构图:

当ILE为1时,只有当/CS、/WR1都为0时输入寄存器才允许输入;当/WR2、/XFER也都为0时,输入寄存器里的信息才能写入DAC寄存器。

根据实际电路图我们就可以得到DAC0832工作的时序的程序。

如下:

P37=0;//P37=CS

_nop_();//P36=WR

P36=0;

P0=value;(数据端口信号数值0~255)

P36=1;

_nop_();

P37=1;

硬件电路:

P0口是数据端口,接上拉电阻(其他端口则不用)。

电源质量要好,质量越好的电源,芯片工作就越稳定。

从LM358运放输出的电压最大峰峰值就是12V所以在二级运放的放大倍数要注意跟基准电压想匹配,否则输出信号会很容易失真。

正弦波的生成:

DAC0832产生信号的原理可以说是ADC0809AD转换的逆过程,但DAC0832生成的信号是离散的。

假设要生成一个Y=Asin(2*pi*f*t)的正弦波。

adc0832数据端口给的数据的范围是0~255一共256个。

前0~127表示是X轴上方的电压值(也可能是下方)。

那么128~255是X轴下方的电压值。

那么我们可以得到数据端口的数值的具体量,即value=127sin(2*pi*f*t)+127;假设我在X轴上抽样100个点(0~99),那么value=127sin(pi/50*t)+127;t:

0~99.(这个100位的数组可以用MATALB生成)。

也可以抽样更多的点,抽样的点越多,得到的信号越保真,但信号的频率会有所下降。

抽样的点越少,失真越大,但频率能成大幅度递增。

怎么选择,具体情况具体分析。

其他的波形也跟正弦波一样。

程序如下:

#include

sbitdac_WR=P3^6;//dac0832的wr端

sbitdac_cs=P3^7;

sbitKEY1=P2^0;

sbitKEY2=P2^1;

bitkeyflag;

unsignedchari;

unsignedcharcodetab[100]={127,135,143,151,159,166,174,181,188,195,202,

208,214,220,225,230,234,238,242,245,248,250,

251,252,253,254,253,252,251,250,248,245,242,

238,234,230,225,220,214,208,202,195,188,181,

174,166,159,151,143,135,127,119,111,103,95,

88,80,73,66,59,52,46,40,34,29,24,

20,16,12,9,6,4,3,2,1,0,1,

2,3,4,6,9,12,16,20,24,29,34,

40,46,52,59,66,73,80,88,95,103,111,119};

voidgetkey(void)

{

if(KEY1==0)

{//按键按下后为电电平

RCAP2L+=10;//调节频率

if(CY==1)

{

RCAP2H+=1;

}

}

if(KEY2==0)

{

RCAP2L-=10;

if(CY==1)

{

RCAP2H-=1;

}

}

}

voidTimer2_Init()

{

T2CON=0x00;

TH2=(65536-300)/256;

TL2=(65536-300)%256;

RCAP2H=0XFE;

RCAP2L=0XDA;//稳定在50Hz左右

EA=1;

ET2=1;

TR2=1;

}

voidT0_service()interrupt1

{

TH0=0XEC;

TL0=0X77;

keyflag=1;

}

voidTimer2_service()interrupt5

{

TF2=0;//清除中断标志位

dac_cs=0;

dac_WR=0;

P1=tab[i];

dac_WR=1;

i++;

dac_cs=1;

if(i==100)i=0;

}

voidmain()

{

Timer2_Init();

TMOD=0x01;

TH0=0XEC;

TL0=0X77;

EA=1;

ET0=1;

TR0=1;

while

(1)

{

if(keyflag)

{

keyflag=0;

getkey();

}

}

}

本程序需注意:

按键是低电平有效。

定时器2中断发送数据给DAC0832,0832在得到一个数据后生成相应的电压值。

所以他的中断时间决定信号的频率,调节它的中断时间就能调节信号的频率。

其他波形的生成,其他的波形也跟正弦波一样,但锯齿波和三角波可以不用查表法,应用加减计算得到就可以得到。

下面介绍的是锯齿波:

#include

#include

sbitDACWR=P3^6;

sbitDACCS=P3^7;

unsignedinti;

voidDAC_0832(void)

{

DACCS=0;

DACWR=0;

P0=i;

i+=1;//加以操作得到上升的锯齿波

DACWR=1;

_nop_();

DACCS=0;

if(i==0xff)i=0x7f;//为什么初值是0x7f,其他的行不行。

大家自己动手试试。

}

voidmain(void)

{

i=0x7f;

while

(1)

{

DAC_0832();

}

}

DAC0832有着致命的一个缺点就是输出的波形里的含有的频率比较杂乱,常常出现过激的现象。

如果你需要精确的信号的话,那么你必须在信号输出端就如滤波器。

得到干净的低频函数信号。

如果要作为信号源的话最好是能就上一级攻放。

效果会好很多。

虽然DAC0832不是非常专业的函数信号发生芯片,但是它的输出波形的范围比较广,常常能输出一些,你意想不到得很有意思的信号曲线。

下面发几张示波器观察到得曲线:

实验室里手机照的,不是太清晰但还能看。

编者注:

最近比较忙很少去查看邮箱,前几天看一下邮箱结果里面有100份邮件是要函数信号发生器的。

为了方便大家于是我今天又重新整理了一下,并有实际搭了一遍电路验证特一下。

效果还行。

但在protues上仿真不了,得到的是一个不能预料的曲线。

没查明原因,如果大家有兴趣,可以研究研究。

共同探讨一番。

anmko@

#include

#include

#include

#defineDA0832XBYTE[0Xa000]

#defineucharunsignedchar

#defineS1XBYTE[0X0000]

#defineS2XBYTE[0X2000]

#defineS3XBYTE[0X4000]

ucharcodetab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

ucharcodetosin[256]={0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5

0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5

0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd

0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda

0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99

0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51

0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16

0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15

0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e

0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80};

ucharfun=0,b=0,c=0,d=0,tl,th;

voidkey1(void);

voidkey2(void);

voidkey3(void);

voidkey4(void);

voidjudge(void);

voidmain(void)

{

TMOD=0X01;

TR0=1;

th=0xff;

tl=0xd0;

TH0=th;

TL0=tl;

ET0=1;

EA=1;

while

(1)

{

judge();

}

}

voidjudge(void)

{

ucharline,row,de1,de2,keym;

P1=0x0f;

keym=P1;

if(keym==0x0f)return;

for(de1=0;de1<200;de1++)

for(de2=0;de2<125;de2++){;}

P1=0x0f;

keym=P1;

if(keym==0x0f)return;

P1=0x0f;

line=P1;

P1=0xf0;

row=P1;

line=line+row;/*存放特征键值*/

if(line==0xde)key1();

if(line==0x7e)key2();

if(line==0xbd)key3();

if(line==0x7d)key4();

}

voidkey1(void)//1键选择发波类型,1为正弦波,2为三角波,3为方波

{

fun++;

if(fun==4)fun=0x00;

}

voidkey2(void)//2键加大频率

{

tl++;

if(tl==0x1f)th++;

}

voidkey3(void)//3键减小频率

{

tl--;

if(tl==0x00)th--;

}

voidkey4(void)//4键显示频率

{

doublet;

intf;

TR0=0;//ET0的区别

t=(65535-th*256-tl)*0.4;

f=(int)(1000/t);

S3=tab[f%10];

f=f/10;

S2=tab[f%10];

f=f/10;

if(f==0)S1=0;

elseS1=tab[f];

TR0=1;

}

voidtime0_int(void)interrupt1//中断服务程序

{

TR0=0;

if(fun==1)

{

DA0832=tosin[b];//正弦波

b++;

}

elseif(fun==2)//三角波

{

if(c<128)DA0832=c;

elseDA0832=255-c;

c++;

}

elseif(fun==3)//方波

{

d++;

if(d<=128)DA0832=0x00;

elseDA0832=0xff;

}

TH0=th;

TL0=tl;

TR0=1;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语考试

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1