51单片机上AD和DA操作

一、ADC0804的操作
1、试验板上ADC0804的接线图
在这里插入图片描述
AD芯片上的第5管脚INTR没有接线,因为该实验板读取A/D数据没有用中断法,所以可以不接该引脚。
2、芯片的操作时序图如下
在这里插入图片描述
操作芯片时基本按照此顺序操作各个引脚。操作过程:在此实验中要连续转换连续读取数据,就将CS一直置低,没有用到中断也不用操作INTR引脚,剩下就只用操作WR和RD引脚,首先将WR置低,经过tW(WR)L时间后拉高WR,转换开始,经过1~8个A/D时钟周期1/fCLK和内部Tc时间后,转换完成;接着将RD置低,经过tACC时间后数字输出口上的数据达到稳定状态,此时直接读取数字输出端口数据,读完数据直接拉高RD。
3、用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁边的电位器Re2时,在数码管前三位以十进制方式动态显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)。

#include <reg52.h>
sbit ledwela=P2^5;//8个LED灯接在锁存器上,锁存端接P2^5口
sbit dula=P2^6;
sbit wela=P2^7;
sbit adwr=P3^6;//写信号输入,低电平启动A/D转换
sbit adrd=P3^7;//读信号输入,低电平输出端有效
#define uint unsigned int
#define uchar unsigned char
unsigned char code table[]={0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}
void display(uchar num)
{
	dula=1;
	P0=table[num/100];
	dula=0;
	P0=0x7f;//所有的P0最高位都要置低,因为CS片选信号低电平有效,AD启动工作
	wela=1;//其实根据时序图在WR拉高后才进行显示的,但是在此程序中看到数码管只显示255
	P0=0x7e;//说明不置低会出现错误,根据时序图理论上再延时一会应该没问题,我就没有测试了
	wela=0;
	delayms(1);
	wela=1;
	P0=0x7f;
	wela=0;

	dula=1;
	P0=table[num/10%10];
	dula=0;
	P0=0x7f;
	wela=1;
	P0=0x7d;
	wela=0;
	delayms(1);
	wela=1;
	P0=0x7f;
	wela=0;

	dula=1;
	P0=table[num%10];
	dula=0;
	P0=0x7f;
	wela=1;
	P0=0x7b;
	wela=0;
	delayms(1);
	wela=1;
	P0=0x7f;
	wela=0;
}
void main()
{
	uchar num=0,i=0;
	ledwela=1;
	P1=0xff;
	ledwela=0;//控制LED灯不亮,不然看到LED灯随着数码管数字变化。这三行不要就看到数码管显示数字的二进制形式在LED灯上体现
	wela=1;
	P0=0x7f;//因为CS片选信号输入端接在数码管位选锁存器的第八个口
	wela=0;/*片选信号低电平有效,一旦有效,表明ADC被选中,可启动工作。即置低就表示该芯片可被操作
或处于能够正常工作状态。因为我们要连续转换并且连续读取数据,所以一开始置低后就可以了,没有必要每次
置低再拉高,以后只用操作WR和RD就可以了*/
	while(1)
	{
		adwr=0;
		//delayms(1);时序图上要tW(WR)L时长,但可以不加延时,说明tW(WR)L时间非常短
		adwr=1;
		for(i=30;i>0;i--)//相当于delayms(100);AD转换时间。如果时间过短(如果把i改为10)就会出现
		{//拧动电位器数码管没有反应,只有按下复位键后数码管上的数字才会变化,这就是转换的时间不够的原因
			display(num);
		}
		adrd=0;
		//delayms(1);经过tAcc时间后,数字输出口上的数据达到稳定状态.这个延时也可取消,说明时间也很短
		num=P1;//读取P1口	
		adrd=1;
	}
}

AD转换关键在于看懂时序图,根据时序图操作,关键代码如下,记住在WR拉高之后,转换时间要够。
while(1)
{
adwr=0;
adwr=1;
for(i=30;i>0;i–)
{
display(num);
}
adrd=0;
num=P1;
adrd=1;
}
二、DAC0832的操作
1、实验板上的DAC0832接线图
DAC0832芯片数据输入可采用双缓冲、单缓冲和直通三种方式,实验板上的是接成直通方式的。
在这里插入图片描述
在此例程中,DAC0832以电流形式输出,当输出需要转换为电压时可在I(OUT1)和I(OUT2)后外接运算放大器,即将电流转换为电压。在此实验板上I(OUT2)接地,I(OUT1)直接与发光二极管D12相连,由于I(OUT1)电流非常小,所以二极管变化的亮度也很暗。
转换电压的典型接法:
在这里插入图片描述
2、DAC0832内部结构
在这里插入图片描述
3、芯片时序图
在这里插入图片描述
将CS置低后数据总线上数据才开始保持有效数据,再将WR置低,从I(OUT)线看出,在WR置低ts秒后,DA转换完成,I(OUT)输出稳定。在此次例程中要连续转换DA,所以CS和WR一直置低即可,只需一直改变P0口。
4、用单片机控制DAC0832芯片输出电流,让发光二极管D12由灭均匀变到最亮,再由最亮均匀熄灭。在最亮和最暗时使用蜂鸣器分别报警一声,完成整个周期时间控制在5s左右,循环变化。

#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit csda=P3^2;//片选信号输入端,低电平有效..实验板上只有这两个与单片机连接,对比芯片内部结构图看
sbit dawr=P3^6;//输入寄存器的写选通输入端,负脉冲有效。当CS为0ILE为1,WR1有效时DI0~DI7状态被锁存到输入寄存器
sbit dula=P2^6;
sbit wela=P2^7;
sbit beep=P2^3;//蜂鸣器的FM端接单片机的P2^3口
void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}
void main()
{
	uchar valtage=0,k=0;
	dula=0;
	wela=0;//关闭数码管的两个锁存器,因为芯片连接P0口
	csda=0;
	dawr=0;//若是一次转换就拉高两位,这里是连续转换,所以一直置低
	//这里出现了一个奇怪的现象,就是在此处定义uchar valtage=0,k=0;时,编译出错,显示valtage和k未定义
	while(1)
	{
		beep=0;//最暗的时候响蜂鸣器
		P0=valtage;
		valtage+=5;//valtage=5
		delayms(50);
		beep=1;
		for(k=0;k<49;k++)
		{
			P0=valtage;
			valtage+=5;//i=48时,valtage=250
			delayms(50);
		}
		P0=valtage;
		valtage+=5;//valtage=255
		delayms(50);
		beep=0;//最亮的时候打开蜂鸣器
		P0=valtage;
		delayms(50);
		beep=1;//关闭蜂鸣器
		for(k=0;k<50;k++)
		{
			valtage-=5;//i=49时,valtage=5
			P0=valtage;
			delayms(50);
		}
		valtage-=5;//valtage=0
	}
}

一个while循环的时间为(1+49+1+50)*50ms=5050ms,约为5s。课本上93页可以看到倒T形电阻网络DAC转换器电流的分流电路图。
蜂鸣器的电路图如下:蜂鸣器的FM端接单片机的P2^3口
在这里插入图片描述

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值