锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

模数转换 A/D 与数模转换 D/A介绍

时间:2023-01-17 17:30:00 ad数模转换电位器ad值集成电路2sa1013l6574d013tr集成电路

模数转换 A/D 与数模转换 D/A介绍


A/D 和 D/A 的基本概念

A/D 从模拟量到数字量的转换取决于模数转换器(Analog to Digital Converter),简称ADCD/A 从数字量到模拟量的转换取决于数模转换器(Digital to Analog Converter),简称 DAC。它们的道理完全一样,只是转换方向不同,

A/D 的主要指标

  1. ADC 的位数

一个 n 位的 ADC 表示这个 ADC 共有 2 的 n 第二个刻度 位的 ADC,输出的是从 0~255 一共 256 数字量,也就是 2 的 8 二次数据刻度。

  1. 基准源

基准源,又称基准电压,是 ADC 的一个重要指标,要想把输入 ADC 如果信号测量准确,则基准源应首先准确,基准源的偏差将直接导致转换结果的偏差。例如,米尺的总长度应该是 1 米,假设米尺被火烤了,实际上变成了 1.2 米,再用这根米尺测物体长度的话自然就有了较大的偏差。假设我们的基准源应该是 5.10V,但它实际上是提供的 4.5V,这样误把 4.5V 当成了 5.10V 如果处理,偏差会比较大。

  1. 分辨率

当数字量变化最小刻度时,模拟信号的变化量被定义为满刻度量程和 2n-1 假设 5.10V 使用电压系统 8 位的 ADC 测量相当于 0~255 一共 256 个刻度把 5.10V 平均分成了 255 份,那么分辨率就是 5.10/255 = 0.02V。

  1. INL(积分非线性度)和 DNL(差异非线性度)

初学者最容易混淆的两个概念是分辨率和精度们认为分辨率越高,精度就越高。事实上,两者之间没有必然的联系。分辨率用于描述刻度划分,精度用于描述准确性。同一米尺,刻度相同,分辨率相同,但精度可以大不相同 ADC 精度关系的两个主要指标是 INL(Integral NonLiner)和 DNL(Differencial NonLiner)。INL 指的是 ADC 所有值对应的模拟值和真实值之间最大误差点的误差值是 ADC 最重要的精度指标是单位 LSB。LSB(Least Significant Bit)它意味着最低有效性,所以它实际上对应于 ADC 的分辨率。一个基准为 5.10V 的 8 位 ADC,它的分辨率是 0.02V,用它来测量电压信号,结果是 100意味着它测量的电压值是 100*0.02V=2V,假定它的 INL 是 1LSB,这意味着电压信号的真正准确值是1.98V~2.02V 之间的,根据理想情况对应的数字应该是 测量误差是99~101的最低有效位 1LSB。DNL 表示的是 ADC 相邻两个刻度之间最大的差异,单位也是 LSB。DNL 表示的是 ADC 相邻两个刻度之间最大的差异,单位也是 LSB。分辨率是 1 毫米的尺子,相邻的刻度之间并不都是正确的 1 毫米,总有大大小小的误差。同理,一个 ADC 两个刻度线之间的分辨率并不总是准确的,也有误差。这个误差是 DNL。一个基准为 5.10V 的 8 位 ADC,假定它的 DNL 是 0.5LSB,然后,当其转换结果从 100 增加到 101 理想情况下,实际电压应增加 0.02V,但 DNL 为 0.5LSB 实际电压增加值为 0.01~0.03V 之间。值得一提的是 DNL 不一定小于 1LSB,在很多情况下,它会等于或大于或大于或大于或大于大于大多数时间 1LSB,当实际电压保持不变时,这相当于一定程度的刻度紊乱,ADC 结果可能会在几个值之间跳动,很大程度上是因为这个原因(但并不完全是因为有无处不在的干扰)。

  1. 转换速率

