实验七 ADC0804 数字电压表
利用单片机STC89C51与ADC0804设计一个数字电压表,能够测量0-5V之间的直流电压值,四位数码显示,要求采用下面电路图。
时序图:
启动时序图
读取时序图
实现一次ADC转换主要包含下面三个过程:(注:对CS为低后,对CS何时为高电平不要求)
- 启动转换:由时序图中的上部“启动时序图”可知,在/CS信号为低电平的情况下,将引脚/WR先由高电平变成低电平,经过至少tW(WR)I 延时后,再将引脚/WR拉成高电平,即启动了一次AD转换。注:ADC0804使用手册中给出了要正常启动AD转换的低电平保持时间tW(WR)I的最小值为100ns,即拉低后延时大于100ns即可以,具体做法可通过插入NOP指令或者调用delay()延时函数实现,不用太精确,只要估计插入的延时大于100ns即可。
- 延时等待转换结束:依然由时序图中的上部“启动时序图”可知,由拉低信号启动AD采样后,经过1到8个Tclk+INTERNAL Tc延时后,AD转换结束,因此,启动转换后必须加入一个延时以等待AD采样结束。注:手册中给出了内部转换时间“INTERNAL Tc”的时间范围为62~73个始终周期,因此延时等待时间应该至少为8+73=81个时钟周期。比如,若R为10K, C为150pF,则时钟频率为Fclk=1/1.1RC=9.09MHz,因此时钟周期约为Tclk=1/Fclk=1.65us。所以该步骤至少应延时81*Tclk=133.65us. 具体做法可通过插入NOP指令或者调用delay()延时函数实现,不用太精确,只要估计插入的延时大于133.65us即可。
- 读取转换结果:由时序图的下部“读取时序图”可知,采样转换完毕后,在信号/CS为低的前提下,将脚/RD由高电平拉成低电平后,经过tACC的延时即可从DB脚读出有效的采样结果。注:手册中给出了tACC的典型值和最大值分别为135ns和200ns,因此将引脚拉低后,等待大于200ns后即可从DB读出有效的转换结果。具体做法可通过插入NOP指令或者调用delay()延时函数实现,不用太精确,只要估计插入的延时大于200ns即可。
#include<reg51.h>
#include <intrins.h>#define uchar unsigned char
#define uint unsigned intuchar code SegCode[]={0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
uchar code BitCode[] = {0x7f, 0xbf,0xdf,0xef};
unsigned char dispbuf[4];sbit adcs = P2^2;
sbit adrd = P3^7;
sbit adwr = P3^6;sbit dio_en=P3^0;void DelayMs(uint n) {uchar j;while (n--) {for (j = 99; j > 0; j--);}
}void seg_display(uint count) {uchar ge, shi,bai;bai = count/100%10;shi = count/10 %10 ;ge = count %10;P2 = BitCode[1];P1 = SegCode[ge];DelayMs(5);P1 = 0xFF; // xiao yinP2 = BitCode[2];P1 = SegCode[shi];DelayMs(5); P1 = 0xFF;P2 = BitCode[3];P1 = SegCode[bai]&0x7f;DelayMs(5); P1 = 0xFF;P2 = BitCode[0];P1 = SegCode[0];DelayMs(5); P1 = 0xFF;
}uchar AD_Convert(void){
//START CONVERTINGadcs = 0; //芯片有效adwr = 0; //启动ADC0804进行ADC采集_nop_(); //延时片刻 1us >100nsadwr = 1; //高电平变低电平触发一次ADC转换
//WAIT FOR CONVERTINGDelayMs(1); //延时1ms,等待采样转换结束 >133usP0=0xFF; //输入拉高
//read converting resultadrd=0; //将RD脚置低电平后,再延时大于135ns左右(这里延时1us),_nop_(); //即可从DB脚读出有效的采样结果,传送到P0口 1us >200nsreturn (P0);
}void main()
{uint num=0;dio_en=0;while(1){num=2*AD_Convert();seg_display(num);}
}