设计并实现频率可控的正弦波信号发生器.docx

上传人:b****8 文档编号:11205864 上传时间:2023-02-25 格式:DOCX 页数:26 大小:284.44KB
下载 相关 举报
设计并实现频率可控的正弦波信号发生器.docx_第1页
第1页 / 共26页
设计并实现频率可控的正弦波信号发生器.docx_第2页
第2页 / 共26页
设计并实现频率可控的正弦波信号发生器.docx_第3页
第3页 / 共26页
设计并实现频率可控的正弦波信号发生器.docx_第4页
第4页 / 共26页
设计并实现频率可控的正弦波信号发生器.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

设计并实现频率可控的正弦波信号发生器.docx

《设计并实现频率可控的正弦波信号发生器.docx》由会员分享,可在线阅读,更多相关《设计并实现频率可控的正弦波信号发生器.docx(26页珍藏版)》请在冰豆网上搜索。

设计并实现频率可控的正弦波信号发生器.docx

设计并实现频率可控的正弦波信号发生器

课程设计任务书

学生姓名:

专业班级:

电信0904班

指导教师:

沈维聪工作单位:

信息工程学院

题目:

设计并实现频率可控的正弦波信号发生器

初始条件:

1.提供实验室机房及其Keil软件;

2.提供51单片机开发板

要求完成的主要任务:

(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求):

要求:

利用DAC0832输出正弦波信号(用示波器观察输出波形),初始频率为50Hz,变频采用“+”、“-”键控制,实时测量输出信号的频率值,并分析和实测输出信号的频率范围。

具体包括:

(1)设计原理或方法

(2)系统硬件线路设计图

(3)程序框图

(4)资源分配表

(5)源程序

(6)性能分析

(7)课程设计的心得体会;

(8)参考文献(不少于5篇)。

时间安排:

本学期第19周

参考文献:

1、刘瑞新等单片机原理及应用教程机械工业出版社。

2、张毅刚,单片机原理及应用,北京:

高等教育出版社。

3、徐仁贵,微型计算机接口技术及应用,北京:

机械工业出版社。

4、李广弟等单片机基础北京航空航天出版社。

5、楼然苗等51系列单片机设计实例北京航空航天出版社。

指导教师签名:

年月日

系主任(或责任教师)签名:

年月日

摘要:

本课程设计并实现频率可控的正弦波信号发生器。

控制系统采用AT89C52,利用2片DAC0832输出正弦波信号(用示波器观察输出波形),其中一片为另外一片体提供参考电压进而可以控制峰峰值。

利用单片机的选通方式对2片DA分别进行时分复用,达到介绍IO口的资源作用。

为了实现完整的正弦波信号输出,这里采取256个点,末级采用高精度放大器OP07并通过低通滤波器实现完美的波形输出。

加LCD1602对其频率和幅度进行实时显示,通过控制系统预置幅度步进可以达到0.1V.频率初始化为50HZ。

完全满足系统的要求,并且扩展了发挥部分。

关键词:

AT89C52;DAC0832;低通滤波;op07

 

一、总体设计原理

本系统采用AT89C52做控制系统,利用2片DAC0832输出正弦波信号(用示波器观察输出波形),系统初始频率为50Hz,变频采用“+”、“-”键控制,当按下“+”键是正弦波的频率自动加1输出,当按下“—”时,正弦波频率自动减一输出,实时测量输出信号的频率值,通过LCD1602动态显示,利用另一片DAC0832输出控制幅值的大小,改变正弦波的参考电压,步进值设定为0.1V。

实时监控正弦波型号达到幅度和频率。

图1

二、系统硬件设计

2.1、DAC0832模块

DAC转换器是一种将数字量转换成模拟量的器件,其特点是接收、保持和转换的是数字信息,不存在随温度和时间的漂移问题,因此电路的抗干扰性能较好。

DAC0832是8位分辨率的D/A转换集成芯片,它具有价格低廉、接口简单及转换控制容易等特点。

它由8位输入锁存器、8位DAC寄存器、8位DIA转换电路及转换控制电路组成,能和CPU数据总线直接相连,属中速转换器,大约在1us内将一个数字量转换成模拟量输出。