转换率,是指 ADC 每秒采样转换的最大次数是单位 sps(或 s/s、sa/s,即 samples per second),它与 ADC 从模拟到数字转换所需的时间是倒数关系。ADC 有很多种,包括积分型 ADC 转换时间为毫秒,属于低速 ADC;逐次逼近型 ADC转换时间为微秒,属于中速 ADC;并行/串行 ADC 转换时间可达纳秒级,属于高速 ADC。

ADC 大家先熟悉一下这些主要指标,对于其他的,作为入门级选手,
不要急于深入理解。以后在使用过程中遇到,然后找到相关信息深入学习,目前的重点是思考。
中建立一个 ADC 基本概念。

介绍转换芯片

PCF8591 的硬件接口

PCF8591 是单电源低功耗 8 位 CMOS 拥有数据采集装置 4 路模拟输入,1 路模拟输出和串行 I2C 用于与单片机通信的总线接口。与前面讲过的 24C02 类似,3 个地址引脚 A0、A1、A2 最多允许编程硬件地址 8 连接到个器件 I2C 总线不需要额外的片选电路。通过设备的地址、控制和数据 I2C 让我们先看看总线传输。 PCF8591 原理图,如图所示 17-3 所示。

在这里插入图片描述

其中引脚 1、2、3、4 是 4 模拟道路输入,引脚 5、6、7 是 I2C 总线硬件地址,8 脚是数字地 GND,9 脚和 10 脚是 I2C 总线的 SDA 和 SCL。12 脚是引脚的时钟。如果连接高电平,则使用外部时钟输入,如果连接低电平,则使用内部时钟。因此,我们的电路使用内部时钟 12 脚直接接 GND,同时 11 脚悬空。13 脚是模拟地 AGND,在实际开发中,如果有复杂的模拟电路,那么 AGND 部分在布局布线上要特别处理,和 GND 连接的方式有很多,14 脚是基准源,15 脚是 DAC 模拟输出,16 脚是供电电源 VCC。

PCF8591通讯

PCF8591 通信接口是 I2C,那么编程必须符合这个协议。单片机对 PCF8591 初始化,发送三个字节。第一个字节,和 EEPROM 类似地,设备地址字节,其中 7 代表地址,1 位代表读写方向。地址高 4 位固定是 0b1001,低三位是 A2,A1,A0.这三个电路都连接了 GND,因此也就是 0b000,如图 17-5 所示。

  • 写地址为:0x阅读地址为:0x91

发送到 PCF8591 控制寄存器将存储第二个字节 PCF8591 功能 3 位和第 7 位是固定的 0,另外 6 每个人都有自己的角色,如图所示 17-6 所示,

控制字节的第 6 位是 DA 使能位,这一位置 1 表示 DA 输出引脚使能,会产生模拟电压输出功能。第 4 位和第 5 位可以实现把 PCF8591 的 4 路模拟输入配置成单端模式和差分模式,单端模式和差分模式的区别,我们在 17.5 节有介绍,这里大家只需要知道这两位是配置 AD输入方式的控制位即可,如图 17-7 所示。

控制字节的第 2 位是自动增量控制位,自动增量的意思就是,比如我们一共有 4 个通道,
当我们全部使用的时候,读完了通道 0,下一次再读,会自动进入通道 1 进行读取,不需要我们指定下一个通道,由于 A/D 每次读到的数据,都是上一次的转换结果,所以同学们在使用自动增量功能的时候,要特别注意,当前读到的是上一个通道的值。为了保持程序的通用性,我们的代码没有使用这个功能,直接做了一个通用的程序。
控制字节的第 0 位和第 1 位就是通道选择位了,00、01、10、11 代表了从 0 到 3 的一共4 个通道选择。
发送给 PCF8591 的第三个字节 D/A 数据寄存器,表示 D/A 模拟输出的电压值。D/A 模拟我们一会介绍,大家知道这个字节的作用即可。我们如果仅仅使用 A/D 功能的话,就可以不发送第三个字节。

