
一、ADS1118模块简介
ADS111x是一款精密、低功耗、16位DELTA-SIGMA(∆-Σ)模数转换器(ADC),提供测量采用超小型VSSOP-10封装的传感器最常见信号所需的所有功能。ADS111x集成了可编程增益放大器(PGA)、电压基准、振荡器;其中ADS1115带数字比较器输出;ADS1118带高精度温度传感器。这些功能以及2V至5.5V的宽电源电压范围,使得ADS111x 非常适合功率受限和空间受限的传感器测量应用。
ADS111x数据转换速率最高可达每秒860次采样(SPS)。PGA的 输入范围为士256MV至±6.144V,能够以高分辨率测量大信号和小信号。该器件通过输入多路复用器(MUX)测量双路差分输入或四路单端输入。ADS1118高精度温度传感器用于系统级温度监控或对热电偶进行冷结点补偿。
特性
- 模块供电:2-5.5V
- 通讯接口:SPI串行通讯
- 静态功耗:<1mA(仅供参考)
- 输入通道数:4通道单端或2通道差分,分时采样
- PGA输入范围:±256mV至±6.144V,软件切换量程
- 分辨率:16位
- 最大采样率:860 SPS
- 模块特点:内部集成高精度温度传感器
模块应用
- 温度测量:热电偶测量、冷结点补偿、热敏电阻测量
- 便携式仪表
- 工厂自动化和过程控制
二、模块引脚说明

| CS | CS片选 |
|---|---|
| SCLK | 串行时钟输入 |
| DIN | 串行数据输入 |
| DOUT | 数据输出与数据就绪 |
三、功能框图与读写时序分析

ADS1118 的一次“数据传输周期”有两种常见形式:32-bit 周期(同时写配置并回读配置)和 16-bit 周期(短读,仅读转换结果)。

32-bit 周期:在一个 32 位数据传输周期中,数据由四个字节组成:两个字节用于转换结果,另外两个字节用于读取配置寄存器。设备始终先读取最高有效位 (MSB)。如图 40 所示,在一个传输周期内,将相同的配置寄存器设置写入两次。如果方便,可以在传输周期的前半段写入一次配置寄存器设置,然后在周期的后半段将 DIN 引脚保持低电平(如图 41 所示)或高电平。如果不需要更新配置寄存器,则在整个传输周期内将 DIN 引脚保持低电平或高电平。在 32 位传输周期的前两个字节中写入的配置寄存器设置,将在同一周期的最后两个字节中读取。

16-bit 周期:如果不需要读取配置寄存器数据,ADS1118 转换数据也可以通过一个较短的 16 位数据传输周期输出,如图 42 所示。因此,在第 16 个 SCLK 周期之后,必须将 CS 置高。将 CS 置高会复位 SPI 接口。下次将 CS 置低时,数据传输开始,在第一个 SCLK 上升沿读取当前缓存的转换结果。如果在数据读取开始时 DOUT/DRDY 为低,则转换缓冲区已更新为新结果。否则,如果 DOUT/DRDY 为高,则读取上一个数据传输周期的结果。
四、ADS1118的寄存器说明
ADS1118 有两个可通过 SPI 接口访问的寄存器。转换寄存器存储上次转换的结果。配置寄存器允许用户更改 ADS1118 的工作模式并查询器件状态。
转换寄存器:16 位转换寄存器以二进制补码格式存储上次转换的结果。上电后,转换寄存器被清零,并保持为 0,直到第一次转换完成。

配置寄存器:16 位配置寄存器可用于控制 ADS1118 的工作模式、输入选择、数据速率、满量程范围和温度传感器模式。

