数字信号发生器设计.docx

上传人:b****4 文档编号:5044198 上传时间:2022-12-12 格式:DOCX 页数:19 大小:1.47MB
下载 相关 举报
数字信号发生器设计.docx_第1页
第1页 / 共19页
数字信号发生器设计.docx_第2页
第2页 / 共19页
数字信号发生器设计.docx_第3页
第3页 / 共19页
数字信号发生器设计.docx_第4页
第4页 / 共19页
数字信号发生器设计.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

数字信号发生器设计.docx

《数字信号发生器设计.docx》由会员分享,可在线阅读,更多相关《数字信号发生器设计.docx(19页珍藏版)》请在冰豆网上搜索。

数字信号发生器设计.docx

数字信号发生器设计

数字信号发生器设计、调试报告

吴穹300820422708级电信2班

孟岱300820422008级电信3班

谢学典300820422808级电信3班

 

设计目标陈述

1.基本要求:

对所输入的频率及幅值,信号发生器根据频率值决定采样点数合成一个数字信号,然后通过一个数模转换器,将数字域向模拟信号转变,最后经过缓冲放大、滤波、保护电路对模拟信号进行修正,从输出端得出一个完整的正弦波形、方波或者锯齿波。

2.参数要求:

幅值在0到5V可调。

输出端频率最大为100Hz。

3.实现功能:

可用键位控制频率,输出模式,占空比,并用数码管显示频率,可显示3种不同波形(方波,正弦波,锯齿波)。

完成情况简述

1.对输入的频率,设计的数字信号发生器都能输出一个完整的正弦波;方波和锯齿波的输出在仿真中可以实现,但最后放弃,具体理由在下面详细陈述。

2.数字信号发生器达到5V,最大输出频率可达75Hz.

3.键位能够调节频率的变化,分别控制百位,十位和各位,可以实现1hz的步进,按键还可以控制输出模式的变换和占空比(但最后放弃);数码管显示仿真能够实现,但在连接中由于某种原因没能实现(很遗憾)。

系统总体描述及系统框图

1.系统总体描述:

整个系统以微控制器(单片机AT89C51)为核心,包括DAC转换模块,滤波器模块,按键模块和数码管显示模块。

2.系统框图:

软件框图:

 

N

Y

 

Y

 

N

 

硬件图:

 

各模块说明

1.单片机控制模块:

主函数先开启定时器,然后在一个循环语句中不断执行jisuan函数,数码管显示函数,和按键扫描函数。

一旦定时器产生中断,就转去执行中断服务程序,然后返回到循环中继续执行。

其中jisuan函数主要完成的功能是计算显示数字,还有给根据频率给计数器赋初值。

2.数码管输出模块:

主要用到了74LS1383-8译码器,和16个反相器,以及8个数码管。

8位数码管分别显示占空比,输出波形的类型,以及频率(包括万位,千位,百位,十位,个位)。

3.按键模块:

按键模块没有采用中断,而是利用循环不断进行中断扫描。

系统键盘实现

工作原理如下:

(1).检测键盘上是否有键按下:

将行线送入低电平,列线送入高电平。

读入P1口的状态来判别。

其具体过程如下:

P1口输出0FH,即所有行线置成高电平,所有列线置成低电平,然后将P1口状态读入与0FH比较。

如果有键按下,总会有一根行线电平被拉至低电平,从而使行输入状态不全为1。

(2).识别键盘中哪一个键按下:

确认有键按下后,保存行扫描时有键按下时的状态X。

P1口输出F0H,进行列扫描,保存列扫描状态Y,取出键值Z=X|Y.例如第一行第一列有键按下,那么行扫描读入的状态为00001110,列扫描读入的状态为11100000,最后键值Z=11101110=EEH,然后转去执行相应的服务程序。

(3).按键还需要考虑连击和去抖动的问题,为了去抖动,在按键扫描程序中如果感知有键按下,先等待10ms,然后再进行一次判断。

为了避免连击,在确认有键按下后,需要延时0.5s才响应。

这样虽然不能完全避免连击,但是一般操作不会有连击现象。

我们也考虑过利用按键抬起的边沿来触发,但是鉴于本按键的设计,这样做着实比较难,所以就用此方法代替。

4.DAC转换模块:

用到的是TLC7528芯片,此芯片利用如下原理可以直接在输出实现电流量向电压量的转变,从而省去了原本需要的基于运放的转换电路。

5.数字滤波器:

数字滤波器采用的是MAX7400芯片。

按照如上连接即可,clock输入时钟是根据INPUT频率的变化而变化的,要求是必须大于INPUT信号100倍的截止频率。

我们最后选定clock信号的频率为INPUT信号频率的120倍。

两个0.1uF的电容起到稳压的作用。

 

调试流程

1.根据目标编写程序,使用Proteus设计原理图并进行仿真。

