使用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;
}
}