欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

ADC0809模数转换与显示

程序员文章站 2024-02-25 14:56:09
...

环境

软件

  • uVision V4.02
  • ISIS Professional 7.8

芯片

  • AT89C51
  • ADC0809

实现效果

用电阻阻值大小控制,并用七段数码管显示0~500的数
ADC0809模数转换与显示

相关代码及资源

https://github.com/duganlx/DSP

操作小记

芯片介绍

ADC0809是带有8位A/D转换器、8路多路开关以及微处理机兼容的控制逻辑的CMOS组件。它是逐次逼近式A/D转换器,可以和单片机直接接口。

内部逻辑结构

ADC0809模数转换与显示
由上图可知,ADC0809由一个8路模拟开关、一个地址锁存与译码器、一个A/D转换器和一个三态输出锁存器组成。多路开关可选通8个模拟通道,允许8路模拟量分时输入,共用 A/D转换器进行转换。三态输出锁器用于锁存 A/D 转换完的数字量,当OE端为高电平时,才可以从三态输出锁存器取走转换完的数据

引脚结构

  • D7-D0:8位数字量输出引脚
  • IN0-IN7:8位模拟量输入引脚
  • VCC:+5V工作电压
  • GND:地
  • REF(+):参考电压正端
  • REF(-):参考电压负端
  • ST:A/D转换启动信号输入端
  • ALE:地址锁存允许信号输入端
  • EOC:转换结束信号输出引脚,开始转换时为低电平,当转换结束时为高电平
  • OE:输出允许控制端,用以打开三态数据输出锁存器
  • CLK:时钟信号输入端(一般为500KHz)
  • A、B、C:地址输入线

说明
ST (转换启动信号)

  • 上跳沿:所有内部寄存器清零
  • 下跳沿开始进行A/D转换
  • 转换期间:ST应保持低电平

EOC (转换结束信号)

  • 高电平:表明转换结束
  • 低电平:正在进行A/D转换

OE (输出允许信号)

  • 为1:输出转换得到的数据
  • 为0:输出数据线呈高阻状态

CLK

  • 因ADC0809的内部没有时钟电路,所需时钟信号必须由外界提供,通常使用频率为500KHZ

引脚端口

ADC0809模数转换与显示
说明
ADC0809对输入模拟量要求:信号单极性,电压范围是0-5V,若信号太小,必须进行放大;输入的模拟量在转换过程中应该保持不变,如若模拟量变化太快,则需在输入前增加采样保持电路
ALE 为地址锁存允许输入线,高电平有效。当 ALE 线为高电平时,地址锁存与译码器将A,B,C三条地址线的地址信号进行锁存,经译码后被选中的通道的模拟量进入转换器进行转换。A,B和C为地址输入线,用于选通 IN0-IN7 上的一路模拟量输入
通道选择表如下所示:
ADC0809模数转换与显示

应用说明

  • ADC0809内部带有输出锁存器,可以与AT89S51单片机直接相连
  • 初始化时,使ST和OE信号全为低电平
  • 送要转换的哪一通道的地址到A,B,C端口上
  • 在ST端给出一个至少有100ns宽的正脉冲信号
  • 是否转换完毕,根据 EOC 信号来判断
  • EOC 变为高电平时,这时给 OE高电平,转换的数据就输出给单片机了

代码编写

引用库文件

#include<reg51.h>
#include<stdio.h>
#include<stdlib.h>
#include<intrins.h>
#include<string.h>

全局变量定义

//地址锁存
sbit ADDC=P1^6;
sbit ADDB=P1^5;
sbit ADDA=P1^4;

sbit CLK=P1^3; //clock
sbit ST=P1^2; //start (转换启动信号)
sbit EOC=P1^1; //end of conversion (转换结束信号)
sbit OE=P1^0; //output enable (输出允许信号)

//0~9
unsigned char code SEG7[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};

延时函数

/*
* 延时
*  
* @param x 时间(不精确)
* @return
*/
void delay_ms(int i)
{
	int j=0;
	while(i--)
	{
		for(j=0;j<120;j++);
	}
}

显示

/*
* 显示
* 
* @param ADx AD转换过后的八位数值
* @return
*/
void display(unsigned char ADx)
{
	int AD = ADx*500.0/255.0;
	P2=0xFD; P0=SEG7[AD/100]; delay_ms(5);//1111_1101 -> P2^1 
	P2=0xFB; P0=SEG7[(AD/10)%10]; delay_ms(5);//1111_1011 -> P2^2
	P2=0xF7; P0=SEG7[AD%10]; delay_ms(5);//1111_0111 -> P2^3
}
说明

由下图所示,led的2、3、4号引脚是与端口P2.1、 P2.2、P2.3一一连接,然后高电平表示选中,选中时,将P0八个引脚的数据送入 led中显示;而 led的1、2、3、4从左到右一一对应上面的八段数码管
ADC0809模数转换与显示

初始化

/*
* 初始化
*
* @return
*/
void init()
{
	// ABC=110选择第三通道
	ADDC=0;
	ADDB=1;
	ADDA=1;
	
	CLK=0;
	ST=1; //内部寄存器清零
	EOC=1; // 转换结束(未开始)
	OE=0; 
}
说明

由下图所示,我们选择通道3作为输入
ADC0809模数转换与显示

中断

/*
* 中断
*
* @return
*/
void t0() interrupt 1
{
	CLK=!CLK;
}

主函数

void main()
{
	init();
	
	//TMOD(定时器)
	TMOD=0x02; //0000_0010 8位 0~255
	/*
	 对定时器T0来说是分成两个寄存器:TH0为高八位,TL0为低八位,组成了16位的定时器,
	 当低位TL0计满就向高位TH0移一个数,然后清零
	 TH0和TL0决定采样频率(数值越大,频率越高)
	*/
	TH0=200; 
	TL0=200; 
	EA=1; // 总中断开关
	ET0=1; // T0定时器总中断开关
	TR0=1; // 启动T0的开定时器位
	
	while(1)
	{
		//产生启动转换的正脉冲信号
		ST=0;_nop_();ST=1;_nop_();ST=0;
		while(EOC==0); //正在转换
		OE=1;
		display(P3); //显示
		OE=0;
	}
	
}
说明

ADC0809转换完毕后,数据存放在 P3 中,所以显示就是以 P3 作为参数
ADC0809模数转换与显示