微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机模数转换学习笔记

51单片机模数转换学习笔记

时间:10-02 整理:3721RD 点击:

数模转换器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 <reg52.h>          //52系列单片机头文件
#include <intrins.h>        //因为下面的程序用到了_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;                //关闭位选锁存器
   
    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);        
    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单片机c语言教程》,感觉A/D转换挺难的:(

很好很实用

好东西。

不错的笔记

确实很实用的

很有用。

多细,收藏了

嗯 虽然我也是刚踏入电子行业 虽然看不懂 不过还是收藏了 留给自己以后的礼物吧!

不错的笔记

希望做出更多的笔记~
这样也方便自己在学郭天祥老师这本书的时候有所交流

呵呵,你也一样啊,把你的经验发上来分享下吧,共同进步。:P

学习!

挺好的

小编有个问题想请教一下:
for(a=10;a>0;a--)      
         {                                                                                                                                                      
             display(A1,A2,A3);     //兼具显示和延时的作用,因为转换需要经过一定的时间,用这个for循环可以起到延时的作用
此程序段中,display(A1,A2,A3);程序执行此句时,A1,A2,A3的参数值缘何而来?

顶,很不错

谢谢小编分享这个   正需要~~~   

那本书真的写的很好

真的很好

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top