×
单片机 > 单片机程序设计 > 详情

51单片机ADC0804模数转换学习

发布时间:2020-06-15 发布时间:
|

    数模转换器ADC0804与单片机连接的原理图:

 

这TX-1C实验板上的ADC0804和单片机连接的电路原理图。

左边的是ADC0804,右边的是74HC573锁存器,锁存器同时又连接了单片机没画出。ADC0804的引脚CSAD是片选引脚,因为是低电平有效所以当

送0时,我们就可以选中它工作了。RD也是低电平有效,是读信号的,WR也是低电平有效,当送0时就可以启动A/D开始转换了。INTR是转换结

束引脚,同样也是低电平有效,当INTR为0时,表示转换结束了。DB0-DB7是转换后的数字信号输出端口。AGND和DGND是接地的。CLK R和

CLK IN(即19和4引脚)是用来给ADC0804产生内部时钟脉冲的(接了一个RC震荡电路)6和7端口是模拟信号的输入端,比如我们滑动电位器就

能使模拟信号发生改变,这样经过A/D转换后,输出的数字信号也就改变了。20引脚是接参考电平的。

下面这个程序是用单片机控制ADC0804进行模数转换,当拧动实验板上的电位器(也就是一个滑动变阻器)时,数码管的前三位以十进制方式动态显示A/D转换后的数字量。代码如下:
#include           //52系列单片机头文件
#include         //因为下面的程序用到了_nop_()函数,因此包含这个头文件
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;           //申明U1锁存器的锁存端
sbit wela=P2^7;           //申明U2锁存器的锁存端
sbit adwr=P3^6;           //定义AD的WR(写信号)端口
sbit adrd=P3^7;           //定义AD的RD(读信号)端口
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delayms(uint);        //延时函数声明
void display(uchar,uchar,uchar)   //显示函数声明

/*--------------------------模数转换核心程序--------------------------------*/
void main()         
{

    uchar a,A1,A2,A3,adval;
    wela=1;            //打开位选锁存器,这样就把单片机的P0口与锁存器连通了
    P0=0x7f;           //这里因为片选 接的是P0口的第7位,P0=0x7f即把第七位置0,片选选定,也即是选定ADC0804工作
    wela=0;                //关闭位选锁存器
[page]
    while(1)           //进入死循环不停地做模数转换
    {
        adwr=1;        /*-----------------------------------------*/  
        _nop_();
        adwr=0;              / *启动AD转换(根据时序图来的)*/
        _nop_();
        adwr=1;       /*-----------------------------------------*/  
        
        for(a=10;a>0;a--)      
        {
    display(A1,A2,A3);     //兼具显示和延时的作用,因为转换需要经过一定的时间,用这个for循环可以起到延时的作用
        }
        
        P1=0xff;                    //读取P1口之前先给其写全1
        
        adrd=1;                    //rd置1(根据时序图可知)
        _nop_();                    //延时一个机器周期(根据时序图可知)
        adrd=0;                     //rd置0(根据时序图可知)
        _nop_();                    //延时一个机器周期
        adval=P1;            //A/D转换后的数据赋给adval
        adrd=1;             //转换后的数字信号(二进制的信号应该已经译成了十进制了)读出(也是根据时序图可知)
        
        A1=adval/100;      /*-----------------------------------------*/  
        A2=adval%100/10;    /*分离转换后的十进制数,用来给数码管显示*/
        A3=adval%10;       /*-----------------------------------------*/  

     }
}
/*-------------------------------------------------------------------------------*/

void delayms(uint xms)               
{
    uint i,j;
    for(i=xms;i>0;i--)              //i=xms即延时约xms毫秒
        for(j=110;j>0;j--);
}

void display(uchar bai,uchar shi,uchar ge)  //显示子函数
{
    dula=1;
    P0=table[bai];   
    dula=0;
    P0=0xff;        
    wela=1;            
    P0=0x7e;        
    wela=0;
    delayms(5);        
[page]
    dula=1;
    P0=table[shi];
    dula=0;
    P0=0xff;
    wela=1;
    P0=0x7d;
    wela=0;
    delayms(5);

    dula=1;
    P0=table[ge];
    dula=0;
    P0=0xff;
    wela=1;
    P0=0x7b;
    wela=0;
    delayms(5);
}
程序中所说的时序图如下:

 

从时序图可知首先要选定片选,即置CS=0,程序中一直让cs为0,这样一直选定其工作。对转换没有影响。再看WR的时序图WR先是高-->低-->高,从低-->高这个过程中至少要延时tw(WR)L(ns),程序中用的的_nop()_函数就是延时一个机器周期,本实验板得机器周期为1000ns远大于tw(WR)L(ns)。再看RD

RD的时序是高-->低-->高,RD为低后延时tACC后就有数据了,adval=P1;            //A/D转换后的数据赋给adval
于是再把wR拉高这样就把数据读走了。因为INTR是自动变化的,所以不需要人为设定。。(以上个人理解不知道是否正确^-^)

呵呵,不同的转换器时序图应该也不一样,程序代码也有差别,但本质是一样的。

关键字:51单片机  ADC0804  模数转换 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
MSP430F5529 上手小例程2