数字信号发生器设计.docx
《数字信号发生器设计.docx》由会员分享,可在线阅读,更多相关《数字信号发生器设计.docx(19页珍藏版)》请在冰豆网上搜索。
数字信号发生器设计
数字信号发生器设计、调试报告
吴穹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;*/
}
感谢老师的耐心阅读,有不对的地方还请老师斧正!