51单片机AD转换

51单片机AD转换电路设计实现
关于AD转换的原理,大家在《数字电子技术》中已经学过,这里做过多的介绍,本文介绍一款经典的8位AD转换芯片ADC0804,基于51单片机设计AD转换电路,并完成测量值的转换。
1 芯片引脚介绍
在这里插入图片描述
CS:片选信号,低电平有效,即CS=0时候芯片才能正常工作,单独一个ADC0804芯片时候直接置零。当有多个芯片时候可以通过片选信号实现分时复用。
WR:低电平有效,当WR信号由高到低时候实现一次ADC转换。
RD:低电平有效,RD=0时候可以读取数据。
Vin+:模拟电压输入端。
Vin-:一般接地,当模拟电压是双边输入时候Vin+和Vin-分别接模拟电压的正负极。
VREF/2:参考电压接入引脚,可悬空或接外界电压。接外电压时候芯片的参考电压为所接电压的两倍。悬空时候芯片参考电压为VCC。
CLKR/CLKIN:外接RC电路产生转换所需的时钟信号,CLK=1/1.1RC。
AGND和DGND:模拟和数字地。
INTR:中断请求信号输出引脚,当完成一次AD转换后该引脚为低电平,一般与单片机的中断信号相连。
DB0~DB7:输出转换后的八位二进制结果。
2 ADC0804的一般接法:
在这里插入图片描述
Proteus仿真电路:
在这里插入图片描述
3 ADC0804的工作时序:
在这里插入图片描述
启动转换时序
先将CS置低电平,芯片开始工作,WR随后置低,经过一段时间的低电平之后,WR拉高,AD转换启动,经过1-8个A/D时钟周期后,模数转换完成,INTR引脚拉低,通知单片机本次转换完成。
在这里插入图片描述
数据读取时序
当INTR为低电平时,先将CS置低,接着RD置低,经过一段时间后数字输出口上的数据达到稳态,此时单片机可以读取数据,读取完成后将RD拉高,最后将CS拉高。INTR自动变化,无需人为操作。一般在只有一片ADC0804芯片时候,可以一直将CS置低。
4 仿真实现
51单片机读取ADC0804数据的方式有两种,一种是通过不断扫描的方式读取;另一种是将ADC0804的INTR引脚接单片机的中断引脚,当AD转换完成后,通过外部中断的方式通知单片机读取数据。
4.1 扫描的方式
Proteus仿真电路图
在这里插入图片描述
源代码:

#include <reg51.h>
#include <intrins.h>
sbit CS=P3^5;
sbit adrd=P3^7;
sbit adwr=P3^6;
unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char com[]={0x01,0x02,0x04,0x08};
unsigned char num,num2=0,time[4]={0,0,0,0},val;
float val2;
unsigned int val3;


void main()
{
	TMOD=0x01;
	TH0=(65536-917)/256;		
	TL0=(65536-917)%256;;		
	EA=1;
	ET0=1;
	TR0=1;
	CS=0;
	while(1){
	   adwr = 1;//
     _nop_();
     adwr = 0;//
		_nop_();
     adwr = 1;//
   
     P1 = 0xff;//
     adrd = 1;//
     _nop_();
		 adrd = 0;//
     _nop_();
     val = P1;//
     adrd = 1;//
		  
	  	val2=((val*1.0/255)*5.0);
	  	val3=val2*1000;
		  time[0]=val3/1000;
			time[1]=val3%1000/100;
		  time[2]=val3%100/10;
			time[3]=val3%10;
		
		
	}
}

void Timer0() interrupt 1
{
  TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;	
	num++;
		if(num==10){		
			num=0;
			P0=~com[num2];
		  P2=0xff;
			if(num2==0)
			{P2=display[time[num2]]|0x80;}
      else			
		  {P2=display[time[num2]];}
			num2++;
			if(num2>=4)
			num2=0;	
		}
	  
}

4.2 外部中断的方式
Proteus仿真电路

在这里插入图片描述
源代码:

#include <reg51.h>
#include <intrins.h>
sbit CS=P3^5;
sbit adrd=P3^7;
sbit adwr=P3^6;
unsigned char code display[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
unsigned char com[]={0x01,0x02,0x04,0x08};
unsigned char num,num2=0,time[4]={0,0,0,0},val;
float val2;
unsigned int val3;

void Delay50ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	_nop_();
	_nop_();
	i = 3;
	j = 26;
	k = 223;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


void main()
{
	TMOD=0x01;
	TH0=(65536-917)/256;		
	TL0=(65536-917)%256;;		
	EA=1;
	ET0=1;
	TR0=1;
	
	
  EX0=1;
	IT0 = 0;
	
	
	CS=0;
	while(1){
	   adwr = 1;//
     _nop_();
     adwr = 0;//
		_nop_();
     adwr = 1;//
    Delay50ms();	
		
	}
}

void Timer0() interrupt 1
{
  TH0 = (65536-917)/256;		
	TL0 = (65536-917)%256;;	
	num++;
		if(num==10){		
			num=0;
			P0=~com[num2];
		  P2=0xff;
			if(num2==0)
			{P2=display[time[num2]]|0x80;}
      else			
		  {P2=display[time[num2]];}
			num2++;
			if(num2>=4)
			num2=0;	
		} 
}

void Init0() interrupt 0
{
     adrd = 1;//
     _nop_();
	 adrd = 0;//
     _nop_();
     val = P1;//
     adrd = 1;//
		  
	   val2=((val*1.0/255)*5.0);
	   val3=val2*1000;
		 time[0]=val3/1000;
		 time[1]=val3%1000/100;
		 time[2]=val3%100/10;
		 time[3]=val3%10;
}
  • 21
    点赞
  • 187
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值