一个能产生正弦波、方波、三角波、梯形波、锯齿波的波形发生器。
基本实现:
5个按键,每按一次按键后输出对应波形
5个led指示对应波形
示波器中显示2~3个周期波形时,正弦波波形要光滑
双极性电压输出,电压幅值可调.
仿真原理图如下
实验报告
实验名称:波形发生器
单片机实验——DA转换实验
DA转换器是将数字量转换为模拟量的电路,主要用于数据传输系统、自动测试设备、医疗信息处理、电视信号的数字化、图像信号的处理和识别、数字通信和语音信息处理等。按数字量输入方式:并行输入和串行输入DA转换器。按模拟量输出方式:电流输出和电压输出DA转换器。按DA转换的分辩率:低分辩率、中分辩率和高分辩率DA转换器。学习并熟悉如何设置DA转换对于科学研究等将产生重要影响。
1实验目的
了解常用DA转换芯片的结构组成,工作原理。
掌握DAC0832的引脚功能,与单片机连接。
理解单、双极输出方式的电路结构原理,学会用这两种方式。
( 4 ) 设计一个能产生正弦波、方波、三角波、梯形波、锯齿波的波形发生器。
2 D/A转换器工作原理
任D/A是将数字量转换成模拟量的器件,D/A的输出是电压或电流信号。衡量D/A性能的主要参数是:
分辨率:即输出模拟量的最小变化量。
满刻度误差:即输入为全1时,实际输出电压与理想值之差。
输出范围
转换时间:从转换器的输入改变到输出稳定的时间间隔。
是否容易与CPU接口。
3 DAC0832工作方式
DAC0832三种工作方式
单缓冲方式:若应用系统中只有一路D/A转换或虽然有夺路转换,但并不要求各路信号同步输出时,则采用单缓冲的方式来接口。方法是:使锁存器和DAC寄存器同时接收数据。
双缓冲方式:当多路D/A信号要求同步输出时,则采用双缓冲方式。方法是:分别使其输入锁存器接收数据;同时传送数据到其DAC寄存器,以实现多路转换同步输出。
直通方式:所有控制信号均有效,适宜连续控制时。
D/A转换
D/A芯片DAC0832的应用:DAC0832是8位 D/A芯片,片内带数据锁存器,电流输出。该系列产品包括DAC0830——32,它们可以完全相互代换。它由8位输入锁存器、8位DAC寄存器、8位D/A转换电路及转换控制电路组成
ADC0808引脚如图,各引脚功能如下:
DI0-DI7:数据输入线,TLL电瓶。
ILE:数据锁存允许控制信号输入线,高电平有效。
CS:片选信号输入线,低电平有效。
WR1:为输入寄存器的写选通信号。
XFER:数据传送控制信号输入线,低电平有效。
WR2:为DAC寄存器写选通输入线。
Iout1:电流输出线。当输入全为1时Iout1最大。
Iout2:电流输出线。其值与Iout1之和为常数。
Rfb:反馈信号输入线,芯片内部有反馈电阻。
Vcc:电源输入线(+5v~+15v)
Vref:基准电压输入线(-10v~+10v)
AGND:模拟地,模拟信号和基准信号参考地。
DGND:数字地,两种地线在基准电源处共地比较好。
主要功能电路
4.0 电路图
4.1转换电路
4.2波形指示灯
4.3按键电路
4.4单片机电路
4.5 运行结果
三角形
方波
锯齿波
梯形波
正弦波
5. 总结
方波拟合成功,其他波形拟合存在问题。
单片机源程序如下:
#include "reg52.h"
#include
#define ADC_PORT P2 //如图,ADC0832连接端口
//老师要求的5种波
#define W_SINE 0
#define W_SQU 1
#define W_TRI 2
#define W_TRA 3
#define W_SAW 4
#define PI 3.1415926f //圆周率好像是这个数
//简化类型符写法
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sbit ADC_CS_WR=P3^0; //如图,ADC0832使能口
//老师要求的5个LED,接P0口
sbit LED0=P0^0;
sbit LED1=P0^1;
sbit LED2=P0^2;
sbit LED3=P0^3;
sbit LED4=P0^4;
//图给出的5个按键
sbit KEY0=P1^0;
sbit KEY1=P1^1;
sbit KEY2=P1^2;
sbit KEY3=P1^3;
sbit KEY4=P1^4;
//全局变量
u8 mode;//模式:正弦波……
u16 freq;//频率
u8 time;//计次参数
u8 AM;//调幅
void Timer0Init(void);
void scanKey(void);
void sys_init(void);
void sine_wave(u8 location);//正弦波
void squ_wave(u8 location);//方……
void tri_wave(u8 location);//三……
void tra_wave(u8 location);//梯……
void saw_wave(u8 location);//锯……
void Timer0Init(void) //100微秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x02; //设置定时器模式
TL0 = 0x9C; //设置定时初值
TH0 = 0x9C; //设置定时重载值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA = 1; //开总中断
ET0 = 1; //开定时器0中断
}
void scanKey(void)//按键扫描
{
if(KEY0==0)
{
mode=0;
P0=0xFF;//灭所有灯
LED0=0;
}
if(KEY1==0)
{
mode=1;
P0=0xFF;//灭所有灯
LED1=0;
}
if(KEY2==0)
{
mode=2;
P0=0xFF;//灭所有灯
LED2=0;
}
if(KEY3==0)
{
mode=3;
P0=0xFF;//灭所有灯
LED3=0;
}
if(KEY4==0)
{
mode=4;
P0=0xFF;//灭所有灯
LED4=0;
}
}
void sys_init(void)//系统初始化
{
time=0;
ADC_CS_WR=0;
ADC_PORT=0;
mode=0;//默认输出正弦波
freq=100;//默认频率100Hz
AM=255;//最大幅度
}
void sine_wave(u8 location)//输出正弦波
{
double x=(double)location/50*PI;//把0-100放缩到0-2派(pai,没有那个符号,好难受(╯﹏╰))
u8 y=(sin(x)*(AM/2)+(AM/2));//算出y,并放缩到0-254(因为ADC范围0-AM,感觉这个芯片好落后)
ADC_PORT=y;
}
void squ_wave(u8 location)//方……
{
if(location<50)
ADC_PORT=AM;
else
ADC_PORT=0x0;//这个好简单
}
void tri_wave(u8 location)//三……
{
//为了简化,在单周期输出V字形
u8 y;
if(location<50)
y=(50-location)*AM/50;
else
y=(location-50)*AM/50;
ADC_PORT=y;
//偶函数,信不?当然你说奇函数也没错
}
void tra_wave(u8 location)//梯……
{
u8 y;
if(location<25)
y=0xFF;
else if(location<50)
y=(50-location)*AM/25;
else if(location<75)
y=0;
else
y=(location-75)*AM/25;
ADC_PORT=y;
}
void saw_wave(u8 location)//锯……
{
ADC_PORT=location*AM/100;
//用(100-location)也以变成反向锯齿
}
void Timer0Work() interrupt 1 //中断服务函数
{
switch(mode)
……………………
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』