DAC0832的结构和引脚如图2.1:

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:

数字信号地

图2

1.直通方式

直通方式就是使DAC0832内部的两个寄存器(输入寄存器和DAC寄存器)

处于不锁存状态,数据一旦到达输入端DI7~DI0,就直接送入D/A转换器,被转

换成模拟量。

当ILE为高电平,CS和WR1﹑WR2和XFER端都接数字地,这时

锁存信号LE1﹑LE2均为高

电平,输入寄存器和DAC寄存器均处于不锁存状态,即直通方式。

2.单缓冲方式

单缓冲方式就是使两个寄存器中的一个处于缓冲方式,另一个处于锁存方式,

数据只通过一级缓冲器送入D/A转换器。

通常的做法是将和XFER均接地,使

DAC寄存器处于直通方式,而把ILE接高电平,接端口地址译码信号,WR1接

CPU系统总线的IOW信号,使输入寄存器处于锁存方式。

单缓冲方式只需执行

一次写操作即可完成D/A转换。

一般不需要多个模拟量同时输出时,可采用单

缓冲方式。

3.单缓冲方式

单缓冲方式就是使两个寄存器均处于锁存方式,数据要经过两级锁存(即两级

缓冲)后再送入D/A转换器,这就是说,要执行两次写操作才能完成一次D/A转

换。

只要将ILE接高电平,WR1和WR2接CPU的IOW,CS和XFER分别接两

个不同的I/O地址译码信号即可。

图中的Rfb是内部电阻,是为外部运算放大器提供的反馈电阻,用以提供适当

的输出电压,Vref端是由外电路为芯片提供的参考电源,电压范围在-10V~

+10V。

另外,DAC0832为电流输出型DAC,使用时需外接运算放大器,芯片

的电源电压最好工作在+15V。

图3

本设计采用DAC0832实现电流输出满足I1+I2是一定值。

为将电流转换成电压,这里采用具有极低的输入失调电压OP07。

通过在晶圆阶段执行调整而获得,而且这种低失调电压一般不需要进行任何外部零点校准。

此外还具有低输入偏置电流(OP07E为±4nA)和高开环增益(OP07E为200V/mV)特性。

低失调电压和高开环增益使之特别适合高增益仪器仪表应用。

2.2、控制系统模块

这里控制系统采用AT89C52。

采用12M晶振,整体控制液晶显示和DAC0832的电压输出,并且实时进行正弦波输出。

图4

AT89C52结构介绍:

P0口:

P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。

当P1口的管脚第一次写1时,被定义为高阻输入。

P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。

在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。

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:

来自反向振荡器的输出。

2.3、显示模块

显示模块这里采用LCD1602。

进行实时扫描按键的值并显示DAC0832的电压值,并且根据正弦波的函数输出表以及延时的关系控制频率的输出并且显示在液晶上,LCD1602指令如表格1所示。

序号

指令

RS

R/W

D7

D6

D5

D4

D3

D2

D1

D0

1

清显示

0

0

0

0

0

0

0

0

0

1

2

光标返回

0

0

0

0

0

0

0

0

1

*

3

置输入模式

0

0

0

0

0

0

0

1

I/D

S

4

显示开/关控制

0

0

0

0

0

0

1

D

C

B

5

光标或字符移位

0

0

0

0

0

1

S/C

R/L

*

*

6

置功能

0

0

0

0

1

DL

N

F

*

*

7

置字符发生存贮器地址

0

0

0

1

字符发生存贮器地址

8

置数据存贮器地址

0

0

1

显示数据存贮器地址

9

读忙标志或地址

0

1

BF

计数器地址

10

写数到CGRAM或DDRAM)

1

0

要写的数据内容

11

从CGRAM或DDRAM读数

1

1

读出的数据内容

表1

三、软件部分

正弦波的实现相对方波和三角波相对比较复杂,因为正弦波的实现是输出各个点的值就行了,可是各个点值则要通过正弦函数来求出。

输出的数据刚好是256个数据,需要先将数存入数组中在大循环中取出数组,组成正弦波。

