adc0834工作原理及AD转换

电子常识

2640人已加入

描述

AD0832是8位逐次逼近模数转换器,可支持两个单端输入通道和一个差分输入通道。是8位逐次逼近模数转换器,可支持两个单端输入通道和一个差分输入通道。

当ADC0832未工作时其CS输入端应为高电平,此时芯片禁用,当要进行A/D转换时,

须先将CS使能端置于低电平并且保持低电平直到转换完全结束。此时芯片开始转换工作,同时由处理器向芯片时钟输入端CLK输入时钟脉冲,DO/DI端则使用DI端输入通道功能选择的数据信号。在第1个时钟脉冲的下沉之前DI端必须是高电平,表示启始信号。在第2、3个脉冲下沉之前DI端应输入2位数据用于选择通道功能,

adc0834

当此2位数据为“1”、“0”时,只对CH0进行单通道转换。

当2位数据为“1”、“1”时,只对CH1进行单通道转换。

当2位数据为“0”、“0”时,将CH0作为正输入端IN+,CH1作为负输入端IN-进行输入。

当2位数据为“0”、“1”时,将CH0作为负输入端IN-,CH1作为正输入端IN+进行输入。

在完成输入启动位、通道选择之后,就可以开始读出数据,转换得到的数据会被送出二次,一次高位在前传送,一次低位在前传送,连续送出。在程序读取二个数据后,我们可以加上检验来看看数据是否被正确读取。

由于ADC0832是8位分辨率,返回的数值在0~255之间,对应模拟数值为0~5V,因此每一档对应的电压值约为0.0196V。大家可以在通道输入端引入模拟信号(0~5V)进行测试,比如可以在通道脚和地之间接入电池来测试电池电压值。为使两位数码管显示电压值大小,在写程序是可将对应比值改位0.196,同理,如果想要显示精度更高,可用三位或四位显示,那么响应的改一下比值为1.96或19.6,当然,需要注意你所得数据的大小是否超出数据类型的大小。

时序图

adc0834

基于ADC0834的AD转换

/*----------------------------------------------------------

功能介绍:

-----------------------------------------------------------*/

#include 《reg52.h》 #include 《stdio.h》

#include 《math.h》

#define uchar unsigned char

#define uint unsigned int

#define ucode unsigned code

/*--------------------------------------------

包含函数

---------------------------------------------*/

void DISP(void); //数码管显示函数

void key(void);//矩阵键盘函数

void _nop_(void);

void ad_buf(); //模拟量转化为数字函数

uchar ADC0834(uchar tds); //AD转换函数

/*-------------------------------------------

参数定义

-------------------------------------------*/

uchar bdata ekey1; //键前沿提取

uchar bdata ekey2;

uchar data key2;

uchar data key1;

uchar bdata lastkey1;

uchar bdata lastkey2;

uchar disp_a;//数码管显示指针

sbit cs0=P2^0;

sbit cs1=P2^1;

sbit cs2=P2^2;

sbit cs3=P2^3;

sbit cs4=P2^4;

sbit esw0=ekey2^6; //独立按键键沿标志

sbit esw1=ekey2^7; //

sbit ek0=ekey1^0; //矩阵按键键沿标志

sbit ek1=ekey1^1;

sbit ek2=ekey1^2;

sbit ek3=ekey1^3;

sbit ek4=ekey1^4;

sbit ek5=ekey1^5;

sbit ek6=ekey1^6;

sbit ek7=ekey1^7;

sbit ek8=ekey2^0;

sbit ek9=ekey2^1;

sbit row0=P2^5;

sbit row1=P2^6;

sbit row2=P2^7;

sbit sw0=P1^6;

sbit sw1=P1^7;

sbit do_0834=P1^0;//0834 DI

sbit cs_0834=P1^1; //0834 片选

sbit di_0834=P1^2; //0834 DI

sbit clk_0834=P1^3; // 0834 时钟

sbit dian=P0^7; // 小数点

uchar buf0; // 显示缓冲单元个位

uchar buf1; // 十

uchar buf2; // 百

uchar buf3; //千

uchar buf4;

uchar code led[]={0x0C0,0x0F9,0x0A4,0x0B0,0x99,0x92,0x82,0x0F8,0x80,0x90};

uchar msta=0;

uchar tds;//通道选择

uint adbuf;

bit t1s;//一秒标志位

bit light; //小数点亮标志位

uchar ktime;

/*-------------------------------------------

主函数

-------------------------------------------*/

void main()

