基于51单片机的波形发生器(2路,4种,调幅调频)原理图、流程图、物料清单、仿真图、源代码

本文介绍了使用51单片机实现的双通道信号发生器,支持正弦、方波、三角波和锯齿波,通过按键控制波形振幅和频率,频率范围1-10Hz。代码包括了DAC0832驱动、LCD1602显示以及在Proteus中的PCB仿真。
摘要由CSDN通过智能技术生成

请添加图片描述

课程设计 基于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();
		 }
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

cqtianxingkeji

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

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

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

打赏作者

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

抵扣说明:

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

余额充值