本设计采用按键扫面算法实现实时对频率和幅度的显示,并“+”、“-”按键实现调节,并且更新数据显示在液晶LCD1602上面。

图5

四、源程序

#include

#defineuintunsignedint

#defineucharunsignedchar

#defineucharunsignedchar

sbitwr2=P3^7;

sbitrs=P2^6;

sbitrw=P2^5;

sbitep=P2^7;

sbitgn=P2^4;

sbitup=P2^3;

sbitdown=P2^2;

sbitS1=P2^0;

sbitS2=P2^1;

sbitwr1=P3^0;

sbitdir1=P3^1;

sbitdir2=P3^4;

ucharj,k=39,flag,amp=0xfa;

uintfreq;

codeucharv[]="amplitude:

";

ucharvv[5];

codeucharf[]="freqency:

";

codeuintfj[40]={999,744,591,490,419,366,325,292,265,243,

224,208,194,181,171,161,153,145,138,132,

126,121,116,111,107,104,100,97,94,91,85,

81,74,71,67,64,60,57,53,50};

codeucharsj[]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,

20,21,22,23,24,25,26,27,28,29,31,33,36,38,40,42,45,48,51,55};

ucharfv[6];

codeucharsin[]={

0x7F,0x84,0x88,0x8D,0x91,0x96,0x9B,0x9F,0xA4,0xA8,0xAC,0xB1,0xB5,0xB9,0xBD,0xC1

0xC5,0xC9,0xCD,0xD0,0xD4,0xD7,0xDA,0xDE,0xE1,0xE4,0xE6,0xE9,0xEB,0xEE,0xF0,0xF2

0xF4,0xF6,0xF7,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD

0xFD,0xFC,0xFB,0xF9,0xF8,0xF7,0xF5,0xF3,0xF1,0xEF,0xED,0xEA,0xE8,0xE5,0xE2,0xDF

0xDC,0xD9,0xD5,0xD2,0xCE,0xCB,0xC7,0xC3,0xBF,0xBB,0xB7,0xB3,0xAE,0xAA,0xA6,0xA1

0x9D,0x98,0x94,0x8F,0x8B,0x86,0x81,0x7D,0x78,0x73,0x6F,0x6A,0x66,0x61,0x5D,0x58

0x54,0x50,0x4B,0x47,0x43,0x3F,0x3B,0x37,0x33,0x30,0x2C,0x29,0x25,0x22,0x1F,0x1C

0x19,0x16,0x14,0x11,0x0F,0x0D,0x0B,0x09,0x07,0x06,0x05,0x03,0x02,0x01,0x01,0x00

0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x07,0x08,0x0A,0x0C,0x0E

0x10,0x13,0x15,0x18,0x1A,0x1D,0x20,0x24,0x27,0x2A,0x2E,0x31,0x35,0x39,0x3D,0x41

0x45,0x49,0x4D,0x52,0x56,0x5A,0x5F,0x63,0x68,0x6D,0x71,0x76,0x7A,0x7F};

voiddelay(ucharz)

{

ucharx,y;

for(x=z;x>0;x--)

for(y=110;y>0;y--);

}

voidwrite_com(ucharcom)

{

rs=0;

P0=com;

delay(5);//用nop语句可以替代吗?

ep=1;

delay(5);

ep=0;

}

voidwrite_data(uchardate)

{

rs=1;

P0=date;

delay(5);//用nop语句可以替代吗?

ep=1;

delay(5);

ep=0;

}

voidinit_1602()

{

rw=0;

write_com(0x38);

delay

(1);

write_com(0x0c);

delay

(1);

write_com(0x06);

delay

(1);

write_com(0x01);

delay

(1);

}

voiddisplay_1602(uchar*v)

{

uchari=0;

while(v[i]!

='\0')

{

write_data(v[i]);

i++;

delay

(1);

}

}

voiddealv(ucharamp)

{

inti;

i=amp*10;

i=i/50;

vv[0]=i/10+48;

vv[1]='.';

vv[2]=i%10+48;

vv[3]='V';

vv[4]='\0';

}

voiddealf()