| 位 | 名字 | 读写类型 | 初始值 | 描述 |
|---|---|---|---|---|
| 15 | SS | 读/写 | 0h | 单次转换启动:此位用于启动单次转换。SS 只能在断电状态下写入,转换进行时无效。写入时:0 = 无影响;1 = 启动单次转换(断电状态下);始终读取为 0(默认值)。 |
| 14~12 | MUX | 读/写 | 0h | 输入多路复用器配置,这些位用于配置输入多路复用器。![]() |
| 11~9 | PGA | 读/写 | 2h | 可编程增益放大器配置,这些位用于配置可编程增益放大器。![]() |
| 8 | MODE | 读/写 | 1h | 设备工作模式:此位控制 ADS1118 的工作模式。0 = 连续转换模式 1 = 断电和单次转换模式(默认)。 |
| 7~5 | DR | 读/写 | 4h | 数据速率:这些位控制数据速率设置。000 = 8 SPS;001 = 16 SPS;010 = 32 SPS;011 = 64 SPS;100 = 128 SPS(默认);101 = 250 SPS;110 = 475 SPS;111 = 860 SPS |
| 4 | TS_MODE | 读/写 | 0h | 温度传感器模式:此位配置 ADC 以转换温度信号或输入信号。0 = ADC 模式(默认);1 = 温度传感器模式 |
| 3 | PULL_UP_EN | 读/写 | 1h | 上拉使能位:仅当 CS 为高电平时,此位才启用 DOUT/DRDY 引脚上的弱上拉电阻。启用后,一个 400 kΩ 的内部电阻将总线连接到电源。禁用时,DOUT/DRDY 引脚悬空。0 = DOUT/DRDY 引脚上的上拉电阻禁用;1 = DOUT/DRDY 引脚上的上拉电阻启用(默认值)。 |
| 2~1 | NOP | 读/写 | 1h | NOP[1:0] 位控制是否将数据写入配置寄存器。要将数据写入配置寄存器,NOP[1:0] 位必须为“01”。任何其他值都会导致 NOP 命令。在 SCLK 脉冲期间,DIN 可以保持高电平或低电平,而不会将数据写入配置寄存器。01=数据有效,其他为数据无效。 |
| 0 | 保留 | 读 | 1h | 保留位。向此位写入 0 或 1 均无效。始终读取为 1。 |
五、数据输出格式与电压换算
ADS1118 以二进制补码格式提供 16 位数据。正满量程输入产生 7FFFh 的输出码,负满量程输入产生 8000h 的输出码。对于超过满量程的信号,输出将截断至这些码值。表 5 总结了不同输入信号的理想输出码。图 39 显示了码转换与输入电压的关系。

采集数据与电压转换
ADS1118 输出 16-bit 有符号整数,范围 -32768 .. +32767。MSB 为符号位(负数以二补表示),ADC 的物理量程由 PGA/FSR 设置决定(例如 ±6.144V、±2.048V 等),每个 LSB 对应的电压 = FSR / 32768(注意分母是 32768 = 2^15)。
即电压 = 16-bit有符号整数 x LSB,LSB大小由设置的量程决定。量程和比例系数如下:

六、STM32F103驱动ADS1118采集信号
准备工作
STM32F103C8T6最小系统板,ADS1118 ADC模块,OLED显示屏。
引脚接线
| STM32F103C8T6 | ADS1118 |
|---|---|
| PA0 | SCLK |
| PA1 | DIN |
| PA2 | CS |
| PA3 | DOUT |
| PB8 | SCL |
| PB9 | SDA |

