51单片机入门教程(4):构建波形发生器

目录

1、总述

2、系统硬件设计

 3、系统软件设计思路

 3、测试与分析

(1)Proteus仿真测试

(2)直流稳压电源测试

(3)实物测试


1、总述

该篇为51单片机入门教程的实战篇,本篇介绍了以51单片机和DAC0832数模转换芯片为核心的波形发生器,并对DAC0832和UA741的结构和工作原理以及电路连接加以说明。该波形发生器通过AT89C51控制DAC0832产生所需电流,然后使用运算放大器UA741将其电流输出线性地转换成电压输出,结合程序控制,通过4输入与门74LS21控制4个开关,可实现锯齿波、三角波、方波和正弦波之间的切换,输出不同的波形。

2、系统硬件设计

本系统以51单片机为控制核心,对系统进行初始化,主要完成对开关的响应、发送指令等功能的控制,起到总控和协调各模块之间工作的作用。波形的具体产生是通过数模转换模块产生。系统主要包括主控器AT89C51,数模转换电路,幅度、频率调节电路,晶振电路以及外加复位电路组成。本设计的特点是数字信号波形的产生通过程序控制,因而波形输出非常稳定,修改控制程序可实现波形参数的任意改变,同时波形的选择可利用外接开关进行改变。

     

PCB原理图如下:

直流稳压电源电路原理图如下:

 3、系统软件设计思路

(1)锯齿波的实现原理:锯齿波的实现过程是首先定义一个初值然后进行加法操作,加的步数的多少则根据要求的频率来进行。然后加到某个数之后就再重新设置为初值,再重复执行刚刚的操作,如此循环下去。在本程序中初值为00H,最大值为0FFH。

(2)三角波的实现原理:三角波的实现是设置一个初值,然后进行加数,同样是加到某个数之后再进行减数,减到初值之后就再返回到先前的操作。此程序输入的VREF的电压是+5V,因此该波形输出的最大频率是初值为00H和最终值为0FFH,且步数为1,这样输出的波形是最大的。

(3)方波的实现原理:此波形的实现只需开始的时候设置一个初值然后直接输出这个值就行了,输出一段时间后,然后再重新置一个数据,然后再输出这个数据一段时间,但是此时的时间一定要等于前面那段时间。这样才是一个方波,如果两个时间不相同,那就相当于一个脉冲波了。

(4)正弦波的实现原理:正弦波的实现过程是把一个周期分为了四部分,提前写一个内含19个数的数组,以此执行,便可得到正弦波的第一个1/4周期。第二个1/4周期则是将数组倒过来执行,第三和第四个1/4周期就是前两个1/4周期的取反过程。通过上述过程,即可完成一个完整周期的正弦波。

至于按键检测部分的程序,属于比较经典的代码。大致思路就是在中断函数中,通过对高低电平的判断,来检测按键或开关是否闭合。

#include<reg52.h>
#include<absacc.h>
#define uchar unsigned char
#define uint unsigned int
#define DAC 0x7FFF //定义DAC端口地址
uchar code SINTAB[]={0x7F, 0x89, 0x94, 0x9F, 0xAA, 0xB4, 0xBE, 0xC8,0xD1, 0xD9,
											0xE0, 0xE7, 0xED,0xF2, 0xF7,0xFA, 0xFC, 0xFE, 0xFF};
uchar bdata Tbase = 0x20;
sbit KST = Tbase^0; //阶梯波标志
sbit KTRI = Tbase^1; //三角波标志
sbit KSQ = Tbase^2;  //方波标志
sbit KSIN = Tbase^3;//正弦波标志
sbit K1=P1^0; //K1健
sbit K2=P1^2; //K2键
sbit K3=P1^4; //K3键
sbit K4=P1^6; //K4键
//延时函数
void delay()
{  
	uchar i;
	for(i = 0; i<0xff;i++);
}
//阶梯波函数
void st()
{
	uchar i = 0;
	while(KST)
	{
		XBYTE[DAC] = i++;//启动DAC
	}
}
//三角波函数
void tri()
{
	uchar i = 0;
	XBYTE[DAC] = i; //启动DAC
	do
	{
		XBYTE[DAC] = i;  //上升沿
		i++;
	}while(i<0xff);
	do
	{
		XBYTE[DAC] = i;//下降沿
		i--;
	}while(i>0x00);
}
//方波
void sq()
{
	XBYTE[DAC] = 0x00;//启动DAC
	delay();
	XBYTE[DAC] = 0xff;
	delay(); 
}
//正弦波
void sin()
{
	uchar i;
	for(i=0;i<18;i++)
	{
		XBYTE[DAC] = SINTAB[i];//第一个1/4周期
	}
	for(i=18;i>0;i--)
	{
		XBYTE[DAC] = SINTAB[i];//第二个1/4周期
	}
	for(i=0;i<18;i++)
	{
		XBYTE[DAC] = ~SINTAB[i];//第三个1/4周期
	}
	for(i=18;i>0;i--)
	{
		XBYTE[DAC] = ~SINTAB[i];//第四个1/4周期
	}
}
//主函数
main()
{
	EX0=1;IT0=1;EA=1;
	while(1)
	{
		if(KST==1)
		{
			st();
		}
		
		if(KTRI==1)
		{
			tri();
		}
		
		if(KSQ==1)
		{
			sq();
		}
		
		if(KSIN==1)
		{
			sin();
		}
		
	}
}
//中断服务
int0() interrupt 0 using 1
{
	if(K1==0)  //判阶梯波键是否按下
	{
		Tbase = 0;
		KST = 1;
	}
	if(K2==0)  //判三角波键是否按下
	{
		Tbase = 0;
		KTRI = 1;
	}
	if(K3==0)  //判方波键是否按下
	{
		Tbase = 0;
		KSQ = 1;
	}
	if(K4==0)  //判正弦波键是否按下
	{
		Tbase = 0;
		KSIN = 1;
	}
}

 3、测试与分析

(1)Proteus仿真测试

在利用Proteus搭建的仿真电路中,我们可以很容易地进行实验仿真测试,在信号输出端口接一个模拟示波器,切换四个开关,即可观察不同的波形。

由于刚开始我给运放提供的是±5V的直流电压,仿真之后会发现波形失真,因此最后选择用±12V的直流电压对运放UA741进行供电,这样得到的波形才能做到无失真。

(2)直流稳压电源测试

(3)实物测试

利用AT89C51和DAC0832以及其他基本模块完成了总体电路的设计,并用开关来控制各种波形的发生及转换,用单片机输出后,经过模数转换器生成波形,最终可以通过示波器观察到较为理想的波形。通过仿真测试运行结果和实物测试结果表明,该波形发生器能够很好满足实际要求,具有重要的应用价值。 

物联沃分享整理
物联沃-IOTWORD物联网 » 51单片机入门教程(4):构建波形发生器

发表评论