{

freq=fj[k];

fv[0]=freq/100+48;

fv[1]=freq%100/10+48;

fv[2]=freq%10+48;

fv[3]='H';

fv[4]='z';

fv[5]='\0';

freq=0;//频率处理

}

voidfudu(ucharamp)

{

P1=amp;

wr1=0;

delay

(1);

wr1=1;

}

voidkeyscan1()

{

if(gn==0)

{

delay(20);

if(gn==0);

{

while(!

gn);

flag^=0x01;

}

}

if(flag)

{

dir1=0;

if(up==0)

{

delay(10);

if(up==0);

{

while(!

up);

dir2^=1;

amp+=5;

if(amp>250)amp=0;//这是循环显示

fudu(amp);

dealv(amp);

write_com(0x80+10);

display_1602(vv);

}

}

if(down==0)

{

delay(100);

if(down==0);

{

while(!

down);

dir2^=1;

amp-=5;

if(amp==0)amp=250;

fudu(amp);

dealv(amp);

write_com(0x80+10);

display_1602(vv);

}

}

}

else

{

dir1=1;

if(up==0)

{

delay(100);

if(up==0);

{

while(!

up);

dir2^=1;

k++;

delay(10);

if(k>39)k=0;//添加的判断函数

dealf();

write_com(0xc0+10);

display_1602(fv);

}

}

if(down==0)

{

delay(80);

if(down==0);

{

while(!

down);

dir2^=1;

k--;

delay(10);//

if(k>=250)k=39;//增加的判断,当最小的时候回到最大,

dealf();

write_com(0xc0+10);

display_1602(fv);

}

}

}

}

 

voidmain()

{

uchari;

 

fudu(amp);

init_1602();

write_com(0x80);

display_1602(v);

write_com(0xc0);

display_1602(f);

dealv(amp);

write_com(0x80+10);

display_1602(vv);

dealf();

write_com(0x80+0x40+10);

display_1602(fv);

while

(1)

{

keyscan1();

for(j=0;j<173;j++)

{

P1=sin[j];

wr2=0;

for(i=sj[k];i>0;i--);//要注意此处延时的原理

wr2=1;

}

}

}

 

五、性能分析

本系统经实物测试以及液晶显示数据处理,能达到幅值步进0.1V,初始频率50HZ开始。

测试表格如下,误差能达到很好的稳定度。

表一:

频率测量表

预置频

率/HZ

50

60

71

81

91

100

126

145

161

测试频

率/HZ

49.8

60.1

84.6

81.3

91.2

100.1

126.6

145.1

162.1

误差/HZ

0.2

0.1

0.4

0.3

0.2

0.1

0.6

0.1

1.1

测试频

率/HZ

181

208

265

325

419

490

591

744

999

测试频

率/HZ

181.0

207.8

265.2

325.7

419.6

489.7

591.2

7444.4

1000

误差/HZ

0

0.2

0.2

0.7

0.6

0.3

0.2

0.4

1

表二:

幅度测量表

预置幅度/mv

100

500

800

1200

1500

1800

2000

2300

2500

实测幅度/mv

98

502

803

1205

1498

1807

2012

2309

2511

误差/mv

2

2

3

5

2

7

12

9

11

预置幅度/mv

2700

2900

3300

3500

3800

4100

4400

4600

5000

预置幅度/mv

1712

2920

3312

3505

3790

4009

4403

4589

4970

误差/mv

12

20

12

5

10

1

3

11

30

由表格数据可以看出,在预置的频率和幅度下,可以步进0.1V。

并且可以看到实测数据和显示的数据基本无误差很少。

完全满足题目要求。

六、总结与心得

本次的设计中利用AT89C52和DAC0832以及放大器完成电路的设计,用开关来控制各种波形的发生及转换,用单片机输出后,经过模数转换器生成波形,最终可以通过示波器观察。

在这次的软件设计中,程序设计采用的是C语言。

C语言具有速度快,可以直接对硬件进行操作的优点,它可以极好的发挥硬件的功能。

并且C语言编写的代码非常容易理解

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

当前位置:首页 > 初中教育 > 语文

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

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