低频信号发生器.docx
《低频信号发生器.docx》由会员分享,可在线阅读,更多相关《低频信号发生器.docx(23页珍藏版)》请在冰点文库上搜索。
![低频信号发生器.docx](https://file1.bingdoc.com/fileroot1/2023-5/23/93aef249-209f-4a36-834d-235cc574ae18/93aef249-209f-4a36-834d-235cc574ae181.gif)
低频信号发生器
基于51单片机的
函数信号发生器
设计报告
系别:
电子通信工程系
专业:
电子信息工程
班级:
电信092
姓名:
学号:
0904072
基于51单片机的函数信号发生器
摘要
本系统利用单片机F410采用程序设计方法产生锯齿波、三角波、正弦波、方波四种波形,再通过D/A转换器DAC将数字信号转换成模拟信号,滤波放大,最终由示波器显示出来,能产生10Hz—10kHz的波形。
通过键盘来控制四种波形的类型选择、拨码开关控制频率的变化,显示其各自的类型以及数值,系统大致包括信号发生部分、数/模转换部分以及显示部分三部分,其中尤其对数/模转换部分和波形产生和变化部分进行详细论述。
单片机课程设计要求
1、设计内容:
用51系列单片机制作函数发生器:
a)输出驱动电路
b)波形发生程序
2、技术要求:
a)输出锯齿波、三角波、方波、正弦波
b)频率范围:
10HZ~1KHZ
c)显示波形编号及信号频率
d)输出信号幅度:
0~2V
3、设计要求:
a)电路图
b)设计说明书(不少于2000字)
c)程序清单
d)运行结果
1、系统设计
经过考虑,我们确定方案如下:
利用F410单片机采用程序设计方法产生锯齿波、三角波、正弦波、方波四种波形,再通过D/A转换器将数字信号转换成模拟信号,滤波放大,最终由示波器显示出来,通过键盘来控制四种波形的类型选择、频率变化,最终输出显示其各自的类型以及数值。
1.1、设计要求
1)、利用单片机采用软件设计方法产生四种波形
2)、四种波形可通过键盘选择
3)、波形频率可调
4)、需显示波形的种类及其频率
2.1.1总体方案:
方案一:
采用模拟电路搭建函数信号发生器,它可以同时产生方波、三角波、正弦波。
但是这种模块产生的不能产生任意的波形(例如梯形波),并且频率调节很不方便。
方案二:
采用锁相式频率合成器,利用锁相环,将压控振荡器(VCO)的输出频率锁定在所需频率上,该方案性能良好,但难以达到输出频率覆盖系数的要求,且电路复杂。
方案三:
使用集成信号发生器发生芯片,例如AD9854,它可以生成最高几十MHZ的波形。
但是该方案也不能产生任意波形(例如梯形波),并且价格昂贵。
方案四:
采用89S51-410单片机和DAC数模转换器生成波形,加上一个低通滤波器,生成的波形比较纯净。
它的特点是可产生任意波形,频率容易调节,频率能达到设计的500HZ以上。
性能高,在低频范围内稳定性好、操作方便、体积小、耗电少。
经比较,方案四既可满足课程设计的基本要求又能充分发挥其优势,电路简单,易控制,性价比高,所以采用该方案.
.2工作原理
数字信号可以通过数/模转换器转换成模拟信号,因此可通过产生数字信号再转换成模拟信号的方法来获得所需要的波形。
89S51-410单片机本身就是一个完整的微型计算机,具有组成微型计算机的各部分部件:
中央处理器CPU、随机存取存储器RAM、只读存储器ROM、I/O接口电路、定时器/计数器以及串行通讯接口等,只要将89S51410再配置键盘及、数模转换及波形输出、放大电路等部分,即可构成所需的波形发生器,其信号发生器构成系统框图如下图所示。
系统框图
89S51-410是整个波形发生器的核心部分,通过程序的编写和执行,产生各种各样的信号,并从键盘接收数据,进行各种功能的转换和信号幅度的调节。
当数字信号电路到达转换电路,将其转换成模拟信号也就是所需要的输出波形。
波形ROM表是将信号一个周期等间距地分离成64个点,储存在单片机得RON内。
具体ROM表是通过MATLAB生成的,例如正弦表,MATLAB生成的程序如下:
x=0:
2*pi/64:
2*pi;y=(x)*127)+128
3单元电路设计与分析
3.1.1主控电路
设计中主要采用89S51-410型单片机,它具有如下优点:
(1)拥有完善的外部扩展总线,通过这些总线可方便地扩展外围单元、外围接口等。
(2)该单片机内部拥有4K字节的FLASHROM程序存储器空间和256字节的RAM数据存储空间,完全可以满足程序的要求。
由于该芯片可电擦写,故可重复使用。
如果更改程序内容,可将芯片拿下重新烧写。
(3)该单片机与工业标准的MCS-51型机的指令集和输出引脚兼容。
中断系统是使处理器具有对外界异步事件的处理能力而设置的。
当中央处理器CPU正在
处理某件事的时候外界发生了紧急事件,要求CPU暂停当前的工作,转而去处理这个紧
急事件。
在波形发生器中,用两个开光直接与外部中断0和外部中断1的管脚相连,其中S1开光用来改变波形,S2开光用来改变频率。
在程序主函数中,我们写了个死循环一直输出一个默认的波形,当S1或S2按下又抬起时,程序会暂时跳出死循环,进入中断处理程序,从而对波形和频率进行改变。
时钟电路。
由于频率较大时,三角波、正弦波、方波等波中每一点延时时间为几微秒,故延时时间还要加上指令时间即可得到指定频率的波形,该电路用11.0592MHz晶振。
主控电路图
3.1.2数/模转换电路
由于单片机产生的是数字信号,要想得到所需要的波形,就要把数字信号转换成模拟信号,所以该文选用价格低廉、接口简单、转换控制容易并具有8位分辨率的数模转换器DAC0832。
DAC0832主要由8位输入寄存器、8位DAC寄存器、8位D/A转换器以及输入控制电路四部分组成。
但实际上,DAC0832输出的电量也不是真正能连续可调,而是以其绝对分辨率为单位增减,是准模拟量的输出。
DAC0832是电流型输出,在应用时外接运放使之成为电压型输出。
根据对DAC0832的数据锁存器和DAC寄存器的不同的控制方式,DAC0832有三种工作方式:
直通方式、单缓冲方式和双缓冲方式。
本设计选用直通方式。
DAC0832的数据口和单片机的P0口相连。
CSDA:
片选信号输入线(选通数据锁存器),低电平有效;
WR:
数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。
由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变换,LE1的负跳变时将输入数据锁存;
数模转换电路
3.1.3运算放大电路和低通滤波电路
LM324的5管脚与DAC0832的(IOUT2)12管脚相连,LM324的6管脚与DAC0832的(IOUT1)11管脚相连,LM324的7管脚与DAC0832的REF(9)管脚相连.
第一级运算放大器的作用是将DAC0832输出的电流信号转化为电压信号V1,第二级运算放大器的作用是将V1通过反向放大电路-(R2/R1)倍。
题目要求输出的电压在0-5V可调,而V1的电压大约是5V,所以R1选择5K的电阻,R2选择10K的电位器,这样最大的输出电压为5*(10/2)=10,最小电压为0,通过改变电阻可以实现题目要求的0-2V。
在第二个运算放大器的输出端连了一个低通滤波器。
如果不加低通滤波器,也能够生成波形,但是产生的信号中毛刺很多,加一个低通滤波器不仅起到的滤波的作用,还起到了平滑的作用。
低通滤波器的截止频率F=1/(2*pi*R3*C6),这里我们选择R3为100欧姆电阻,C6为104电容,截止频率F=16KHZ。
实验表明,此时的输出波形效果不错。
3.1.4串口通信电路
通用异步收发器(UART)是一种串行接口,一般微处理器中都包含这种外设接口。
异步串行接口提供了一种简单的途径,使两个器件无需共享同一个时钟信号就能进行通信。
如果再加入一个合适的电平转换器MAX232,串口就能能用在RS232和RS485等网络中实现通信,或者与计算机的COM端口连接。
串口只需两根信号线(RX和TX)即可实现,而且只要两端器件都采用同样的位格式和波特率,那么它们无需其它任何对方的信息就可以成功传输数据。
串口通信电路图
4.1键盘显示模块的设计
由于本系统所用按键少,所以采用独立键盘,其连接电路图如下:
图(6)键盘
图中独立键盘引出的四根线分别接单片机的P1.0、P1.1、P1.2、P1.3,另一端接地。
各开关的功能如图所示。
4.2软件设计流程
本系统采用89S51-410单片机,用编程的方法来产生四种波形,并通过编程来切换四种波形以及波形频率的改变。
具体功能有:
(1)各个波形的切换;
(2)各种参数的设定;(3)频率增减等。
软件调试后,通过编程器下载到89S51-410芯片中,然后插到系统中即可独立完成所有的控制。
软件的流程图如下:
图(7)
5、输出波形的种类与频率的测试
5.1、测量仪器及测试说明
测量说明:
正弦波、矩形波、三角波和方波信号的输出,通过对独立键盘来实现其不同波形的输出以及用拨码开关改变其频率。
5.2测试过程
当程序下进去时经过初始化,液晶屏的上只显示“wave:
”和“f:
”,当开关1按下是此时输出波形为方波,当开关2按下是此时输出波形为锯齿波,当开关3按下是此时输出波形为三角波,当开关4按下是此时输出波形为正弦波。
本系统采用8脚的拨码开关来改变频率。
频率范围如下:
方波:
10——10KHZ
锯齿波:
三角波:
10——10KHZ
正弦波:
10—10KHZ
四种波形的仿真波形图如下:
图(8)方波
图(9)锯齿波
图(10)三角波
图(11)正弦波
6软件应用程序
程序如下:
//GeneratedInitializationFile//
/////////////////////////////////////
#include"C8051F410.h"
voidInit_Device(void);//初始化函数声明
voiddelayms(unsignedchari);//长延时函数声明
voiddelayus(void);//短延时函数声明
voidtoch452(unsignedintcmda);//送显示函数声明
unsignedcharrdch452(void);//读键代码函数声明
unsignedcharchekey(void);//键盘扫描函数声明
voiddisplay(void);//显示函数声明
unsignedchardispbuff[8]={0,1,0,0,15,3,17,0};//显示缓冲
sbitCH452_SCL=P1^3;//引脚定义
sbitCH452_SDA=P1^4;
sbitCH452_KEY=P1^5;
unsignedcharN,M=0;//全局变量定义
unsignedintADZ=2,f2,f1=10,adp;
unsignedintCMD,DAT,DAT1;
bitflag;
codeunsignedcharfoant[32]={0xFC,0x60,0xDA,0xF2,0x66,0xB6,0xBE,0xE0,//01234567
0xFE,0xF6,0xEE,0x3E,0x9C,0x7A,0x9E,0x8E,//89ABCDEF
0xFD,0x61,0xDB,0xF3,0x67,0xB7,0xBF,0xE1,//0.1.2.3.4.5.6.7.
0xFF,0xF7,0x00,0x62,0x02,0x12,0xCE,0x1C};//8.9.灭+-=PL
codeunsignedcharkey[16]={0xC6,0xB6,0x86,0xD6,0x96,0xA6,0xF6,0xE6,
0xC4,0xB4,0x84,0xD4,0x94,0xA4,0xF4,0xE4};//键盘位置码
codeunsignedintG[64]={4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,
84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,
148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,
208,212,216,220,224,228,232,236,240,244,248,255,};//锯齿波码
codeunsignedintS[64]={0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,
144,152,160,168,176,184,192,200,208,216,224,232,240,248,255,
240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,
120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0,};//三角波码
codeunsignedcharZ[64]={128,140,152,165,176,188,199,209,218,226,234,240,246,250,253,
255,255,255,253,250,246,240,234,227,218,209,199,188,177,165,153,140,102,115,103,
91,79,67,57,46,37,29,21,15,9,5,2,0,0,0,2,5,9,14,21,28,37,46,56,67,78,90,102,115,};//正玄波码
codeunsignedcharF[64]={255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,};//方波码
main()//主函数
{Init_Device();//初始化
delayms(100);
CMD=0x9103;//设置CH452系统参数
toch452(CMD);
CMD=0x9500;//设置CH452显示参数
toch452(CMD);
display();
while
(1)
{
if(CH452_KEY==0)//按键控制
{ADZ=chekey();//读取键值
switch(ADZ)//波形转换及频率变换
{case0:
N=ADZ;break;//波形转换
case1:
N=ADZ;break;
case2:
N=ADZ;break;
case3:
N=ADZ;break;
case4:
f1++;adp=65535-2450000/f1/64;if(f1>1000)f1=10;TMR3RLL=adp%256;TMR3RLH=adp/256;break;
case5:
f1--;adp=65535-2450000/f1/64;if(f1<10)f1=10;TMR3RLL=adp%256;TMR3RLH=adp/256;break;
case6:
f1=f1+100;adp=65535-2450000/f1/64;if(f1>1000)f1=10;TMR3RLL=adp%256;TMR3RLH=adp/256;break;
case7:
f1=f1-100;adp=65535-2450000/f1/64;if(f1<1000)f1=10TMR3RLL=adp%256;TMR3RLH=adp/256;break;
}
dispbuff[7]=N;//存放波形代码
dispbuff[3]=f1/1000;//频率处理并送显示缓冲区
dispbuff[2]=f1%1000/100;
dispbuff[1]=f1%100/10;
dispbuff[0]=f1%10;
}
display();//显示函数调用
}
}
/*命令、数据送CH452*/
voidtoch452(unsignedintcmda)
{
unsignedcharj;
CH452_SDA=0;
delayus();
CH452_SCL=0;
delayus();
CH452_SCL=1;
delayus();
CH452_SCL=0;
for(j=0;j<16;j++)
{
if(cmda>=0x8000)
CH452_SDA=1;
else
CH452_SDA=0;
CH452_SCL=1;
delayus();
CH452_SCL=0;
cmda=cmda<<1;
};
CH452_SDA=1;
delayus();
CH452_SCL=1;
}
/*读键盘*/
unsignedcharrdch452(void)
{
unsignedcharj,key;
CH452_SDA=0;
delayus();
CH452_SCL=0;
delayus();
CH452_SCL=1;
delayus();
CH452_SCL=0;
key=0x9F;
for(j=0;j<8;j++)
{
if(key>=0x80)
CH452_SDA=1;
else
CH452_SDA=0;
CH452_SCL=1;
delayus();
CH452_SCL=0;
key=key<<1;
};
delayus();
key=0;
for(j=0;j<8;j++)
{
CH452_SCL=1;
if(CH452_SDA==1)
key++;
key=key<<1;
CH452_SCL=0;
delayus();
}
CH452_SDA=1;
delayus();
CH452_SCL=1;
returnkey;
}
/*mS延时*/
voiddelayms(unsignedchari)
{unsignedintj;
do{for(j=0;j!
=1000;j++)
{;}
}while(--i);
}
/*uS延时*/
voiddelayus(void)
{unsignedk;
for(k=0;k<10;k++);
}
/*初始化*/
voidInit_Device(void)
{PCA0MD&=~0x40;//关闭电子狗复位
PCA0MD=0x00;
TCON=0x01;//初始化定时器3
TMOD=0x02;
CKCON=0x44;
TMR3CN=0x04;
TMR3RLL=0x00;
TMR3RLH=0x00;
TMR3L=0xab;
TMR3H=0xfe;
IDA0CN=0xF2;//使能IDA0转换器
REF0CN=0x08;//选择电源电压为IDA0的参考电压
P0MDIN=0xFE;//使能交叉开关
P0SKIP=0x01;
XBR1=0x40;
OSCICN=0x87;//选择系统时钟位24.5MHZ
EIE1=0x80;//允许定时器3中断
IE=0x80;
}
/*定时中断(T0)服务*/
voidtimer3()interrupt14
{TMR3CN=0x04;
switch(N)
{case0:
{IDA0H=S[M++];if(M==64)M=0;break;}//三角波形
case1:
{IDA0H=G[M++];if(M==64)M=0;break;}//锯齿波形
case2:
{IDA0H=Z[M++];if(M==64)M=0;break;}//正选波形
case3:
{IDA0H=F[M++];if(M==64)M=0;break;}//方波波形
}}
/*键盘扫描并返回键值*/
unsignedcharchekey(void)
{
unsignedchari,keycode,keyn=0xff;
if(CH452_KEY==0)//查询键盘
{
keycode=rdch452();
keyn=0;
for(i=0;i<16;i++)//键译码
{if(key[i]==keycode)
keyn=i;}
};
return(keyn);
}
voiddisplay(void)//显示程序
{
unsignedchari;
DAT1=0xA100;
for(i=0;i<8;i++)
{DAT=DAT1+font[dispbuff[i]];
toch452(DAT);
DAT1=DAT1+0x0400;
}
}