基于51单片机的波形发生器设计(proteus仿真波幅周期可调)

/*********************************************
Waveform generator based on 51

2023/1/10
*********************************************/
#include<reg52.h>
#include<intrins.h>
#include<math.h>
#define  data_L P2						//P2引脚接DAC1208(12位分辨率)的低八位
#define  data_H P1						//P1引脚的低四位接DAC1208的高四位
										//共计12位
#define uint unsigned int
#define uchar unsigned char

sbit wave_button = P3^2;				//波形参数调整按钮
sbit adder_button = P3^1;				//参数增键
sbit reduce_button = P3^0;				//参数减键
sbit led_wave = P3^3;					
sbit cs = P3^4;							//DAC1208片选位

void delay5us(unsigned char);
void delay100us(unsigned char);
void delay6ms(unsigned char);
void delay50ms(unsigned char);
void Square_wave(void);					//方波输出函数
void Triangle_wave(void);				//三角波输出函数
void sinusoid(void);					//正弦波输出函数
void initEx0(void);						//外部中断0
void add_(void);						//参数调整函数

uint am;								//正弦波波幅调整参数
uint T=1;								//波形周期调整参数
uint ampl_H,ampl_L;						//三角波、方波波幅调整参数
uint adjust=0;							//调整对象选择变量
uint amplitude = 0x07ff;				//三角波、方波波幅初始参数
uint break_signal = 0;					//波形切换
unsigned int code sin_data[]=
			{0x7F,0x82,0x85,0x88,0x8B,0x8F,0x92,0x95,0x98,0x9B,0x9E,0xA1,0xA4,0xA7,0xAA,0xAD
			,0xB0,0xB3,0xB6,0xB8,0xBB,0xBE,0xC1,0xC3,0xC6,0xC8,0xCB,0xCD,0xD0,0xD2,0xD5,0xD7
			,0xD9,0xDB,0xDD,0xE0,0xE2,0xE4,0xE5,0xE7,0xE9,0xEB,0xEC,0xEE,0xEF,0xF1,0xF2,0xF4
			,0xF5,0xF6,0xF7,0xF8,0xF9,0xFA,0xFB,0xFB,0xFC,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE
			,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFD,0xFD,0xFC,0xFB,0xFB,0xFA,0xF9,0xF8,0xF7,0xF6
			,0xF5,0xF4,0xF2,0xF1,0xEF,0xEE,0xEC,0xEB,0xE9,0xE7,0xE5,0xE4,0xE2,0xE0,0xDD,0xDB
			,0xD9,0xD7,0xD5,0xD2,0xD0,0xCD,0xCB,0xC8,0xC6,0xC3,0xC1,0xBE,0xBB,0xB8,0xB6,0xB3
			,0xB0,0xAD,0xAA,0xA7,0xA4,0xA1,0x9E,0x9B,0x98,0x95,0x92,0x8F,0x8B,0x88,0x85,0x82
			,0x7F,0x7C,0x79,0x76,0x73,0x6F,0x6C,0x69,0x66,0x63,0x60,0x5D,0x5A,0x57,0x54,0x51
			,0x4E,0x4B,0x48,0x46,0x43,0x40,0x3D,0x3B,0x38,0x36,0x33,0x31,0x2E,0x2C,0x29,0x27
			,0x25,0x23,0x21,0x1E,0x1C,0x1A,0x19,0x17,0x15,0x13,0x12,0x10,0x0F,0x0D,0x0C,0x0A
			,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00
			,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08
			,0x09,0x0A,0x0C,0x0D,0x0F,0x10,0x12,0x13,0x15,0x17,0x19,0x1A,0x1C,0x1E,0x21,0x23
			,0x25,0x27,0x29,0x2C,0x2E,0x31,0x33,0x36,0x38,0x3B,0x3D,0x40,0x43,0x46,0x48,0x4B
			,0x4E,0x51,0x54,0x57,0x5A,0x5D,0x60,0x63,0x66,0x69,0x6C,0x6F,0x73,0x76,0x79,0x7C};
			
			//正弦波离散点(256个)

int main()
{
	
	initEx0();					//启动外部中断0
	
	while(1)
	{
		cs = 0;					//启动DAC1208
		
		switch(break_signal)	//信号break_signal控制输出波形
		{
			case 0: Square_wave();	break;
			case 1: Triangle_wave();break;
			case 2: sinusoid();		break;
			default:				break;
		}
	}
	
	
	return 0;
}



