课程设计 基于51单片机的波形发生器(2路,4种,调幅调频)原理图 PCB 仿真 源代码及proteus 软件
双通道信号发生器
1、输出用DAC0832芯片,显示器用LCD1602
2、输出正弦,方波,三角波,锯齿波四种波形。
3、按键设置波形振幅和频率,频率调节范围1-10Hz(因为单片机速度问题,频率很难提升)
仿真是proteus8.9。
#include "reg51.h"
#include"intrins.h"
#include "lcd1602.h"
sbit CS1=P3^2; //DAC控制
sbit CS2=P3^3;
sbit read=P3^6;
unsigned char code sinc[]={//正弦编码
128,131,134,137,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,188,191,194,
196,199,202,204,207,209,212,214,216,219,221,223,225,227,229,231,233,234,236,238,239,241,242,244,245,246,247,249,
250,250,251,252,253,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,254,254,253,252,251,250,250,249,247,
246,245,244,242,241,239,238,236,234,233,231,229,227,225,223,221,219,216,214,212,209,207,204,202,199,196,194,191,
188,186,183,180,177,174,171,168,165,162,159,156,153,150,147,144,141,137,134,131,128,125,122,119,115,112,109,106,
103,100,97,94,91,88,85,82,79,76,73,70,68,65,62,60,57,54,52,49,47,44,42,40,37,35,33,31,29,27,25,23,22,20,18,17,15,
14,12,11,10,9,7,6,6,5,4,3,2,2,1,1,1,0,0,0,0,0,0,0,1,1,1,2,2,3,4,5,6,6,7,9,10,11,12,14,15,17,18,20,22,23,25,27,29,
31,33,35,37,40,42,44,47,49,52,54,57,60,62,65,68,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,115,119,122,125,128
};
unsigned char mode1=0,mode2=0;
uchar xian1[]="10Hz 2.5V";//显存
uchar amp1=50,amp2=50;//振幅
uchar freq1=10,freq2=10;//频率
uchar key=0;
uchar key_scan()//按键检测
{
uchar i,j;
i=0;
j=0;
P1=0x0f;
if(P1!=0x0f) //检测有无按下
{
switch(P1)//检测行
{
case 0x0e:i=3;break;
case 0x0d:i=2;break;
case 0x0b:i=1;break;
case 0x07:i=0;
}
P1=0xf0;
switch(P1)//检测列
{
case 0xe0:j=13;break;
case 0xd0:j=9;break;
case 0xb0:j=5;break;
case 0x70:j=1;
}
}
if(key!=i+j)
{
key=i+j;
return key;
}
else
return 0;
}
//显示
void disp()
{
switch(mode1)
{
case 0:write_string(1,0,"sin ");break;
case 1:write_string(1,0,"squre ");break;
case 2:write_string(1,0,"three ");break;
case 3:write_string(1,0,"zigzag ");
}
switch(mode2)
{
case 0:write_string(2,0,"sin ");break;
case 1:write_string(2,0,"squre ");break;
case 2:write_string(2,0,"three ");break;
case 3:write_string(2,0,"zigzag ");
}
xian1[0]=freq1/10+0x30;
xian1[1]=freq1%10+0x30;
xian1[5]=amp1/10+0x30;
xian1[7]=amp1%10+0x30;
write_string(1,7,xian1);
xian1[0]=freq2/10+0x30;
xian1[1]=freq2%10+0x30;
xian1[5]=amp2/10+0x30;
xian1[7]=amp2%10+0x30;
write_string(2,7,xian1);
}
void main()//主函数
{
unsigned char i1=0,i2=0,k=0;
uchar keynum=0;
uint tt1=0,tt2=0,set1=0,set2=0;//频率控制
init_1602();
disp();
while(1)
{
keynum=key_scan();//按键扫描
//通道1
if(tt1<set1)
tt1++;
else
{
tt1=0;
i1++;
CS1=0;//片选
if(mode1==0)//正弦波
{
P2=amp1*sinc[i1]/50;read=0;_nop_();read=1;
}
if(mode1==1)//方波
{
if(i1<125)
{
P2=amp1*0xff/50;read=0;_nop_();read=1;
}
else
{
P2=0;read=0;_nop_();read=1;
}
}
if(mode1==2)//三角波
{
if(i1<128)
{
P2=2*amp1*i1/50;read=0;_nop_();read=1;
}
else
{
P2=2*amp1*(255-i1)/50;read=0;_nop_();read=1;
}
}
if(mode1==3)//锯齿波
{
P2=amp1*i1/50;read=0;_nop_();read=1;
}
CS1=1;
}
//通道2
if(tt2<set2)
tt2++;
else
{
tt2=0;
i2++;
CS2=0;//片选
if(mode2==0)//正弦波
{
P2=amp2*sinc[i2]/50;read=0;_nop_();read=1;
}
if(mode2==1)//方波
{
if(i2<125)
{
P2=amp2*0xff/50;read=0;_nop_();read=1;
}
else
{
P2=0;read=0;_nop_();read=1;
}
}
if(mode2==2)//三角波
{
if(i2<128)
{
P2=2*amp2*i2/50;read=0;_nop_();read=1;
}
else
{
P2=2*amp2*(255-i2)/50;read=0;_nop_();read=1;
}
}
if(mode2==3)//锯齿波
{
P2=amp2*i2/50;read=0;_nop_();read=1;
}
CS2=1;
}
if(keynum==1)//通道1
{
if(mode1<3)
mode1++;
else
mode1=0;
disp();
}
if(keynum==9)//通道2
{
if(mode2<3)
mode2++;
else
mode2=0;
disp();
}
if(keynum==7)//振幅加
{
if(amp1<50)
amp1++;
disp();
}
if(keynum==8)//振幅减
{
if(amp1>1)
amp1--;
disp();
}
if(keynum==15)//振幅加
{
if(amp2<50)
amp2++;
disp();
}
if(keynum==16)//振幅减
{
if(amp2>1)
amp2--;
disp();
}
if(keynum==3)//频率加
{
if(freq1<10)
freq1++;
set1=1000/freq1-100;
set1=set1/5;
disp();
}
if(keynum==4)//频率减
{
if(freq1>1)
freq1--;
set1=1000/freq1-100;
set1=set1/5;
disp();
}
if(keynum==11)//频率加
{
if(freq2<10)
freq2++;
set2=1000/freq2-100;
set2=set2/5;
disp();
}
if(keynum==12)//频率减
{
if(freq2>1)
freq2--;
set2=1000/freq2-100;
set2=set2/5;
disp();
}
}
}