1070-基于51单片机的波形发生器(4种,振幅,频率,相差)原理图、流程图、物料清单、仿真图、源代码

1070-基于51单片机的波形发生器(4种,振幅,频率,相差)原理图、流程图、物料清单、仿真图、源代码

功能介绍:

双通道信号发生器
1、可通过串口设置波形灯参数
2、输出正弦波、方波、三角波或锯齿波
3、波的类型、振幅、频率可调
4、波的相位差可调

有哪些资料:

1、仿真工程文件
2、源代码工程文件
3、原理图工程文件
4、流程图
5、功能介绍
6、元件清单

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

#include<reg51.h>
#include"absacc.h"
#include"intrins.h"
#include "lcd1602.h"
#include "ad5601.h"
#define uchar unsigned char
#define uint unsigned int
#define out XBYTE[0xfeff]
sbit k1=P2^3;//按钮
sbit k2=P2^4;
sbit k3=P2^5;
sbit k4=P2^6;
sbit k5=P2^7;

uchar boxing=0;//波形。正弦、三角、锯齿	、方波
uint bu=0,step=1;//步进数

uint freq=100;	//频率
uint amp1=255,amp2=255;//振幅
uint xiang=64;//相位
uchar time=0;//计时
//波形Triangle wave.sine wave.sine wave
uchar two[]="F:0000Hz  P:000 ";//频率+相位
uchar one[]="1:0.00V  2:0.00V";//振幅
uchar code zhengx[]={//正弦编码
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,1,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,128,128};
void disp()//显示
{
	two[2]=freq/3/1000+0x30; //频率
	two[3]=freq/3%1000/100+0x30;
	two[4]=freq/3%100/10+0x30;
	two[5]=freq/3%10+0x30;
	two[12]=(xiang*72/51)/100+0x30;
	two[13]=(xiang*72/51)%100/10+0x30;
	two[14]=(xiang*72/51)%10+0x30;
	one[2]=(amp1/51)+0x30;//振幅
	one[4]=(amp1*100/51)%100/10+0x30;
	one[5]=(amp1*100/51)%10+0x30;
	one[11]=(amp2/51)+0x30;//振幅
	one[13]=(amp2*100/51)%100/10+0x30;
	one[14]=(amp2*100/51)%10+0x30;
	write_string(2,0,two);
	write_string(1,0,one);
}
uchar key_scan()//按键检测
{
uchar i,j;
i=0;
j=0;
P1=0x0f;
if(P1!=0x0f) //检测有无按下
{
 switch(P1)//检测行
 {
  case 0x0e:i=1;break;
  case 0x0d:i=5;break;
  case 0x0b:i=9;break;
  case 0x07:i=13;
 }
 P1=0xf0;
 switch(P1)//检测列
 {
  case 0xe0:j=0;break;
  case 0xd0:j=1;break;
  case 0xb0:j=2;break;
  case 0x70:j=3;
 }
 while(P1!=0xf0);//等待按键松开
}
return i+j;
}

void main()
{
	uchar i;
	ad5601_init();
	two[15]=0xdf;
	SCON=0X50;			//设置为工作方式1
	TMOD=0X22;			//设置计数器工作方式2
	TH1=0XFD;			
	TL1=0XFD;
	ES=1;						//打开接收中断
	TR1=1;					//打开计数器	
//设置定时器
	TH0=156;//给定时器赋初值
	TL0=156;	
	ET0=1;//打开定时器0中断允许
	TR0=0;//打开定时器
	EA=1;//打开总中断

	init_1602();//初始化LCD
	disp();
	step=64*freq/5;//计算步进数
	while(1)
	{
		i=key_scan();
		if(i==1)//波形切换
		{
			if(boxing<3)
				boxing++;
			else
				boxing=0;
		}
		if(i==9)//频率加
		{
			freq+=2;
			step=64*freq/5;//计算步进数
			disp();
		}
		if(i==13)//频率减
		{
			freq-=2;
			step=64*freq/5;//计算步进数
			disp();
		}
		if(i==2)//振幅加
		{
			if(255-amp1>10)
			amp1+=10;
			disp();
		}
		if(i==3)//振幅减
		{
			if(amp1>0)
			amp1-=10;
			disp();
		}
		if(i==6)//振幅加
		{
			
			if(255-amp2>10)
			amp2+=10;
			disp();
		}
		if(i==7)//振幅减
		{
			if(amp2>0)
			amp2-=10;
			disp();
		}
		if(i==10)//相位加
		{
			if(xiang<255)
			xiang++;
			disp();
		}
		if(i==14)//相位减
		{
			if(xiang>0)
			xiang--;
			disp();
		}	
	}
}
void Timer0() interrupt 1//定时器中断
{
	uint i;
	uchar num=0;
	TR0=0;
	bu+=step;
	if(bu>25500)
		bu=0;
	time=bu/100;
	if(boxing==0)//正弦波
	{		
		i=zhengx[time]*amp1;
		i=i/255;
		ad5601_send(i<<6);
	}
	if(boxing==1)//三角波
	{
		if(time<128)
		{
			i=time*amp1;
			i=i/255;
			ad5601_send(i<<6);
		}
		else
		{
			i=(255-time)*amp1;
			i=i/255;
			ad5601_send(i<<6);
		}
	}
	if(boxing==2)//锯齿波
	{
		i=time*amp1;
		i=i/255;
		ad5601_send(i<<6);
	}
	if(boxing==3)//方波
	{
		if(time<128)
			ad5601_send(amp1<<6);
		else
			ad5601_send(0);
	}
	//==============================
	num=time+xiang;
	if(boxing==0)//正弦波
	{		
		i=zhengx[num]*amp2;
		i=i/255;
		ad5601_send1(i<<6);
	}
	if(boxing==1)//三角波
	{
		if(num<128)
		{
			i=num*amp2;
			i=i/255;
			ad5601_send1(i<<6);
		}
		else
		{
			i=(255-num)*amp2;
			i=i/255;
			ad5601_send1(i<<6);
		}
	}
	if(boxing==2)//锯齿波
	{
		i=num*amp2;
		i=i/255;
		ad5601_send1(i<<6);
	}
	if(boxing==3)//方波
	{
		if(num<128)
			ad5601_send1(amp2<<6);
		else
			ad5601_send1(0);
	}
	TR0=1;
}
//串口中断
void Usart() interrupt 4
{
	uchar i;
	i=SBUF;//出去接收到的数据
	RI = 0;//清除接收中断标志位
	if(i=='Q')//波形切换
		{
			if(boxing<3)
				boxing++;
			else
				boxing=0;
		}
		if(i=='W')//频率加
		{
			freq+=2;
			step=64*freq/5;//计算步进数
			disp();
		}
		if(i=='E')//频率减
		{
			freq-=2;
			step=64*freq/5;//计算步进数
			disp();
		}
		if(i=='R')//振幅加
		{
			if(255-amp1>10)
			amp1+=10;
			disp();
		}
		if(i=='T')//振幅减
		{
			if(amp1>0)
			amp1-=10;
			disp();
		}
		if(i=='A')//振幅加
		{
			
			if(255-amp2>10)
			amp2+=10;
			disp();
		}
		if(i=='S')//振幅减
		{
			if(amp2>0)
			amp2-=10;
			disp();
		}
		if(i=='D')//相位加
		{
			if(xiang<255)
			xiang++;
			disp();
		}
		if(i=='F')//相位减
		{
			if(xiang>0)
			xiang--;
			disp();
		}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我Eric

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值