基于51单片机的波形发生器(双通道,5种,调频)(原理图+仿真+程序)
基于单片机的波形发生器设计
设计内容:1、设计一款能产生3种以上波形的波形发生器
2、设计波形选择按钮(采用3个独立按键)3、点阵显示波形图案
4、能同时输出两种波形5、显示频率
频率调节范围为1Hz-0.3Hz。因为正弦波编码很多,再加上DAC芯片的速度,以及还要显示点阵和频率,所以波形输出频率很低。
#include "reg51.h"
#include <PCF8591_1.h>
#include <PCF8591_2.h>
#include "74hc595.h"
#define uchar unsigned char
#define uint unsigned int
sbit k1=P3^1;//按钮
sbit k2=P3^0;
sbit k3=P3^2;
uchar code smgduan0[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示0~9,无小数点
uchar code smgduan1[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//显示0~9,有小数点
uchar time=0,mode1=0,mode2=0;//系统变量
uchar code wave[256]={//正弦波
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,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
};
uchar disp1[]={0x18,0x04,0x04,0x08,0x10,0x20,0x20,0x18};//正弦波
uchar disp2[]={0x3E,0x02,0x02,0x3E,0x20,0x20,0x3E,0x00};//方波
uchar disp3[]={0x20,0x20,0x10,0x08,0x08,0x08,0x10,0x20};//梯形波
uchar disp4[]={0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x00};//三角波
uchar disp5[]={0x00,0x40,0x20,0x10,0x08,0x04,0x7E,0x00};//锯齿波
uchar ta=0,tb=0,freq=100;//频率控制
uint zhou=4000;//周期
uchar flag=0,*p;
//延时
void delay(uint i)
{
while(i--);
}
//主函数
void main()
{
uchar k=0;
ta=(65536-zhou)/256;
tb=(65536-zhou)%256;
TMOD|=0X01;
TH0=ta;
TL0=tb;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
while(1)
{
if(!k1 &&(k!=1))//通道1
{
k=1;
if(mode1<4)
mode1++;
else
mode1=0;
}
if(!k2 &&(k!=2))//通道2
{
k=2;
if(mode2<4)
mode2++;
else
mode2=0;
}
if(!k3 &&(k!=3))//频率
{
k=3;
if(zhou<10000)
zhou+=1000;
else
zhou=4000;
ta=(65536-zhou)/256;
tb=(65536-zhou)%256;
switch(zhou)
{
case 4000:freq=100;break;
case 5000:freq=83;break;
case 6000:freq=71;break;
case 7000:freq=56;break;
case 8000:freq=50;break;
case 9000:freq=42;break;
case 10000:freq=38;
}
}
if(k1 && k2 && k3)
k=0;
//查找数组
switch(mode1)
{
case 0:p=disp1;break;
case 1:p=disp2;break;
case 2:p=disp3;break;
case 3:p=disp4;break;
case 4:p=disp5;
}
//======================================
if(zhou>5000)
{
//=================================显示频率
Hc595SendByte(0);
P0=0;P2=0xe7;P0=smgduan0[freq%100/10];
delay(50);
Hc595SendByte(0);
P0=0;P2=0xe3;P0=smgduan0[freq%10];
delay(50);
Hc595SendByte(0);
P0=0;P2=0xeb;P0=smgduan1[freq/100];
delay(50);
//=================================显示波形
P2=0xff;
P0=0xff;
Hc595SendByte(*p);
P0=0x7f;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+1));
P0=0xbf;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+2));
P0=0xdf;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+3));
P0=0xef;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+4));
P0=0xf7;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+5));
P0=0xfb;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+6));
P0=0xfd;
delay(50);
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+7));
P0=0xfe;
delay(50);
}
}
}
//定时器中断
void Timer0() interrupt 1
{
TH0=ta;
TL0=tb;
time++;
if(zhou<6000)
{
//=================================显示频率
if(flag==1)
{
Hc595SendByte(0);
P0=0;P2=0xe7;P0=smgduan0[freq%100/10];
}
if(flag==2)
{
Hc595SendByte(0);
P0=0;P2=0xe3;P0=smgduan0[freq%10];
}
if(flag==0)
{
Hc595SendByte(0);
P0=0;P2=0xeb;P0=smgduan1[freq/100];
}
//=================================显示波形
if(flag==3)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*p);
P0=0x7f;
}
if(flag==4)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+1));
P0=0xbf;
}
if(flag==5)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+2));
P0=0xdf;
}
if(flag==6)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+3));
P0=0xef;
}
if(flag==7)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+4));
P0=0xf7;
}
if(flag==8)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+5));
P0=0xfb;
}
if(flag==9)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+6));
P0=0xfd;
}
if(flag==10)
{
P2=0xff;
P0=0xff;
Hc595SendByte(*(p+7));
P0=0xfe;
}
if(flag<10)
flag++;
else
flag=0;
}
//通道1
if(mode1==0)//正弦
{
PCF8591_write1(wave[time]);
}
if(mode1==1)//方波
{
if(time<128)
PCF8591_write1(0);
else
PCF8591_write1(0xff);
}
if(mode1==2)//梯形波
{
if(time<64)
PCF8591_write1(0);
else
{
if(time<128)
PCF8591_write1((time-64)*4);
else
{
if(time<192)
PCF8591_write1(0xff);
else
PCF8591_write1((255-time)*4);
}
}
}
if(mode1==3)//三角波
{
if(time<128)
PCF8591_write1(time*2);
else
PCF8591_write1((255-time)*2);
}
if(mode1==4)//锯齿波
{
PCF8591_write1(time);
}
//通道2
if(mode2==0)//正弦
{
PCF8591_write2(wave[time]);
}
if(mode2==1)//方波
{
if(time<128)
PCF8591_write2(0);
else
PCF8591_write2(0xff);
}
if(mode2==2)//梯形波
{
if(time<64)
PCF8591_write2(0);
else
{
if(time<128)
PCF8591_write2((time-64)*4);
else
{
if(time<192)
PCF8591_write2(0xff);
else
PCF8591_write2((255-time)*4);
}
}
}
if(mode2==3)//三角波
{
if(time<128)
PCF8591_write2(time*2);
else
PCF8591_write2((255-time)*2);
}
if(mode2==4)//锯齿波
{
PCF8591_write2(time);
}
}