在电路板上焊接基本元器件(单片机仿真器串口,DAC转换芯片,3-8译码器,滤波器芯

2.实验室以单片机仿真器为基础,将基础程序输入单片机,用示波器观察输出波形,调节内置频率,找到频率显示范围。

3.根据波形以及参数修改后的显示状况和频率范围,修改源程序,反复调试。

4.基本功能调试好后,在电路板上焊接数码管,按键以及三极管反相器器件,连接相应线路。

5.调试按键控制下示波器输出情况,根据与期望的差距修改源程序及检查电路连接,以测试及优化键控及显示输出。

6.调试完成,等待验收。

遇到的问题及解决方法

问题1:

在Proteus仿真过程中,没有TLC7528这个DAC元件,影响仿真。

解决:

在Proteus中找到了一个不带锁存器的DAC芯片,在其输出端加上锁存器,就可以实现与TCL7528相同的功能。

问题2:

波形显示设计阶段,只能达到很低的输出频率,没有超过10Hz。

解决:

经过检查,源程序中初次设计的采样点是256个,要多次调用中断,每次调用中断又占用一定机器周期,使得采样周期过长。

将采样点设为10个后,频率最大值大大增加。

牺牲的采样精度在经过滤波器后可以得到解决,依然是较漂亮的正弦波。

问题3:

80C51的剩余管脚数不能满足对8个数码管的控制。

解决:

在80C51的P3.0-P3.2口加上了3-8译码器74LS138,将输出扩展即可满足要求。

问题4:

74LS138输出为高电平有效,而实验提供的数码管是共阳极的,需要低电平输入才能控制。

解决:

在数码管阴极加上由三极管组成的8组反相器,即可为数码管提供低电平。

问题5:

数码管显示的问题,最初设计数码管显示输出8位片选和8为位选信号,但发现如果这样设计管脚不够用,所以最后选择用一个3-8译码器来减少单片机管脚的使用,但是我们有发现实验室提供的3-8译码器输出是低电平有效,而数码管恰恰又是共阴极的,所以只能再次加入反相器已达到显示效果,最后由于在显示电路搭接的过程中可能出现了些小失误,虽然在仿真中能够实现数码管的显示,但是在最后的电路中没能实现(很是遗憾)。

问题6:

在编写软件时,开始希望能够实现四种输出波型,所以中断服务程序很长,经过调试后发现如果这样,那么最后正弦波的频率收到很大限制,所以最后无奈将其他三种波形的输出放弃掉。

问题7:

在软件的编写中,为了使中断服务程序能尽量的短,从而达到更大的极限频率,想分别对clock和INPUT信号使用中断,中断的周期为24的关系,此处解释一下为什么是24倍的关系:

因为想要得到的clock和INPUT信号的频率为120倍的关系,而INPUT信号每个正弦信号周期采样10个点,而clock信号一个中期只需采样2个点,这里相差了5倍的关系,

120/5=24

为了不影响INPUT信号的正常输出,将INPUT信号的中断优先级设为最高,但是经过仿真,并没能达到预期的效果,clock信号输出正常,但是INPUT信号输出反而不正常,并不符合优先级的设定,这个问题到最后也没能找出解决的方案,所以只能采用一个中断的方法,在中断函数中在用判断的方法实现24周期的关系。

问题8:

尽管程序再优化,中断服务程序再简短,正弦波的频率也很难再高,出现了瓶颈,出现这种问题的原因在芯片上,要解决这个问题只能更换更高速的芯片。

原理图及实物照片

原理图

实物照片

程序流程图和源代码(附注释)

#include

 

sbitP3_0=P3^0;

sbitP3_1=P3^1;

sbitP3_2=P3^2;

sbitP3_3=P3^3;

#defineucharunsignedchar

ucharcodetab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//0---9数字共阴极

ucharcodetab1[8]={0X73,0x73,0x73,0x76,0x79,0x38,0x38,0x3f};//PPP.HELLO共阴极

ucharcodetosin[11]={0x80,0xca,0xf9,0xf8,0xc7,0x7c,0x30,0x04,0x09,0x3d};//正弦波数据

ucharcount=0,b=0,c=0,d=0,e=0,i,k,tl,th;

intww=0,qw=0,bw=0,sw=5,gw=0,zkgw=0,zksw=5;//ww为万位数字,qw为千位数字,bw为百位数字,

//sw为十位数字,gw为个位数字,zkgw为占空比个位数字,zksw为占空比十位数字

intf,m,choice=1,zk=50;//f为频率变量,choice为波形类型选择变量,zk为占空比变量,默认占空比为50%

unsignedlongt,ff;//t为时间变量

voiddelay10ms()//延时10ms程序

{

unsignedchari,j;

for(i=20;i>0;i--)

for(j=248;j>0;j--);

}

 

/*1键选择发波类型,1为正弦波,2为三角波,3为方波*/

voidkey1(void)

{

if(choice<4)

choice=choice+1;

else

choice=1;}

/*个位频率调整*/

voidkey2(void)

{

if(gw<9)

gw=gw+1;

else

gw=0;}

/*十位频率调整*/

voidkey3(void)

{if(sw<9)

sw=sw+1;

else

sw=0;}

/*百位频率调整*/

voidkey4(void)

{

if(bw<9)

bw=bw+1;

else

bw=0;}

/*千位频率调整*/

voidkey5(void)

{

if(qw<9)

qw=qw+1;

else

qw=0;}

/*万位频率调整*/

voidkey6(void)

{

if(ww<5)

ww=ww+1;

else

ww=0;}

/*方波占空比加大*/

voidkey7(void)

{if(zk<100)

zk=zk+1;

else

zk=0;}

/*方波占空比减小*/

voidkey8(void)

{

if(zk>=1)

zk=zk-1;

else

zk=0;

}

/*计算显示数字*/

voidjisuan(void)

{

f=1000*qw+100*bw+10*sw+gw;

ff=120*f;

t=65536-1000000/ff;

th=t/256;

tl=t%256;

ww=f/10000;

f=f%10000;

qw=f/1000;

f=f%1000;

bw=f/100;

f=f%100;

sw=f/10;

gw=f%10;

zkgw=zk%10;

zksw=zk/10;

}

/*显示*/

voiddisplay(void)

{/*P3_0=0;//此处为略去的初始化

P3_1=1;

P3_2=0;

P2=tab[choice];

for(i=0;i<=60;i++);

P2=0x80;//小数点显示

for(i=0;i<=60;i++);

P3_0=1;

P3_1=1;

P3_2=0;

P2=tab[ww];

for(i=0;i<=60;i++);

P3_0=0;

P3_1=0;

P3_2=1;

P2=tab[qw];*/

for(i=0;i<=60;i++);

P3_0=1;

P3_1=0;

P3_2=1;

P2=tab[bw];

for(i=0;i<=60;i++);

P3_0=0;

P3_1=1;

P3_2=1;

P2=tab[sw];

for(i=0;i<=60;i++);

P3_0=1;

P3_1=1;

P3_2=1;

P2=tab[gw];

/*for(i=0;i<=60;i++);//此处为使数码管显示连续,去掉显示占空比的两位

if(choice==3){

P3_0=1;

P3_1=0;

P3_2=0;

P2=tab[zkgw];

for(i=0;i<=60;i++);

P3_0=0;

P3_1=0;

P3_2=0;

P2=tab[zksw];

for(i=0;i<=60;i++);

P3_0=1;

P3_1=0;

P3_2=0;

P2=0x80;//小数点显示

for(i=0;i<=60;i++);

}*/}

/*键盘扫描*/

voidjudge(void)

{

{unsignedcharX,Y,Z;

P1=0xff;

P1=0x0f;//先对P3置数行扫描

if(P1!

=0x0f)//判断是否有键按下

{delay10ms();//延时,软件去干扰

if(P1!

=0x0f)//确认按键按下X=P1;

{TR0=0;

X=P1;//保存行扫描时有键按下时状态

P1=0xf0;//列扫描

Y=P1;//保存列扫描时有键按下时状态

Z=X|Y;//取出键值

switch(Z)//判断键值(那一个键按下)

{case0x7d:

key1();break;

case0xee:

key2();break;//对键值赋值

case0xde:

key3();break;

case0xbe:

key4();break;

case0x7e:

key5();break;

case0xed:

key6();break;

case0xdd:

key7();break;

case0xbd:

key8();break;

}

for(i=50;i>0;i--)

delay10ms();

TR0=1;}}}}

voidmain(void)

{

TMOD=0X01;

TR0=1;

ET0=1;

EA=1;

P3_3=0;

while

(1)

{jisuan();

display();

judge();

}}

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

{

/*TR0=0;*/

/*if(choice==1)

{*/

P3_3=P3_3^1;

count++;

if(count==24)

{count=0;

P0=tosin[b];

if(b==9)

b=0;

elseb++;

}//正弦波

/*}*/

/*elseif(choice==2)//三角波之所以去掉是因为终端服务程序太长,导致频率不能到达很高

{if(c<=128)P0=c;

elseP0=255-c;

c++;

}

elseif(choice==3)//方波

{k=zk*256/100;

d++;

if(d<=k)P0=0x00;

elseP0=0xff;}

elseif(choice==4)//锯齿波

{if(e<=255)P0=255-e;

elseP0=0;

e++;

}*/

TH0=th;

TL0=tl;

/*TR0=1;*/

}

 

感谢老师的耐心阅读,有不对的地方还请老师斧正!

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

当前位置:首页 > 求职职场 > 简历

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

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