┊ 网站导航 ┊ 管理登陆 ┊ 免责声明 ┊ 问题反馈 ┊ 友链说明┊本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正! 不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作! ![]() ![]() ![]() ![]() ![]() ![]() 本站学习交流群:138..158(高级群1-满)、77930286(高级群2)、61804809(群3) Copyright© MCUSY All Rights Reserved 本站网警备案号: WZ36040002485 ICP备案证书号:粤ICP备09034963号 |
初次接确ADC0804 A/D转换器的朋友,知道ADC0804在输入0~5V电压时显示在0~255,看起来显示数字与相应电压并不成比例,怎么办呢?当然有方法去实现了,此文章包含电路和程序给大家参考,希望能给你帮助,也希望您批评指正!下图就是笔者实验的拍照图。
在此之前,我们还是非常有必要先了解一下ADC0804的一些特性和功能。
一、关于ADC0804
ADC0804是8 BIT A/D转换集成电路,采用了逐次逼近的转换方法,在振动频率F为640KHZ时,取样时间仅为100US,转换出来的数字量是以8位二进制数码在DB0~DB7接脚输出的,那么我们需要用单片机调整为十进制来用于数码管或LCD显示,这样实际上我们就可以做成一个数字式电压表或温度表等。
● 特性:
8位元CMOS逐次逼近型ADC。
三态门锁输出。
最大误差:1LSB。
內部具有时钟产生电路,频率由外加之R、C決定 ( T=1.1RC)。
转换时间:100uS@640KHz。
功耗:875 mW
●ADC0804管脚說明
⊕ VCC (20):电源管脚。
⊕ Vref/2 (9):参考电压管脚。
⊕ V+,V- (6,7):差动模拟电压输入.输入单端正电压时,VIN(-)接地;而差动输入时,直接加入VIN(+) 。VIN(-).
⊕ AGND,DGND (8,10):AGND,DGND;模拟信号以及数字信号的接地。
⊕ DB7~DB0 (11~18):具有三态门锁8 位的数字输出。
⊕ /CS (1):芯片选择脚,低电平有效。
⊕ /RD (2):读取转换结果控制。/RD 为1 时,DB0~DB7 处理高阻抗:/RD 为0 时,数字数据才会输出。
⊕ /WR (3):启动转换控制。相当于ADC 的转换开始(/CS=0 时),当/WR 由1变为0时,转换器被清除:当/WR 回到1 时,转换正式开始。
⊕ CLK (4):时钟脉冲输入脚。內部为斯密特电路,震荡周期T=1.1RC,其中100KHz < f < 1460KHz。
⊕ CLKR (19):CLK之反相输出。
⊕ /INTR (5):中断请求输出脚,低电平动作。
二、ADC0804数据转换表和计算
例:Vin+ = 2V,由上查表可知是高4位+低4位,即1.920+0.080=2V,为01100100=64H ,也可以根据以下式子得出:
关于输入测试和Vref/2脚的解读 三、数字电压表电路图 四、参考C51程序 点击下载>> ADC0804+1602数字电压表.rar
1. 首先提示: ADC0804的Vin+脚最大只能输入5V电压,为FFH(即255)。
2. Vref/2(9脚)-此脚很重要!使用此引脚时,必须加入Vref/2之电压,且不可超过Vref电压的一半。若悬空则内部分压一半自动作为参考电压。
说明:VCC-即电源电压, Vref-外电压的最大值, 这是两个电压概念,虽然都可以是5V,但Vref不能超过VCC)。上面电路中推荐的2.50V是Vref/2参考电压值(ADC0804手册说明不可超过Vref电压最大值的一半),可以由外部电路供给。但如果所加的VCC 电源电压准确且稳定,可以作为参考基准,则ADC0804 芯片内部设置的分压电路,可以自行提供Vref/2,此时Vref/2 端可以不外加电压,浮空即可。
3. 经过多次实践证明,为了使测试的模拟量与转换后显示对应更合理,我们最好用降低基准电压的办法来适应,根据上面提供的公式的计算我们放弃了2.56V。因此我们把公式的参考电压稍微改一下,变成:AD数据 = 满幅数据255*测量电压/(参考电压2.50*2)。
(单片机和ADC0804电路 - 降压和Vref/2的电压值最好要用数字万用表核对一下)
//======================================================
// 程序名称:ADC0804 + 1602数字电压表0.00~50.0V
// 实验对象:XY900_USB型单片机开发系统板
// 单 片 机:AT89S52或STC89C52
// 提 示:本板还有一个外接口,用于外部输入低电压的模拟量实验
// 若测高一点的电压如0~50V请先降压10倍后再输入ADC0804
// 月夜听风:mcusy_cn@126com
//======================================================*/
//------------------------------------------------------------
#include <reg52.h>
#include<absacc.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//------------------------------------------------------------
#define DataPort P0 //LCD接口
#define ReadPort P1 //AD读取
sbit RS = P2^5; //LCD读写控制
sbit RW = P2^6;
sbit EN = P2^7;
sbit cs=P3^2; //芯片选择信号,低电平有效
sbit rd=P3^7; //读数据控制,低电平有效
sbit wr=P3^6; //AD转换起动控制,上升沿有效
//------------------------------------------------------------
uchar code tab0[] = {" Voltage test "}; //第一行'LCD电压表'
uchar code tab1[] = {" = 00.0 V "}; //第二行数据
//====================== 延时程序 ===========================//
void delay(uint ms) // 约1毫秒
{
uint t;
while(ms--)
{ for(t=0;t<112;t++){} }
}
//////////////////// 以下是LCD操作子函数 //////////////////////
//================函数名:LCD检测忙碌信号====================//
void WaitEnable(void)
{
DataPort = 0xff;
RS = 0; RW = 1; _nop_();
EN=1;
_nop_(); _nop_();
while(DataPort&0x80);
EN=0;
}
//------------------- 函数名:写命令到LCD -------------------//
void WriteCommand(uchar Order,uchar Attribc)
{
if(Attribc)WaitEnable();
RS = 0; RW = 0; _nop_();
DataPort=Order; _nop_();
EN = 1;
_nop_(); _nop_();
EN = 0;
}
//------------------- 函数名: LCD写数据 --------------------//
void WriteData(uchar dataW)
{
WaitEnable();
RS = 1; RW = 0; _nop_();
DataPort=dataW; _nop_();
EN = 1;
_nop_(); _nop_();
EN = 0;
}
//----------------- 函数名: LCD初始化 --------------------//
void InitLcd()
{
WriteCommand(0x38,1);
WriteCommand(0x08,1);
WriteCommand(0x01,1);
WriteCommand(0x06,1);
WriteCommand(0x0c,1);
}
//------------ 函数名:显示指定坐标的一个字符 -------------//
void DisplayOne(uchar X,uchar Y,uchar DData)
{
Y&=1;
X&=15;
if(Y)X|= 0x40;
X|= 0x80;
WriteCommand(X,0);
WriteData(DData);
}
//------------- 函数名:显示指定坐标的一串字符 --------------//
void DisplayList(uchar X,uchar Y,uchar code *DData)
{
uchar ListLength=0;
Y&= 0x1;
X&= 0xF;
while(X<=15)
{
DisplayOne(X,Y,DData[ListLength]);
ListLength++;
X++;
}
}
//////////////////// 以下是ADC0804操作子函数 ////////////////
/*************读AD0804 子程序*******************************/
unsigned char adc0804( void )
{
uchar read_ad;
rd = 1; wr = 1; //读ADC
ReadPort = 0xff; //P1置位
cs=0;
wr = 0; wr = 1; //启动ADC
rd=0; //开始读转换后数据
_nop_(); _nop_(); //稍延时,等待读完数
read_ad = ReadPort; //读出的数据赋与ad_data
rd = 1;
cs = 1; //读数完毕
return(read_ad);//返回最后读出的数据
}
//============= 函数名:数据处理及LCD显示函数 ==============//
void display(uint ad_data)
{
uint qian,bai,shi,ge; //定义变量
qian= ad_data/51+0x30; //千位数
bai = ad_data%51*10/51+0x30; //百位数
shi = ad_data%51*10%51*10/51+0x30; //十位数
ge = ad_data%51*10%51*10%51*10/51+0x30; //个位数
//以下为显示位置
DisplayOne(4,1,qian);_nop_(); //百
DisplayOne(5,1,bai);_nop_();
DisplayOne(7,1,shi);_nop_();
//个位显示省略
}
//==================== 函数名:主函数 ========================//
void main(void)
{
char i;
InitLcd(); //LCD初始化
for(i=15;i>=0;i--)
{
DisplayList(i,0,tab0);
DisplayList(i,1,tab1);
delay(60);
}
while(1) display(adc0804()); //调用显示
}
┊ 网站导航 ┊ 管理登陆 ┊ 免责声明 ┊ 问题反馈 ┊ 友链说明┊本站部分内容来自网络共享资源,如有冒犯您的权利请来信告之删除或纠正! 不得对本站进行复制、盗链或镜像,转载内容须获得同意或授权;欢迎友情链接、站务合作! ![]() ![]() ![]() ![]() ![]() ![]() 本站学习交流群:138..158(高级群1-满)、77930286(高级群2)、61804809(群3) Copyright© MCUSY All Rights Reserved 本站网警备案号: WZ36040002485 ICP备案证书号:粤ICP备09034963号 |