基于51单片机的波形发生器(正弦,方波,锯齿,数码管,振幅频率)原理图 PCB 仿真 源代码及proteus 软件

基于MCS-51单片机的信号发生器

采用带内部程序存储器的MCS51单片机,采用10位精度D/A(TLC5615),采用运算放大器LM358调节输出信号幅度。使输出最大幅度为0.1V–3V可调。输出的函数信号为正弦波,方波,锯齿波,频率为0.1Hz–100Hz。用数码管显示输出信号类型和频率,扩展按键用于输出功能选择。

说明:频率越高,误差越大,因为51单片机速度太慢了

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
在这里插入图片描述

#include<reg51.h>
#include"intrins.h"
#include"TLC5615.h"
#include "74hc595.h"
#define uchar unsigned char
#define uint unsigned int

sbit smg1=P2^0;//数码管引脚
sbit smg2=P2^1;
sbit smg3=P2^2;
sbit smg4=P2^3;
sbit smg5=P2^4;
sbit smg6=P2^5;
sbit smg7=P2^6;
sbit smg8=P2^7;
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 boxing=0;//波形。正弦、锯齿、方波
uint step=0;//步进数
uchar bu=0;
uchar sec=0,flag=0;//显示计时

uint freq=1000;	//频率/10
uint amp=30;//振幅
uint time=0;//计时
uchar code zhengx[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 key=0;
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;
 }
 }
	if(key!=i+j)
	{
		key=i+j;
		return key;
	}
	else
		return 0;
}
//主函数
void main()
{
	uchar i;
	Hc595SendByte(~amp);
	TMOD=0X02;			//设置计数器工作方式2
//设置定时器
	TH0=217;//给定时器赋初值
	TL0=217;	
	ET0=1;//打开定时器0中断允许
	TR0=1;//打开定时器
	EA=1;//打开总中断

	while(1)
	{
		i=key_scan();
		if(i==1)//正弦波
		{
			boxing=0;
		}
		if(i==2)//方波
		{
			boxing=1;
		}
		if(i==3)//锯齿波
		{
			boxing=2;
		}
		if(i==5)//频率加
		{
			if(freq<1000)
				freq++;
			step=1000/freq-1;//计算步进数
		}
		if(i==6)//频率减
		{
			if(freq>1)
				freq--;
			step=1000/freq-1;//计算步进数
		}
		if(i==9)//频率加10
		{
			if(freq<1000)
				freq+=10;
			step=1000/freq-1;//计算步进数
		}
		if(i==10)//频率减10
		{
			if(freq>10)
				freq-=10;
			step=1000/freq-1;//计算步进数
		}
		if(i==13)//频率加100
		{
			if(freq<1000)
				freq+=100;
			step=1000/freq-1;//计算步进数
		}
		if(i==14)//频率减100
		{
			if(freq>100)
				freq-=100;
			step=1000/freq-1;//计算步进数
		}
		if(i==7)//振幅加
		{
			if(amp<30)
				amp++;
			Hc595SendByte(~amp);
		}
		if(i==8)//振幅减
		{
			if(amp>1)
				amp--;
			Hc595SendByte(~amp);
		}
		if(i==11)//振幅加10
		{
			if(amp<30)
				amp+=10;
			Hc595SendByte(~amp);
		}
		if(i==12)//振幅减10
		{
			if(amp>10)
				amp-=10;
			Hc595SendByte(~amp);
		}
	}
}
void Timer0() interrupt 1//定时器中断
{
	uint i;
	if(time<step)//周期延时
		time++;
	else
	{
		time=0;
		bu++;
	if(boxing==0)//正弦波
	{		
		i=zhengx[bu];
		WriteTLC5615(i<<1);
	}
	if(boxing==2)//锯齿波
	{
		WriteTLC5615(bu<<1);
	}
	if(boxing==1)//方波
	{
		if(bu<128)
			WriteTLC5615(0);
		else
			WriteTLC5615(255);
	}	
	}
	//显示
	if(sec<5)
		sec++;
	else
	{
		sec=0;
		if(flag<6)
			flag++;
		else
			flag=0;
		switch(flag)
		{
			case 0:smg8=1;P0=smgduan0[boxing];smg1=0;break;
			case 1:smg1=1;P0=smgduan0[freq/1000];smg3=0;break;
			case 2:smg3=1;P0=smgduan0[freq%1000/100];smg4=0;break;
			case 3:smg4=1;P0=smgduan1[freq%100/10];smg5=0;break;
			case 4:smg5=1;P0=smgduan0[freq%10];smg6=0;break;
			case 5:smg6=1;P0=smgduan1[amp/10];smg7=0;break;
			case 6:smg7=1;P0=smgduan0[amp%10];smg8=0;break;
		}
	}
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