1. 设计内容和设计要求
1.1 设计内容
利用AT89C52单片机、DAC0832、ADC0808设计信号发生器,能够产生固定幅值的方波、锯齿波、三角波及正弦波。要求能够调节信号的幅度及频率,并在波形切换过程中,能够给予相应的指示。其中幅值采用DAC0832进行调节,频率的设定部分采用ADC0808进行调节,并可以在不同的波形之间任意切换。
1.2设计要求
(1)完成原理图设计、系统仿真
(2)ADC0808和DAC0832自己查阅资料
2.所用器件列表
器件列表如表1
元件 | 参数 | 个数 | |
1 | 电容 | 30pf | 2 |
2 | 电容 | 10uf | 1 |
3 | 发光二极管 | 红黄蓝绿 | 4 |
4 | 电阻 | 200 | 4 |
5 | 排阻 | 1k | 1 |
6 | 电阻 | 10k | 1 |
7 | 电阻 | 1k | 2 |
8 | AT89C52 | \ | 1 |
9 | ADC0808 | \ | 1 |
10 | DAC0832 | \ | 1 |
11 | 放大器 | \ | 1 |
12 | 电源 | \ | \ |
13 | 接地端 | \ | \ |
14 | 滑动变阻器 | 1k | 2 |
15 | 示波器 | \ | 1 |
(表1)
3.系统工作原理及原理图
3.1系统工作原理
利用8位D/A转换器DAC0832,可以将8位数字量转换成模拟量输出。数字量输入范围为0-255之间,对应的模拟量输出范围在VREF-~VREF+之间。根据这一特性,可以利用单片机的并行口输出的数字量,产生常用的波形。而调节输出波形只需调节VREF即可。调节信号频率,只需在单片机输出的两个数据之间加入一定的延时即可,通过调节输入ADC0808转换的模拟电压值,从而产生8位二进制数作为延时函数,即可输出波形的频率。
波形切换可以利用4位DIP开关DSW1来选择波形,并通过4个LED来进行指示。
以锯齿波为例,要产生0~5v的锯齿波,只要将DAC0832的VREF-接地,VREF+接5v,单片机并行口首先输出00H,再输入01H、02H,直到FFH,再输入00H,依次循环,这OUTPUT端所连接的示波器就可以看到0~5V之间变化的锯齿波。
DAC0832引脚图如图1
图1 DAC0832引脚图
(1)D0~D7:8位数据输入线
(2)ILE:数据锁存允许控制输入线,高电平有效
(3)CS:片选信号,低电平有效
(4)WR1:数据锁存器写选通输入线
(5)XFER:数据传输控制信号输入线,低电平有效
(6)WR2:DAC寄存器选通输入线,负脉冲有效
(7)IOUT1:电流输出端1,一般IOUTI+IOUT2=常数
(8)IOUT2:电流输出端2
(9)RFB:反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度
(10)Vcc:接电源
(11)DGND:接数字地,芯片数字信号接地点
(12)AGND:接模拟地,芯片模拟信号接地点
(13)VREF:参考电压输入端,可接正电压,也可接负电压,范围为-10V~+10V。
ADC0809引脚图如图2
图2 ADC0808引脚图
各引脚功能如下:
(1)IN0-IN7:8 路模拟量输入通道。
(2)D7-D0:数据输出线,为三态缓冲输出形式,可以和单片机的数据线直接相连。
(3)ADDA、ADDB、ADDC:三位地址输入线,用于选通 8 路模拟输入中的一路,ADD为低位地址,ADDC 为高位地址。当 ADDC、ADDB、ADDA为000时,选通IN0通道;为001,选通IN1 通道;……为 111,选通 IN7 通道。
(4)ALE:地址锁存允许信号,输入高电平有效。
(5)START:A/D转换启动脉冲输入端,输入一个正脉冲(至少 100ns 宽)使其启动(脉冲上升沿使A/D转换器复位,下降沿启动 A/D 转换)。
(6)EOC:A/D 转换结束信号。启动转换后,系统自动设置 EOC=0(转换期间一直为低 电平),当A/D转换结束时,EOC=1(次端输出一个高电平)。该状态信号既可作为查询的状态标志,又可作为中断请求信号使用。
(7)OE:数据输出允许信号,输入高电平有效。当 A/D 转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量。
(8)CLK:时钟脉冲输入端。ADC0808/ADC0809 的内部没有时钟电路,所需时钟信号由外界提供,通常使用频率为 500kHz 的时钟信号。
(9)Vref(+)、Vref(-):基准电压,用来与输入的模拟信号进行比较,作为逐次逼近的基准,其典型值为+5V(Vref(+)=+5V,Vref(-)=0V)。
3.2系统原理图
原理图如图3
图 3 系统原理图
4.程序流程图及程序清单
程序流程图如图4
图 4 流程图
#include <reg52.h>
#include <intrins.h>
sbit OE=P3^0;
sbit EOC=P3^1;
sbit CLK=P3^4;
sbit ST=P3^2;
sbit K1=P1^4;
sbit K2=P1^5;
sbit K3=P1^6;
sbit K4=P1^7;
sbit LEDB=P1^0;
sbit LEDG=P1^1;
sbit LEDR=P1^2;
sbit LEDY=P1^3;
#define ADC P2
#define uchar unsigned char
#define uint unsigned int
uchar code sin[]={0,0,0,0,1,1,2,3,4,5,6,8,9,11,13,15,17,19,22,24,27,30,33,36,39,42,46,49,53,56,60,64,68,72,76,80,84,88,92,97,101,105,110,114,119,123,128,132,136,141,145,150,154,158,163,167,171,175,179,183,187,191,195,199,202,206,209,213,216,219,222,225,228,231,233,236,238,240,242,244,246,247,249,250,251,252,253,254,254,255,255,255};void timer () interrupt 1 //用定时器来创造时钟函数
{CLK=~CLK;
}
uchar adc0808()
{uchar t;ST=0;ST=1; //形成下跳脉冲信号,开启adST=0;while(!EOC); //等待转换完成OE=1; //允许输出t=ADC; //获取输出return (t);
}
/**********方波*********/
void square()
{uchar a,b;for(a=0;a<127;a++){P0=0xff;P2=0xff;b=adc0808();b=~b;while(b--);}for(a=0;a<127;a++){P0=0x00;P2=0xff;b=adc0808();b=~b;while(b--);}
}
/********锯齿波*******/
void sawtooth()
{uchar a,b;for(a=0;a<255;a++){P0=a;P2=0xff;b=adc0808();b=~b;while(b--);}
}
/*******三角波*******/
void triang()
{uchar a,b;for(a=0;a<254;a=a+2){P0=a;P2=0xff;b=adc0808();b=~b;while(b--);}for(a;a>1;a=a-2){P0=a;P2=0xff;b=adc0808();b=~b;while(b--);}
}
/*******正弦波******/
void sinwave()
{uchar a,b;for(a=0;a<92;a++){P0=sin[a];P2=0xff;b=adc0808();b=~b;while(b--);}for(a=a-1;a>0;a--){P0=sin[a];P2=0xff;b=adc0808();b=~b;while(b--);}
}main()
{EA=1; //开定时ET0=1;TMOD=0X02;TH0=0Xff;TL0=0Xff;TR0=1;while(1){P0=0;if(K1==0){LEDB=0;square(); //方波,蓝灯}LEDB=1;if(K2==0){LEDG=0;sawtooth(); //锯齿波,绿灯}LEDG=1;if(K3==0){LEDR=0;triang(); //三角波, 红灯}LEDR=1;if(K4==0){LEDY=0;sinwave(); //正弦波,黄灯}LEDY=1;}
}
仿真结果: