学习单片机的第19天——A/D转换之模拟电压变化显示实验

例题:用单片机控制ADC0804进行模数转换,当拧动实验板上A/D旁边的电位器Re2时,在数码管的前三位以十进制方式动态显示出A/D转换后的数字量(8位A/D转换后数值在0~255变化)。

#include 
#include 
#define uchar unsigned char
#define uint unsigned int
sbit duan=P2^6;
sbit wei=P2^7;
sbit adwr=P3^6;                     //定义A/D的WR端口
sbit adrd=P3^7;                     //定义A/D的RD端口 
unsigned char code table[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 
                       0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71};\
void delayms(uint xms)
{
  uint i,j;
  for(i=xms;i>0;i--)
     for(j=110;j>0;j--);
}
void display(uchar bai,uchar shi,uchar ge)
{
    duan=1;
    P0=table[bai];                  //送段选数据
    duan=0;
    P0=0xff;                        //消影
    wei=1;
    P0=0x7e;                        //送位选数据
    wei=0;
    delayms(5);
    duan=1;
    P0=table[shi];
    duan=0;
    P0=0xff;
    wei=1;
    P0=0x7d;
    wei=0;
    delayms(5);
    duan=1;
    P0=table[ge];
    duan=0;
    P0=0xff;
    wei=1;
    P0=0x7b;
    wei=0;
    delayms(5);
}
void main()                            //主程序
{
    uchar a,A1,A2,A3,adval;            
    wei=1;
    P0=0x7f;                           //置CSAD为0,选通ADCS,以后不必在管ADCS
    wei=0;
    while(1)
    {
        adwr=1;
        _nop_();
        adwr=0;                        //启动A/D转换
        _nop_();
        adwr=1;
        for(a=10;a>0;a--)              //TX-1C实验板A/D工作频率较低,所以启动转换后要多留点时间
        {
            display(A1,A2,A3);
        }
        P1=0xff;                       //读取P1口之前先给其全写1
        adrd=1;                        //选通ADCS
        _nop_();
        adrd=0;                        //A/D读使能
        _nop_();
        adval=P1;                      //A/D数据读取赋值给P1口
        adrd=1;
        A1=adval/100;                  //分出百、十、个位
        A2=adval%100/10;
        A3=adval%10;
    }
}    

在TX-1C版上,ADC0804旁边有个插针ADIN,只有我们用短路帽插上去,我们的电位器才可以和A/D芯片连接上。设计这个插针的目的是,考虑用户可能会用A/D采集实验板外面的模拟信号,这时候直接与该插针连接就可以

分析程序:

  1. 刚进入主程序后,先将U2锁存器的输出口的最高位置低电平,目的是将与之相连的ADC0804的CS片选端置低选中,也就是将A/D转换器选中。前面讲到过,ADC0804的CS片选端是和U2的Q7输出端,也就是最高输出位相连接。因为本例子专门操作A/D芯片,所以一次选中,以后再不用管它。同时注意,以后凡是操作U2锁存器的地方都不要再改变ADC的CS端,在数码管显示程序中,送出位选信号时,始终保持U2锁存器的最高位为低电平,上面数码管显示部分中“P0=0x7e;P0=0x7d;P0=0x7b”就是表达这个意思。
  2. 在进入while(1)大循环后,先启动A/D转换,其操作方式是按照前面介绍的启动时序图来完成的。其中用到的“_ nop _()”相当于一个及其周期的延时,详解在下面。
  3. 在启动A/D转换后,还未读取转换结果,立刻先送结果给数码管显示,这样写的目的是给A/D转换留有一定时间。我们把数码管显示这部分作为A/D转换的时间,首次显示时,数码管上必然显示的全都是0。我们编码下载程序后,首次上电会看到显示全是0,但马上又出现了了数字因为首次显示完后,接下来便读取到了A/D转换后的结果,当程序再次循环回来时,变现实了上次的数值。这样并不影响我们观察实验现象。
  4. 有些人可能会发现,拧动电位器时,数码管上数字始终不动,只有复位一次,或者重新上电一次,数字才会刷新。这是因为转换时间不够,遇到这种情况时,有两种解决办法。一是将实验板上C11电容换成150pF;二是在适当延长A/D转换的时间,即增加数码管显示的次数,可将上面for(a=10;a>0;a--)中的a变大

我们作为电气的,对于ADC内部到底怎么运作不用太了解,我们只用知道如何去使用便可。前面讲了那么多ADC内部的东西,到头来我们就用了个WR,CS就解决了。

_ nop _()

这个东西,我们知道有这个东西存在就好了,它就是用来延时一个机器周期的,用的时候写一下就好了。

你可能感兴趣的:(89C52笔记,单片机,编程语言)