ADC0809工作原理: ADDA/ADDB/ADDC 输入3位地址,并使ALE=1,将地址存入地址锁存器中 ALE:地址锁存允许信号接入端,高电平时允许改变CBA的值,低电平时锁死,防止在A/D转换过程中切换通道 地址经译码选通8路模拟输入IN0~IN7之一到比较器,输入与被选通道关系 · START端上升沿将逐次逼近寄存器复位,下降沿启动A/D转换 · EOC输出信号变低电平,表示正在转换;当A/D转换完成,EOC变为高电平,结果数据已存入锁存器。 · · OE输入高电平,输出三态门打开,转换结果的数字量输出到数据总线上。 · · OE=1时,D0-D7引脚上为转换后的数据,当OE=0时,D0-D7为对外呈现高阻状态 其他引脚: file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps1AD1.tmp.jpg IN0~IN7:8路模拟量输入引脚 CLK:时钟信号输入端 V_(REF(+)):参考电压正端 V_(REF(-)):参考电压负端
实现思路: A/D转换 初始化时启动A/D转换,转换结束后OE自动置位 检查OE状态,为高电平时读取数据口数据并转换成对应的电压值 显示结束后启动下一次A/D转换数码管显示读入数据并转换成电压值后,通过数码管显示,百位数值后显示小数点。 程序如下: - #include <reg52.h>
- typedef unsigned char uchar;
- typedef unsigned int uint;
- typedef unsigned long ulong;
- uchar code table[] =
- {
- 0xfc, 0x60, 0xda, 0xf2,
- 0x66, 0xb6, 0xbe, 0xe0,
- 0xfe, 0xf6, 0xee, 0x3e,
- 0x9c, 0x7a, 0x9e, 0x8e 8 };
- sbit start = P3 ^ 0; //控制start引脚
- sbit eoc = P3 ^ 1; //查询eoc引脚情况
- sbit oe = P3 ^ 2; //输出允许控制端
- sbit dot = P1 ^ 0; //数码管小数点
- void Delay(uint m) {
- while(m--);
- }
- //主函数
- void main() {
- ulong temp, temp_data;
- // uint temp;
- start = 0;
- oe = 0; //oe为高阻状态
- start = 1; //start下降沿开始转换
- start = 0;
- while(1)
- {
- if (eoc == 1) //当eoc为1时转换结束
- {
- /*读入状态*/
- oe = 1; //打开oe,数据读入引脚
- temp = P0;
- /*读入的数值转换成模拟电压对应的电压值,由于ADC0809将0-5V平分为255份,每一份为5/255v,
- 电压=1.0v时,temp=1.0*(5/255),为了方便显示小数,则扩大一百倍,得到公式temp=temp*1.0/255*500
- 但是在此处存在个问题,temp转换成为flout类型后运算量过大,影响后数码管显示速度,在一定范围内数码管显示错误 temp = temp * 1.0 / 255 * 500; → temp = temp * 500 / 255;
- p.s. 修改后的temp要改成unsigned long, FF*500溢出int范围
- */
- temp = temp * 500 / 255;
- oe = 0; //oe呈高阻
- /*数码管显示*/
- temp_data = temp % 10;
- P2 = 0xfe; //数码管选择最后一位
- P1 = table[temp_data];
- Delay(500);
- temp_data = temp / 10 % 10;
- P2 = 0xfd; //数码管选择十位
- P1 = table[temp_data];
- Delay(500);
- temp_data = temp / 100 % 10;
- P2 = 0xfb; //数码管选择百位
- P1 = table[temp_data];
- dot = 1; //显示小数点
- Delay(500);
- /*启动下一次转换*/
- start = 1;
- start = 0;
- }
- }
- }
复制代码
完整的Word格式文档51黑下载地址:
51单片机AD转换器实现数字电压表实例.docx
(238.71 KB, 下载次数: 102)
|