多功能波形发生器Word文档下载推荐.docx
《多功能波形发生器Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《多功能波形发生器Word文档下载推荐.docx(16页珍藏版)》请在冰豆网上搜索。
总体电路图见附录2。
由于proteus单片机已默认连接复位电路、晶振电路、以及电源,所以本设计中没有这几个模块的具体电路。
3.软件的实现
系统软件由主程序和外部中断程序,定时器中断程序以及键值判断子程序,显示子程序子程序组成,波形的产生主要通过定时器中断来完成。
波形的转换通过改变波形标志位实现。
周期的改变可通过定时器的初值改变的方法来实现。
幅值可通过初始值的改变而方法来实现,由LCD1602完成显示部分。
具体如下所述
3.1波形的产生原理
将各种波形的每个周期平均分成255份,把每份的值依次发给P0口,每份的时间间隔通过开启定时器0来控制,当定时时间到时单片机就产生中断,在中断服务程序里面通过P0口将每份的值发出去,这个值通过DAC0832转换为模拟量。
如图3.1
图3.1
3.2波形的产生过程
3.2.1正弦波的产生过程
对正弦波的一个周期进行等间隔的采样,采样次数为255次,将所采样的数值转化为8位二进制数存放在数组tosin[255]里面。
然后定义一个无符号型变量b,当定时器产生一次中断,单片机就将tosin[b]值赋予P0引脚,同时变量b自加1,并且当b加到255时会自动变为0,因为无符号型变量的范围是0~255。
程序如下:
switch(fun)
{
case0:
//fun==0正弦波
{
P0=tosin[b];
b++;
}break;
3.2.2三角波的产生过程
定义一个无符号变量c,每当定时器定时时间到达时,如果c值大于0而小于128,c自加1,将c值赋予P0口;
如果c值大于128,则用255减去c值赋予P0口;
case1:
//fun==1三角波{
if(c<
128)P0=2*c;
else
P0=2*(255-c);
c++;
}break;
给赋值结果乘以2,因为不乘2的话,锯齿波中的变量e最大可以加到255,但三角波中赋予P0口的最大值只有128,为了让输出电压幅值统一期间,我们对其乘以2。
图3.3
3.2.3方波的产生过程
方波较其它波的产生原理较简单,它也是定义一个无符号字符变量d,当定时器产生一次中断则d自动加1。
当d小于128时,将0xff赋予P0口;
当d大于128时,将0x00赋予P0口;
case2:
//fun==2方波
d++;
if(d<
=128)
P0=0x00;
else
P0=0xff;
图
图3.4
3.2.4锯齿波的产生过程
锯齿波的产生是定义一个变量e,每当定时器中断一次,则把n值赋予P0口。
同时n自加1。
在此处当e加到255时则会自动溢出变为0。
case3:
//fun==3锯齿波
{if(n<
255)
{P0=n;
}
n++;
图3.5
3.3波形的选择及调频调幅的实现
波形的选择及调频调幅通过P1口按键选择来实现,具体如下所述
3.3.1波形的选择
在本方案中,我们通过1#按键进行波形选择。
具体方法是定义一个变量fun,当1#按键按下一次时,其就自动加1。
其不同的数值代表不同的波形。
具体如下:
fun==0代表正弦波
fun==1代表三角波
fun==2代表方波
fun==3代表锯齿波
3.3.2调幅功能的实现
本方案对波形的幅值可以调节为5V、4V、3V、2V、1V;
在这里我们定义一个变量“chu”,并且将赋予P0端口的值5等分,也就是把那个值先除以5,再乘以变量“chu”,所以在这里只要改变变量“chu"
的值就可以改变输出波形的幅值。
在方案中是通过2#按键改变变量的。
voidkey2(void)//选择幅值
{chu++;
if(chu==11)
chu=0x01;
具体的调压方式以正弦波说明如下:
P0=tosin[b]/5*chu;
也就是说,调压功能把将要赋给P0口的值除以5乘以“chu”即可实现。
3.3.3调频功能的实现
由于波形的输出时通过将一个周期的完整波形平均分成255份,每等份的时间是由定时器0初值来确定的。
故在这里改变定时器0的初值就可以改变输出波形的频率。
本方案是通过3#按键来调频的,定义一个变量fre,每按一下fre加1,则定时器初值改变,频率改变。
3.4按键中断方式的介绍及程序
本方案采用独立式按键中断来控制单片机的,相比较键盘扫描方式而言大大的节省了CPU运行时间,因为扫描方式单片机不停的忙于扫描键盘,而中断方式不需要,只要键盘有按键按下,硬件就会给单片机一次中断,单片机收到外部中断后采取扫面键盘一次,所以无需不停地扫描。
voidexinto(void)interrupt0
{EA=0;
TR0=1;
key_value=(P1&
0Xff);
EA=1;
voidjudge(void)//键值判断程序
{
ucharline;
line=key_value;
if(line==0xfe)key1();
if(line==0xfd)key2();
if(line==0xfb)key3();
key_value=0;
}
4.仿真与调试分析
本次实验我们是在proteus仿真软件下完成的。
系统的仿真波形如下:
正弦波
三角波
方波
锯齿波
#include<
reg51.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitrs=P3^7;
sbitrw=P3^6;
sbite=P3^5;
ucharfun=0,chu=5,key_value=0,fre=0,b=0,c=0,d=0,n=0,pinlu,tl,th;
ucharcodetable1[]="
sin"
;
ucharcodetable2[]="
sawtooth"
ucharcodetable3[]="
square"
ucharcodetable4[]="
train"
ucharcodefe[2]={0xa9,0xfc};
ucharcodetosin[256]=
{0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,0xbf,0xc2,0xc5
0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,0xee,0xef,0xf1,0xf2,0xf4,0xf5
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd
0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda
0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99
0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51
0x4e,0x4c,0x48,0x45,0x43,0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16
0x15,0x13,0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,0x11,0x13,0x15
0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,0x40,0x43,0x45,0x48,0x4c,0x4e
0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80};
voiddelay(uintt)
while(t--);
voiddelay1(uintz)
uintx,y;
for(x=z;
x>
0;
x--)//1毫秒延时
for(y=110;
y>
y--);
}
voidwrite_com(ucharcom)
rs=0;
P2=com;
e=1;
delay(5);
e=0;
voidwrite_date(uchardate)
rs=1;
P2=date;
delay1(5);
voidwrite_f(uintdate)//写频率//
{ucharqian,bai,shi,ge;
if(fre==0)
date=25;
elseif(fre==1)
date=40;
qian=date/1000;
bai=date/100%10;
shi=date/10%10;
ge=date%10;
write_com(0x80+0x45);
write_date(0x30+qian);
wr