代码示例
ads1118.c
#include "stm32f10x.h"
#include "ads1118.h"
#include "delay.h"
void ADS1118_Init(void) //ADS1118初始化
{
uint16_t config = ADS1118_CONFIG_SS_START_OFF | //
ADS1118_CONFIG_MODE_CONTIN | //连续转换模式
ADS1118_CONFIG_DR_128SPS | // 转换 速率 SPS
ADS1118_CONFIG_TS_MODE_ADC | // 读取ADC,而不是温度
ADS1118_CONFIG_PULL_UP_ON | //上拉电阻启用
ADS1118_CONFIG_NOP_VALID | // this is valid data (default)
ADS1118_CONFIG_PGA_6_144V | // FSR is ±6.144 V
ADS1118_CONFIG_MUX_SINGLE_0| //AINP is AIN0 and AINN is GND//单端
ADS1118_CONFIG_RESV; // reserved bits must be set to 1
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能端口时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
CS_H;
MISO_H;
SCLK_L;
MOSI_L;
Write_ADS1118(config,1);//设置ads1118
}
/*******************************************************************************
//函数名称:ADS_SEL_Read()
//函数功能:读取各路电压,通过两个switch选择读取不同的通道
//输 入:road:增益放大器两端的电压选择,并选择测几路电压
// Ref: 选择参考电压,有6种选择
// mode: 是否更新读回数据 0读回 1不读回
//输 出:dat:16位ad转换数据
//备 注:这一次读出的转换数据是上一次的转换数据,不要混淆.这里选择的是单次
转换电压值,当然,也可以选择多次转换,通过寄存器的第8位可以设置
*******************************************************************************/
int16_t ADS_SEL_Read(uint8_t road,uint8_t Ref,uint8_t mode) //测几路电压
{
int dat = 0;
uint16_t config = ADS1118_CONFIG_SS_START_OFF | //
ADS1118_CONFIG_MODE_CONTIN | //连续转换模式
ADS1118_CONFIG_DR_128SPS | // 转换 速率 SPS
ADS1118_CONFIG_TS_MODE_ADC | // 读取ADC,而不是温度
ADS1118_CONFIG_PULL_UP_ON | //上拉电阻启用
ADS1118_CONFIG_NOP_VALID | // this is valid data (default)
ADS1118_CONFIG_RESV; // reserved bits must be set to 1
switch(road) //选择有效转换的路数
{
case 0: config |= ADS1118_CONFIG_MUX_DIFF_0_1;break; //AINP = AIN0 and AINN = AIN1 (default)
case 1: config |= ADS1118_CONFIG_MUX_DIFF_0_3;break; //AINP = AIN0 and AINN = AIN3
case 2: config |= ADS1118_CONFIG_MUX_DIFF_1_3;break; //AINP = AIN1 and AINN = AIN3
case 3: config |= ADS1118_CONFIG_MUX_DIFF_2_3;break; //AINP = AIN2 and AINN = AIN3
case 4: config |= ADS1118_CONFIG_MUX_SINGLE_0;break; //AINP = AIN0 and AINN = GND
case 5: config |= ADS1118_CONFIG_MUX_SINGLE_1;break; //AINP = AIN1 and AINN = GND
case 6: config |= ADS1118_CONFIG_MUX_SINGLE_2;break; //AINP = AIN2 and AINN = GND
case 7: config |= ADS1118_CONFIG_MUX_SINGLE_3;break; //AINP = AIN3 and AINN = GND
default : break;
}
switch(Ref)
{
case 0: config |= ADS1118_CONFIG_PGA_6_144V;break; //000 : FS = ±6.144V(1)
case 1: config |= ADS1118_CONFIG_PGA_4_096V;break; //001 : FS = ±4.096V(1)
case 2: config |= ADS1118_CONFIG_PGA_2_048V;break; //002 : FS = ±2.048V(1)
case 3: config |= ADS1118_CONFIG_PGA_1_024V;break; //003 : FS = ±1.024V(1)
case 4: config |= ADS1118_CONFIG_PGA_0_512V;break; //004 : FS = ±0.512V(1)
case 5: case 6: case 7: config |= ADS1118_CONFIG_PGA_0_256V;break; //005 : FS = ±0.256V(1)
default : break;
}
dat = Write_ADS1118(config,mode);
return dat;
}
/*******************************************************************************
//函数名称:Write_ADS1118()
//函数功能:设置1118寄存器
//输 入:config:寄存器配置
// discardData: 是否更新读回数据 0读回 1不读回
//返 回: 16位ad转换数据
//备 注:
*******************************************************************************/
int16_t Write_ADS1118(uint16_t config,uint8_t discardData)
{
uint8_t i=0;
static int16_t read=0;
CS_L;
if(discardData==0)
{
read=0;
}
delay_us(1);
for(i=0;i<16;i++) // 循环16次
{
if(config & 0x8000)MOSI_H;
else MOSI_L;
config <<= 1;
delay_us(1);
SCLK_H;
delay_us(1);
SCLK_L;
delay_us(1);
if(discardData==0)
{
read<<=1;
if(READ_MISO)read ++;
}else{
delay_us(2);
}
}
CS_H;
delay_us(2);
CS_L;
// SCLK_L;
// MOSI_L;
// MISO_H;
return read;
}
main.c
#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stdlib.h"
#include "oled.h"
#include "ads1118.h"
int main(void)
{
uint8_t i=0;
char showLcd[30];
char infoBackPC[64];
int16_t value[4];
float Volt_Value;
SystemInit();
delay_init(72); //延时初始化
uart_init(9600); //串口初始化
OLED_Init();
delay_ms(100);
ADS1118_Init();//ADS1118初始化
OLED_ShowString(1, 5, "ADS1118");
delay_ms(1000);
OLED_Clear();
while(1)
{
delay_ms(100);
//四单端
if(READ_MISO==0)
{
///循环配置通道并读取
value[i]=ADS_SEL_Read(i+4,0,0); //读取通道
if(i==3) ADS_SEL_Read(4,0,1);//配置下一通道
else ADS_SEL_Read(i+5,0,1); //配置下一通道
i++;
}
if(i==4)
{
i=0;
Volt_Value = value[0]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN0=%f",Volt_Value);
OLED_ShowString(1, 1, showLcd);
Volt_Value = value[1]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN1=%f",Volt_Value);
OLED_ShowString(2, 1, showLcd);
Volt_Value = value[2]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN2=%f",Volt_Value);
OLED_ShowString(3, 1, showLcd);
Volt_Value = value[3]*ADS1118_CONST_6_144V_LSB_mV/1000;
sprintf(showLcd, "AIN3=%f",Volt_Value);
OLED_ShowString(4, 1, showLcd);
// sprintf(infoBackPC, "AIN0=%f\r\nAIN1=%f\r\nAIN2=%f\r\nAIN3=%f\r\n\r\n",value[0]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[1]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[2]*ADS1118_CONST_6_144V_LSB_mV/1000,\
// value[3]*ADS1118_CONST_6_144V_LSB_mV/1000);
// printf("%s",infoBackPC); //串口发送
}
//两差分,采集差分信号时需把ADS1118_Init函数的ADS1118_CONFIG_MUX_SINGLE_0改为ADS1118_CONFIG_MUX_DIFF_0_1
// if(READ_MISO==0)
// {
// ///循环配置通道并读取
// value[i]=ADS_SEL_Read(i,0,0); //读取通道
// if(i==1) ADS_SEL_Read(0,0,1);//配置下一通道
// else ADS_SEL_Read(i+3,0,1); //配置下一通道
// i++;
// }
// if(i==2)
// {
// i=0;
// Volt_Value = value[0]*ADS1118_CONST_6_144V_LSB_mV/1000;
// sprintf(showLcd, "AIN01=%f",Volt_Value);
// OLED_ShowString(1,1,showLcd);
//
// Volt_Value = value[1]*ADS1118_CONST_6_144V_LSB_mV/1000;
// sprintf(showLcd, "AIN23=%f",Volt_Value);
// OLED_ShowString(2,1,showLcd);
//
//// sprintf(infoBackPC, "AIN0=%.6f\r\nAIN1=%.6f\r\n\r\n",value[0]*ADS1118_CONST_6_144V_LSB_mV/1000,value[1]*ADS1118_CONST_6_144V_LSB_mV/1000);
//// printf("%s",infoBackPC); //串口发送
// }
}
}
效果展示
四单端输入:AIN0接GND,AIN1接3.30V,AIN2接1.81V,AIN3接1.20V 。
两差分输入:AIN0接3.30V,AIN1接2.47V,AIN2接1.20V,AIN3接1.81V。
注意:通道悬空不为0。