void Square_wave()		//方波
{
		while(1)
		{
			ampl_H = (amplitude >> 8);          //amplitude初始值0x07ff(2.5V)
			ampl_L = ((amplitude << 8)/256);
			data_H = ampl_H;
			data_L = ampl_L;
			delay100us(T);						//变量T控制程序内部延时时间(即控制通过控制T控制周期)
			data_L = 0x00;
			data_H = 0x00;
			delay100us(T);
			while(!(adder_button && reduce_button))
			{
				delay100us(10);
				add_();
			}
			if(break_signal != 0)
				break;
		}	
}


void Triangle_wave()	//三角波
{
		data_L = 0x00;
		data_H = 0x00;
		while(1)
		{
			while(1)
			{
				ampl_H = (amplitude >> 8);
				ampl_L = ((amplitude << 8)/256);
				delay5us(T);
				data_L++;
				if((data_L == 0xff)&&(data_H != ampl_H))		//data值线性增加(三角波上升部分)
				{
					data_L = 0;
					data_H++;
				}
				if((data_H == ampl_H)&&(data_L == ampl_L))
					break;
			}
			
			while(1)
			{
				ampl_H = (amplitude >> 8);
				ampl_L = ((amplitude << 8)/256);				//data值线性减小(三角波下降部分)
				delay5us(T);
				data_L--;
				if((data_L == 0)&&(data_H != 0))
				{
					data_H--;
					data_L = 255;
				}
				if((data_H == 0)&&(data_L == 0))
					break;
			}
			while(!(adder_button && reduce_button))
			{
				delay100us(10);
				add_();
			}
			if(break_signal != 1)
				break;
		}
}


void sinusoid()		//正弦波
{
		while(1)
		{
			uint i;
			uchar sin;
			for(i=0;i<=255;i++)
			{
				sin = sin_data[i]>>am;
				data_L = sin<<4;
				data_H = sin>>4;
				delay5us(T);
			}
			while(!(adder_button && reduce_button))
			{
				delay100us(10);
				add_();
			}
			if(break_signal != 2)
				break;
		}	
}

void add_()			//变量调整函数
{
	if(adjust == 1)			//为1,调整对象为波幅
	{
		if((adder_button == 0)&&(amplitude != 0x0fff)&&(break_signal != 2))
			amplitude++;
		else if((reduce_button == 0)&&(amplitude != 0x0000)&&(break_signal != 2))
			amplitude--;
		else if((adder_button == 0)&&(am>0))
		{	
			delay50ms(5);
			am--;
		}
		else if((reduce_button == 0)&&(am<9))
		{	
			delay50ms(5);
			am++;
		}
		else
			am = am;
			amplitude = amplitude;
	}
	else if(adjust == 2)	//为2,调整对象为周期
	{
		delay50ms(5);
		if((adder_button == 0)&&(T < 500))
			T++;
		else if((reduce_button == 0)&&(T > 2))
			T--;
		else
			T = T;
	}
}

void initEx0()
{
	EA = 1;
	EX0 = 1;
	IT0 = 1;
}

void Ex0_intr() interrupt 0			//外部中断函数
{
	delay50ms(20);
	if(wave_button == 0)      //长按(大于1s)
	{	
		while(!wave_button);
		adjust = adjust + 1;
		if(adjust == 3)
			adjust = 0;
	}
	else					  //短按
	{
		break_signal = break_signal + 1;
		if(break_signal == 3)
			break_signal = 0;
	}
}

void delay100us(unsigned char delay_time_squ)   // 100us
{
    unsigned char a,b;
    for(b=delay_time_squ;b>0;b--)
        for(a=47;a>0;a--);
}

void delay6ms(unsigned char delay_time_Tri)   //	6ms
{
    unsigned char a,b,c;
    for(c=delay_time_Tri;c>0;c--)
        for(b=222;b>0;b--)
            for(a=12;a>0;a--);
}

void delay50ms(unsigned char delay_time_sin)   //	50ms
{
    unsigned char a,b,c;
		for(c=delay_time_sin;c>0;c--)
			for(b=173;b>0;b--)
					for(a=143;a>0;a--);
}

void delay5us(unsigned char delay_time_5u)   //  5us
{
    unsigned char a;
    for(a=delay_time_5u;a>0;a--);
}

  • 2
    点赞
  • 52
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GLY_2002

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

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

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

打赏作者

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

抵扣说明:

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

余额充值