AT89C51使用DAC0832数模转换,波形发生器


  使用51单片机和DAC0832构建按键波形发生器,按下不同的按键能够产生不同波形,可以产生波形为阶梯波、三角波、方波、正弦波。

DAC0832简介

  DAC0832是采样频率为八位的D/A转换器件,芯片内有两级输入寄存器,使DAC0832具备双缓冲、单缓冲和直通三种输入方式。

  1、单缓冲方式。单缓冲方式是控制输入寄存器和DAC寄存器同时接收资料,或者只用输入寄存器而把DAC寄存器接成直通方式。此方式适用只有一路模拟量输出或几路模拟量异步输出的情形。
  2、双缓冲方式。双缓冲方式是先使输入寄存器接收资料,再控制输入寄存器的输出资料到DAC寄存器,即分两次锁存输入资料。此方式适用于多个D/A转换同步输出的情节。
  3、直通方式。直通方式是资料不经两级锁存器锁存,即 CS*,XFER* ,WR1* ,WR2* 均接地,ILE接高电平。此方式适用于连续反馈控制线路和不带微机的控制系统,不过在使用时,必须通过另加I/O接口与CPU连接,以匹配CPU与D/A转换。

DAC0832的逻辑框图和引脚排列:
在这里插入图片描述
引脚简介:

D0~D7:数字信号输入端。

ILE:输入寄存器允许,高电平有效。

CS:片选信号,低电平有效。

WR1:写信号1,低电平有效。

XFER:传送控制信号,低电平有效。

WR2:写信号2,低电平有效。

IOUT1、IOUT2:DAC电流输出端。

Rfb:是集成在片内的外接运放的反馈电阻。

Vref:基准电压(-10~10V)。

Vcc:是源电压(+5~+15V)。

AGND:模拟地 NGND:数字地,可与AGND接在一起使用。

电路构建

在这里插入图片描述

单片机代码

#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;
	}
}

效果截图

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45488643/article/details/106859627