跳转到内容

ADS1110A0 开发使用

ADS1110A0 是一颗精密、连续自校准的 16 位模数转换器(ADC),带有差分输入和 I2C 接口。它内置了极低漂移的 2.048V 电压基准和可编程增益放大器(PGA),适合高精度的电压测量。

官方数据手册 https://www.ti.com/cn/lit/ds/symlink/ads1110.pdf

I2C 地址

地址为 0x48(对应后缀型号 ADS1110A0,芯片丝印为 ED0)。该芯片的 I2C 地址在出厂时固定

cpp
static const uint8_t ADS1110A0_ADDR = 0x48;

寄存器概览与数据格式

ADS1110A0 的操作非常简单,内部没有多重寄存器地址指针。通过 I2C 读写可直接访问数据和配置:

  • 读操作:连续读取 3 个字节,分别为 数据高字节数据低字节配置寄存器字节
  • 写操作:发送 1 个字节,直接写入 配置寄存器

量化数据格式为 16-bit 有符号整数,范围为 -32768 到 +32767。

  • 电压(V)V = (raw_data / resolution_max) * (2.048 / PGA)
  • 2.048:为内置基准电压。
  • raw_data:为读出的有符号整数。
  • PGA:为配置的增益倍数,默认 1
  • resolution_max:为当前数据速率(DR)对应的满量程值,默认 32768.0

配置(Configuration 寄存器)

配置寄存器为 8-bit,上电默认值为 0x8C(即 0b10001100):

  • Bit 7 (ST/DRDY):状态/数据就绪位。单次转换模式下,写 1 开始转换;读 0 表示转换完成,读 1 表示未完成。
  • Bit 6..5:保留位,始终为 0。
  • Bit 4 (SC):转换模式。0 = 连续转换(默认),1 = 单次转换。
  • Bit 3..2 (DR):数据速率与分辨率。
DR 设定数据速率 (SPS)分辨率满量程值 (resolution_max)
0024012-bit2048.0
016014-bit8192.0
103015-bit16384.0
111516-bit32768.0 (默认)
  • Bit 1..0 (PGA):可编程增益放大器。
PGA 设定增益倍数测量范围
001±2.048V (默认)
012±1.024V
104±0.512V
118±0.256V

典型配置思路:

  • 想要更高的分辨率和稳定性:选择 15 SPS(DR=11
  • 想要更快的刷新率:选择 240 SPS(DR=00
  • 测量更微小的电压:提高 PGA 增益倍数

写入配置(操作方法)

ADS1110 的写操作非常直接:只需向该设备的 I2C 地址发送 1 个字节 即可。芯片会自动将接收到的这个字节覆盖到 Configuration 寄存器。

写入操作函数示例:

cpp
// 发送配置参数到 ADS1110
void setADS1110Config(uint8_t sc, uint8_t dr, uint8_t pga) {
  // sc  (转换模式)   : 0 = 连续转换, 1 = 单次转换
  // dr  (数据速率)   : 0 = 240SPS, 1 = 60SPS, 2 = 30SPS, 3 = 15SPS
  // pga (可编程增益) : 0 = 1x, 1 = 2x, 2 = 4x, 3 = 8x
  
  uint8_t config = 0;
  config |= (1 << 7);                 // Bit 7: ST/DRDY = 1
  config |= ((sc & 0b1) << 4);       // Bit 4: SC
  config |= ((dr & 0b11) << 2);       // Bit 3..2: DR
  config |= (pga & 0b11);             // Bit 1..0: PGA

  Wire.beginTransmission(ADS1110A0_ADDR);
  Wire.write(config);
  Wire.endTransmission();
}

读取电压

读取流程(连续转换模式下):

  1. 直接向设备的 I2C 地址发起读请求,读取 3 个字节(高字节、低字节、配置寄存器)。
  2. 将前两个字节组合成 int16_t 类型的有符号整数。
  3. 按照公式换算成实际电压值。

Arduino 示例

下面示例展示:

  • 初始化 I2C
  • 使用自定义函数写入配置寄存器(设置连续转换,15 SPS,PGA=1)
  • 循环读取电压并打印到串口
cpp
#include <Wire.h>

void setup() {
  Serial.begin(115200);

  Wire.begin();
  // ADS1110 支持高达 3.4MHz 的 I2C,这里使用标准的 400kHz
  Wire.setClock(400000);

  // 配置 ADS1110:
  // 连续转换模式(0),15 SPS(3),PGA = 1x(0)
  setADS1110Config(0, 3, 0);
}

void loop() {
  // ADS1110 读取时固定返回 3 个字节:高字节、低字节、配置寄存器
  Wire.requestFrom(ADS1110A0_ADDR, (uint8_t)3);
  
  if (Wire.available() >= 3) {
    uint8_t msb = Wire.read();
    uint8_t lsb = Wire.read();
    uint8_t config = Wire.read(); // 读取第 3 个字节(配置状态)

    // 组合为 16 位有符号整数
    int16_t rawADC = (int16_t)((msb << 8) | lsb);

    // 从读取到的配置字节中提取 PGA 设置并计算倍数 (Bit 1..0)
    uint8_t pga = 1 << (config & 0b11); // 00->1, 01->2, 10->4, 11->8

    // 从读取到的配置字节中提取 DR 设置 (Bit 3..2)
    uint8_t dr_bits = (config >> 2) & 0b11;
    float resolution_max = 32768.0f; // 默认 DR=3 (16-bit)
    if (dr_bits == 0) resolution_max = 2048.0f;       // 12-bit
    else if (dr_bits == 1) resolution_max = 8192.0f;  // 14-bit
    else if (dr_bits == 2) resolution_max = 16384.0f; // 15-bit

    // 换算电压
    float voltageV = (rawADC / resolution_max) * (2.048f / pga);

    // 根据分压电阻计算实际电压
    float R1 = 120000.0;
    float R2 = 10000.0;  // (连接跳线后R2为5000)
    // 实际电压为
    voltageV = voltageV * (R1 / (R1 + R2));

    Serial.print("Raw: ");
    Serial.print(rawADC);
    Serial.print("\tVoltage: ");
    Serial.print(voltageV, 3);
    Serial.println(" V");
  }

  delay(200);
}

常见问题排查

  • 读不到设备:使用 I2C 扫描工具确认地址。
  • 读数始终为满量程(如 32767 或 -32768):输入电压超出了当前 PGA 设置的测量范围(例如 PGA=1 时输入超过了 2.048V),或者输入引脚悬空。请确认输入电压在允许范围内。
  • 读数抖动或噪声大
    • 检查数据速率(DR)设置,降低速率(如 15 SPS)可以获得最高的 16 位分辨率并显著降低噪声。
    • 检查硬件接线,确保信号源与测量模块良好共地(GND 相连)。