基于51单片机信号发生器的设计.docx
《基于51单片机信号发生器的设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机信号发生器的设计.docx(15页珍藏版)》请在冰豆网上搜索。
![基于51单片机信号发生器的设计.docx](https://file1.bdocx.com/fileroot1/2022-11/25/d90013d5-2169-41b5-9853-42bc8b59663c/d90013d5-2169-41b5-9853-42bc8b59663c1.gif)
基于51单片机信号发生器的设计
专业方向课程设计报告
设计课题:
信号发生器的设计
设计时间:
2012年06月6日
信号发生器的设计
摘要:
本文以STC89C51单片机为核心设计了一个低频函数信号发生器。
信号发生器采用数字波形合成技术,通过硬件电路和软件程序相结合,可输出自定义波形,如正弦波、方波、三角波、三角波、梯形波及其他任意波形,波形的频率和幅度在一定范围内可任意改变。
波形和频率的改变通过软件控制,幅度的改变通过硬件实现。
介绍了波形的生成原理、硬件电路和软件部分的设计原理。
关键词:
低频信号发生器;单片机;D/A转换
1设计要求
设计一个能产生方波、三角波、梯形波、锯齿波并且频率、幅度可调的信号发生器。
发挥部分:
作品还能产生正弦波。
2系统概述
2.1.1波形产生方案
采用AT89C51单片机和DAC0832数模转换器生成波形,加上一个低通滤波器,生成的波形比较纯净。
它的特点是可产生任意波形,频率容易调节,频率能达到设计的500HZ以上。
2.1.2改变幅度方案:
方案一:
可以将送给DA的数字量乘以一个系数,这样就可以改变DA输出电流的幅度,从而改变输出电压;但是这样做有很严重的问题,单片机在做乘法运算时需要很长的时间,这样的话输出波形的频率就会很低;并且该方案的输出电压做不到连续可调,当DA的输入数字量比较小时,输出的波形失真就会比较严重。
方案二:
将输出电压通过一个运算放大器的放大。
这样还有个优点是幅度连续可调。
经比较,方案二既可满足课程设计的基本要求,并且电路也挺简单。
2.2工作原理
数字信号可以通过数/模转换器转换成模拟信号,因此可通过产生数字信号再转换成模拟信号的方法来获得所需要的波形。
89C51单片机本身就是一个完整的微型计算机,具有组成微型计算机的各部分部件:
中央处理器CPU、随机存取存储器RAM、只读存储器ROM、I/O接口电路、定时器/计数器以及串行通讯接口等,只要将89C51再配置键盘及、数模转换及波形输出、放大电路等部分,即可构成所需的波形发生器,其信号发生器构成系统框图如图2.2所示。
89C51是整个波形发生器的核心部分,通过程序的编写和执行,产生各种各样的信号,并从键盘接收数据,进行各种功能的转换和信号幅度的调节。
当数字信号电路到达转换电路,将其转换成模拟信号也就是所需要的输出波形。
波形ROM表是将信号一个周期等间距地分离成64个点,储存在单片机得RON内。
具体ROM表是通过MATLAB生成的,例如正弦表,MATLAB生成的程序如下:
x=0:
2*pi/64:
2*pi;y=round(sin(x)*127)+128
图2.2系统框图
3单元电路设计与分析
3.1.1主控电路(如图3.1.1所示)
设计中主要采用STC89C51型单片机,它具有如下优点:
(1)拥有完善的外部扩展总线,通过这些总线可方便地扩展外围单元、外围接口等。
(2)该单片机内部拥有4K字节的FLASHROM程序存储器空间和256字节的RAM数据存储空间,完全可以满足程序的要求。
由于该芯片可电擦写,故可重复使用。
如果更改程序内容,可将芯片拿下重新烧写。
在波形发生器中,用两个开关直接与外部中断0和外部中断1的管脚相连,其中S1开光用来改变波形,S2开光用来改变频率。
在程序主函数中,我们写了个死循环一直输出一个默认的波形和频率(正弦波),当S1或S2按下(接通低电平)又抬起(STC89C51单片机管脚使能高电平)时,程序会暂时跳出死循环,进入中断处理程序,从而对波形和频率进行改变。
由于频率较大时,三角波、正弦波、方波等波中每一点延时时间为几微秒,故延时时间还要加上指令时间即可得到指定频率的波形,该电路用12MHz晶振。
3.1.2数/模转换和运放电路
由于单片机产生的是数字信号,要想得到所需要的波形,就要把数字信号转换成模拟信号,所以必须用到数模转换器件,我们选用的DAC0832,此器件具有8位分辨率的数模转换,它价格低廉、接口简单、转换控制容易等优点。
DAC0832主要由8位输入寄存器、8位DAC寄存器、8位D/A转换器以及输入控制电路四部分组成。
但实际上,DAC0832输出的电量也不是真正能连续可调,而是以其绝对分辨率为单位增减,是准模拟量的输出。
DAC0832是电流型输出,在应用时外接运放使之成为电压型输出。
以便于示波器显示其波形及调节其幅度。
所以又用到了运放,我们用到的是LM324,此运放采用±12V双电源供电,其内部集成有4个放大器,我们用到了其中两个,2和3,没有用到的放大器接地。
3.1.3器件间的连接(见附录2)
DAC0832的数据口和单片机的P0口相连。
CSDA:
片选信号输入线(选通数据锁存器),低电平有效;WR:
数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。
由ILE、CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据线变换,LE1的负跳变时将输入数据锁存。
图3.1.1主控电路图
3.1.4运算放大电路和低通滤波电路
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-5V。
图3.1.4运算放大电路和低通滤波电路
在第二个运算放大器的输出端连了一个低通滤波器。
如果不加低通滤波器,也能够生成波形,但是产生的信号中毛刺很多,加一个低通滤波器不仅起到的滤波的作用,还起到了平滑的作用。
低通滤波器的截止频率F=1/(2*pi*R3*C6),这里我们选择R3为100欧姆电阻,C6为104电容,截止频率F=16KHZ。
实验表明,此时的输出波形效果不错。
3.2系统软件设计
软件设计上,根据功能分了几个模块编程。
模块主要有:
主程序模块、外部中断0模块,外部中断1模块。
3.2.1主程序:
主程序先是进行一些初始化的工作,然后根据波形标志a,b,c,d,e的值进入相应的while循环。
这样写的好处是输出的波形频率可以790多HZ。
在while循环中,单片机根据地址标志位不停的查表,然后把查得的值赋给DAC0832的数据口,然后地址标志位加一,并判断地址标志位是否等于64,如果是就置0再往下执行,如果不是直接往下执行。
然后根据频率标志位进行相应的延时。
图3.2.1主程序流程图
3.2.2中断服务程序:
本程序中两个外部中断分别起到了控制波形和频率的作用。
在程序中还加入了消抖部分。
图3.2.2中断服务程序流程图
4安装调试及测量数据分析
4.1调试过程;
a.不通电,用万用表根据电路图仔细检查各线路连接是否正常。
b.首先是调试单片机部分,DA和运算放大器芯片不接。
用STC_ISP_V483软件通过串口下程序。
看是否可以正常下程序。
c.当可以正常下程序时,给51单片机下一个让所有I/0口一会儿输入0,延时,再输出1,以此类推。
用万用表测量各I/O口得电压是不是一会儿高,一会儿低。
d.安上DA和运算放大器芯片,给单片机下一个输出正弦波的测试程序,通过示波器看输出是否正常。
e.给单片机下一个完整的程序,分别按下S1,看波形是否改变。
按下S2,看频率是否改变。
4.2频率的测量数据:
单位:
HZ
周期
T
2T
3T
4T
5T
6T
7T
8T
理论值
798.6
399.3
266.2
199.7
159.7
133.1
114.1
99.8
实际值
798.6
399.6
266.5
199.9
159.9
133.3
114.2
99.9
4.3出现的问题与解决的方法:
调试单片机的串口时,发现不能正常的下程序。
我想可能是单片机坏了借了一块学习板测试了一下单片机芯片,发现可以正常下载;刚开始写的测试程序输出的波形失真很大。
我想可能是波形的ROM表里的数据值过小,导致DA输出的误差很大。
因而我将波形的ROM表里的数据值调大,在测试时发现波形变得好多了;调试波形的时候我发现矩形波的失真比较大。
我想到可能是低通滤波器的截止频率太低了,因而我将RC低通滤波器的电阻由1K换成了100欧姆,效果好了很多。
4.4系统仿真波形:
图4.4Protus仿真图
a.正弦波b.梯形波
c.三角波d.锯齿波
e.方波
4.5效果分析:
由Protus仿真可知频率误差很小。
最终的波形输出效果也很不错。
4.6测量仪器
示波器、直流稳压电源、万用表。
5结束语
基于单片机的信号发生器设计,这个信号发生器的设计中涉及到一个典型的控制过程。
通过单片机控制一个模数转换器DAC0832产生所需要的电流,然后使用运算放大器LM324可以将其电流输出线性地转换成电压输出,再将电压经过运算放大器的放大,可以得到足够幅度的信号。
通过程序的控制,可以产生一系列有规律的波形。
这样一个信号发生装置在控制领域有相当广泛的应用范围。
信号发生器可以生成更多的波形,只需要再加些波形表即可。
最终做出来的信号发生器满足了题目中的所有要求:
1.产生五种波形。
正弦波、三角波、矩形波、梯形波,锯齿波。
2.最大频率为798.6HZ。
并且频率可步进调节。
3.幅度可调,峰峰值在0——5V之间变化。
当然还是存在不足的地方,比如频率不高,频率太小时矩形波会有些失真,并且不是连续可调,只能步进调制。
参考文献:
[1]郭天翔.新概念51单片机C语言教程入门、提高、开发、拓展全.北京.电子工业出版社2009.1
[2]童诗白.模拟电路技术基础[M].北京:
高等教育出版社,2000.171~202.
[3]陈大钦。
电子技术基础实验。
北京:
高等教育出版社,2009.679~83.
[4]潘永雄沙河电子线路CAD实用教程西安:
西安电子科技大学出版社
附录
附录1:
源程序
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitcsda=P2^2;//DAC0832的片选信号,低电平有效
sbitwr=P2^1;//输入寄存器的写选通输入端,负脉冲有效
sbits1=P3^2;//波形选择中断入口
sbits2=P3^3;//频率选择中断入口
uchark=0,p=0,delay=0;
ucharbxxz=0;pinglv=0;
uchara=1,b=0,c=0,d=0,e=0;
//正弦波数据
ucharcodesin[64]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
//方波数据
ucharcodejuxing[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,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
//锯齿波数据
ucharcodejuchi[64]={0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255};
//梯形波数据
ucharcodetixing[64]={0,13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,242,229,216,203,190,177,164,151,138,125,112,99,86,73,60,47,34,21,8};
//三角波数据
ucharcodesanjiao[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,248,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};
voiddelay1()//延时程序
{
inta,b;
for(a=1;a>0;a--)
for(b=122;b>0;b--);
}
voidint0()interrupt0//采用T0中断选择波形
{
EX0=0;
delay1();
if(s1==0){
bxxz++;
if(bxxz==5)
bxxz=0;
switch(bxxz)
{
case0:
//默认为正弦波
{a=1,b=0,c=0,d=0,e=0;}
break;
case1:
//选择方波
{a=0,b=1,c=0,d=0,e=0;}
break;
case2:
//选择锯齿波
{a=0,b=0,c=1,d=0,e=0;}
break;
case3:
//选择梯形波
{a=0,b=0,c=0,d=1,e=0;}
break;
case4:
//选择三角波
{a=0,b=0,c=0,d=0,e=1;}
break;
}
delay1();//延时,判断键按S1是否真的被按下
while(!
s1);//若真的被按下,为消除按键抖动影响
}
while(!
s1);//等待按键松开
EX0=1;
}
voidint1()interrupt2//采用T1中断选择频率
{
EX1=0;
delay1();//延时,判断S2是否真的键被按下
if(s2==0){//若真的被按下,为消除按键抖动影响
p++;
if(p==8)
p=0;//输出波形的每一点设定延时时间长短,以便选择频率
switch(p)
{
case1:
pinglv=3;
break;
case2:
pinglv=6;
break;
case3:
pinglv=9;
break;
case4:
pinglv=12;
break;
case5:
pinglv=15;
break;
case6:
pinglv=18;
break;
case7:
pinglv=21;
break;
default:
pinglv=0;
break;
}
delay1();
while(!
s2);
}
while(!
s2);
EX1=1;
}
voidmain()//主程序
{//初始化
csda=0;
wr=0;
EA=1;
IT0=1;
EX0=1;
IT1=1;
EX1=1;
while
(1)//设定死循环
{
while(a)//默认为正弦波;频率最高
{delay=pinglv;
P0=sin[k];
k++;
if(k==64)
k=0;
while(delay)
delay--;
}
while(b)//方波
{delay=pinglv;
P0=juxing[k];
k++;
if(k==64)
k=0;
while(delay)
delay--;
}
while(c)
{delay=pinglv;
P0=juchi[k];//锯齿波
k++;
if(k==64)
k=0;
while(delay)
delay--;
}
while(d)
{delay=pinglv;
P0=tixing[k];//梯形波
k++;
if(k==64)
k=0;
while(delay)
delay--;
}
while(e)
{delay=pinglv;
P0=sanjiao[k];//三角波
k++;
if(k==64)
k=0;
while(delay)
delay--;
}
}
}
附录2:
总电路图