{ uchar f1s=0;

uchar i;

TMOD=0x01;

TH0=0xec;

TL0=0x78;

TR0=1;

while(1)

{

while(!TF0); //5ms?

TF0=0;

TH0=0x0ec;

TL0=0x78;

++f1s;

if(f1s==200)

{t1s=1;

f1s=0;}

key();

DISP();

switch(msta)

{ //待机模块 显示“0000”

case 0:if(esw0){msta=1;tds=0xd0;}//SW1按下跳到模块1 选择单端模式 AD一次

if(esw1){msta=1;tds=0x80;}//SW2按下跳到模块1 选择差分模式 AD一次

if(ek0){msta=2;tds=0xd0;}// ek0按下跳到模块2 选择单端模式 十次AD取平均

if(ek1){msta=2;tds=0x80;}//ek1按下跳到 模块2 选择差分模式 十次AD取平均

if(ek2){msta=3;tds=0xd0;}// ek2按下跳到模块3 选择单端模式 一秒AD一次

if(ek3){msta=3;tds=0x80;}// ek3按下跳到模块3 选择差分模式 一秒AD一次

buf4=0,buf3=0,buf2=0,buf1=0;

buf0=0;

break;

case 1:if(esw0){msta=1;tds=0xd0;} //只AD一次

if(esw1){msta=1;tds=0x80;}

light=1;//小数点亮

adbuf=ADC0834(tds);

ad_buf(); break;

case 2:if(ek0){msta=2;tds=0xd0;} //AD十次取平均

if(ek1){msta=2;tds=0x80;}

light=1;

for(i=0;i《10;i++)

{adbuf=adbuf+ADC0834(tds);}

adbuf=adbuf/11;

ad_buf();

break;

case 3:if(ek2){msta=3;tds=0xd0;} //一秒AD一次

if(ek3){msta=3;tds=0x80;}

light=1;

if(t1s)

{t1s=0;

adbuf=ADC0834(tds);

ad_buf();}

break;

default:break;

}

}

}

/*-----------------------------------------------

数码管显示

------------------------------------------------*/

void DISP()

{ P0=0xff;

P2=0xff;

switch(disp_a)

{ case 0: cs0=0; // 点亮第0位数码管

P0=led[buf0];

disp_a=1;

break;

case 1: cs1=0; // 点亮第1位数码管

P0=led[buf1];

disp_a=2;

break;

case 2: cs2=0; // 点亮第2位数码管

P0=led[buf2];

disp_a=3;

break;

case 3: cs3=0; // 点亮第3位数码管

P0=led[buf3];

if(light)

dian=0; //小数点亮

disp_a=4;

break;

case 4: cs4=0; // 点亮流水灯

P0=buf4;

disp_a=0;

break;

default:break;

}

}

/*-------------------------------------------------------

矩阵键盘及独立按键子程序

------------------------------------------------------------*/

void key()

{uchar kbuf;

P2=0x0ff;//关数码管

row0=0; //扫描K0~3

_nop_(); //延时

_nop_();

kbuf=P2;

kbuf=(kbuf&0x0f)^0x0f;

//K0~3键位保留 求反转正逻辑

lastkey1=kbuf; // 新的键状态暂存R6

P2=0x0ff;

row1=0; //扫描K4~7

_nop_();

_nop_();

kbuf=P2;

kbuf=(kbuf&0x0f)^0x0f;

lastkey1=(kbuf《《4)+lastkey1;

P2=0x0ff;

row2=0;//扫描K8~K11

_nop_();

_nop_();

kbuf=P2;

kbuf=(kbuf&0x0f)^0x0f;

lastkey2=kbuf;

P2=0x0ff;

P1=P1|0x0c0;

kbuf=P1;

kbuf=(kbuf&0x0c0)^0x0c0;

lastkey2=kbuf+lastkey2;

if((lastkey2!=key2)||(lastkey1!=key1))//键状态变化则转移

{if(ktime--!=0)

{lastkey1=key1;

lastkey2=key2;}

}

else

ktime=0x04;

ekey1=(key1^lastkey1)&lastkey1;

key1=lastkey1;

ekey2=(key2^lastkey2)&lastkey2;

key2=lastkey2; }

/************************************************************

AD转换

************************************************************/

uchar ADC0834(uchar tds)

{

uchar i,adbuf=0; cs_0834=0; for(i=0;i《5;i++)

{

clk_0834=0;

di_0834=0;

if(tds&0x80)

di_0834=1;

clk_0834=1;

tds《《=1;

}

do_0834=1;

for(i=0;i《8;i++)

{

clk_0834=0;

clk_0834=1;

adbuf=(adbuf《《1)|do_0834;

}

cs_0834=1;

return(adbuf);

}

/*****************************************************************

模拟量转化为数字并送显

******************************************************************/

void ad_buf()

{

buf4=adbuf%51*10%51*10%51*10/51;//

流水灯

buf3=adbuf/51; //个位

buf2=adbuf%51*10/51;//十分位

buf1=adbuf%51*10%51*10/51;//百分位

buf0=adbuf%51*10%51*10%51*10/51;// 千分位

}

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分