七、注意事项和常见问题
注意事项
(1)模块为低功耗模块,建议供电电源不超过5.5V。
(2)由于模块是高精度器件,为了避免不必要的干扰,建议使用线性电源供电。
(3)输出信号线建议尽量短,过长容易引入噪声信号。接触不良或劣质的线材可能导致信号衰减或者噪声过大。
(4)如需简单测试模块功能,建议搭配本店控制板使用,正确接线后给控制板供电即可实现信号采集显示。
常见问题
Q:ADS1115和ADS1118有什么区别?
A:ADS1118是SPI通信,内部集成了高精度温度传感器;ADS1115 是IIC通信,带数字比较器输出。
Q:最大可以测量多少电压?
A:最大测量电压为供电电压加0.3V。即理论最大测量电压为5.8V。
Q:比如给一个电压:2.1234V的一个电压让它去一直采集,它的结果是怎样的?数值会跳动吗?
A:数据肯定是有跳动的,这个不是单一条件决定的,电源纹波噪声,线材过长等因素都会对其造成影响。
Q:使用ADS111X和配套的主控板,用USB口供电,无法采集到5V的电压?
A:由于普遍的USB口的电压都是低于5V的,则ADS1118芯片的供电电压就会不足5V,这样就采集不了5V的电压,建议使用DC接口,5V 以上的供电,但是不可超过5.5V,这样就可以采集到5V的电压。
Q:ADS111X采集小电压信号不准,是什么情况?
A:可能是芯片内部(PGA)放大倍率配置过大,可根据自己要采集的信号范围合理设置芯片量程范围(PGA)。
Q:模块正常驱动后,没有接电压的管脚显示也有电压,正常吗?
A:模块默认是4通道一直采集的,在没有接入电压的时候也会采集到管脚上的浮空电压。可将管脚直接接地。即为0电压。