D/A 输出

D/A 是和 A/D 刚好反方向的,一个 8 位的 D/A,从 0~255,代表了 0~2.55V 的话,那么我们用单片机给第三个字节发送 100,D/A 引脚就会输出一个 1V 的电压,发送 200 就输出一个 2V 的电压,很简单,我们用一个简单的程序实现出来,并且通过上、下按键可以增大或减小输出幅度值,每次增加或减小 0.1V。如果有万用表的话,可以直接测试一下板子上
AOUT 点的输出电压,观察它的变化。由于 PCF8591 的 DA 输出偏置误差最大是 50mv(由数据手册提供),所以我们用万用表测到的电压值和理论值之间的误差就应该在 50mV 以内。

示例代码

/* ******************************************************************************* * 《手把手教你学51单片机(C语言版)》 * 配套 KST-51 单片机开发板 示例源代码 * 描 述:第17章 DA转换例程 * 由按键控制DA输出可调电压值 ******************************************************************************* */

#include 

unsigned char T0RH = 0;  //T0重载值的高字节
unsigned char T0RL = 0;  //T0重载值的低字节

void ConfigTimer0(unsigned int ms);
extern void KeyScan();
extern void KeyDriver();
extern void I2CStart();
extern void I2CStop();
extern bit I2CWrite(unsigned char dat);

void main()
{ 
             
    EA = 1;           //开总中断
    ConfigTimer0(1);  //配置T0定时1ms
    
    while (1)
    { 
         
        KeyDriver();  //调用按键驱动
    }
}
/* 设置DAC输出值,val-设定值 */
void SetDACOut(unsigned char val)
{ 
         
    I2CStart();
    if (!I2CWrite(0x48<<1)) //寻址PCF8591,如未应答,则停止操作并返回
    { 
         
        I2CStop();
        return;
    }
    I2CWrite(0x40);         //写入控制字节
    I2CWrite(val);          //写入DA值 
    I2CStop();
}
/* 按键动作函数,根据键码执行相应的操作,keycode-按键键码 */
void KeyAction(unsigned char keycode)
{ 
         
    static unsigned char volt = 0;  //输出电压值,隐含了一位十进制小数位
    
    if (keycode == 0x26)  //向上键,增加0.1V电压值
    { 
         
        if (volt < 25)
        { 
         
            volt++;
            SetDACOut(volt*255/25); //转换为AD输出值
        }
    }
    else if (keycode == 0x28)  //向下键,减小0.1V电压值
    { 
         
        if (volt > 0)
        { 
         
            volt--;
            SetDACOut(volt*255/25); //转换为AD输出值
        }
    }
}
/* 配置并启动T0,ms-T0定时时间 */
void ConfigTimer0(unsigned int ms)
{ 
         
    unsigned long tmp;  //临时变量
    
    tmp = 11059200 / 12;      //定时器计数频率
    tmp = (tmp * ms) / 1000;  //计算所需的计数值
    tmp = 65536 - tmp;        //计算定时器重载值
    tmp = tmp + 28;           //补偿中断响应延时造成的误差
    T0RH = (unsigned char)(tmp>>8);  //定时器重载值拆分为高低字节
    T0RL = (unsigned char)tmp;
    TMOD &= 0xF0;   //清零T0的控制位
    TMOD |= 0x01;   //配置T0为模式1
    TH0 = T0RH;     //加载T0重载值
    TL0 = T0RL;
    ET0 = 1;        //使能T0中断
    TR0 = 1;        //启动T0
}
/* T0中断服务函数,执行按键扫描 */
void InterruptTimer0() interrupt 1
{ 
         
    TH0 = T0RH;  //重新加载重载值
    TL0 = T0RL;
    KeyScan();   //按键扫描
}

  • 示例以及源码来源于:http://www.qdkingst.com/cn/disc51,提供了视频和资料下载,想离线学习的朋友可以去哪里将资源下载到本地进行学习。
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章