基于STM32LXXX的模数转换芯片ADC(ADS1110A0IDBVR)驱动C程序设计

一、简介:

ADS1110 是德州仪器(TI)生产的16位精密集成的Δ-Σ模数转换器,采用超小型的SOT-23-6封装,特别适合空间受限且需要高分辨率测量的STM32LXXX低功耗物联网节点或便携设备。

二、主要技术特性:

  • 分辨率:16位,无失码

  • 采样率:可编程(15SPS,30SPS,60SPS,240SPS)

  • 输入通道:1个差分输入(可配置为单端)

  • 内部基准:2.048V ±0.05%,温漂5ppm/°C

  • 可编程增益(PGA):增益最高8倍

  • 接口 :兼容I²C,器件地址由型号后缀(A0)固定为 1001 000(即0x48)

  • 电源:2.7V - 5.5V,适合与STM32LXXX共用3.3V供电

  • 功耗:连续转换模式240μA;单次转换模式具有自动断电功能,闲置电流极低

三、主要应用:

工业过程控制、智能变送器、便携仪器、高精度温度测量(可直接连接热电偶或RTD)。

四、内部原理框图:

五、典型应用:

六、引脚定义:

ADS1110引脚 功能 连接至STM32LXXX 备注
VDD 电源 3.3V 需并联0.1μF陶瓷电容紧靠芯片放置
GND GND
SCL I²C时钟 PB6 (I2C1_SCL) 或任意开漏GPIO 必须外接上拉电阻(4.7kΩ)
SDA I²C数据 PB7 (I2C1_SDA) 或任意开漏GPIO 必须外接上拉电阻(4.7kΩ)
VIN+ 差分正输入 模拟信号源 对地电压范围:GND-0.2V 至 VDD+0.2V
VIN- 差分负输入 模拟信号源/AGND 单端模式接模拟地

七、头文件:

#ifndef __ADS1110_H

#define __ADS1110_H

#include "stm32l0xx_hal.h"

/* ADS1110 设备地址 (A0后缀固定为0x48) */

#define ADS1110_ADDRESS 0x48 // 7位地址,左移1位后为0x90(写)/0x91(读)

/* 配置寄存器位定义 (ADS1110只有一个8位配置寄存器) */

#define ADS1110_REG_CONFIG 0x00 // 唯一可写的寄存器(实际发送命令时无需指定地址,直接写1字节)

typedef enum {

ADS1110_DR_240SPS = 0x00, // 240 SPS (默认)

ADS1110_DR_60SPS = 0x01, // 60 SPS

ADS1110_DR_30SPS = 0x02, // 30 SPS

ADS1110_DR_15SPS = 0x03, // 15 SPS

} ADS1110_DataRate_t;

typedef enum {

ADS1110_PGA_1 = 0x00, // 增益 1 (FSR = ±2.048V)

ADS1110_PGA_2 = 0x04, // 增益 2 (FSR = ±1.024V)

ADS1110_PGA_4 = 0x08, // 增益 4 (FSR = ±0.512V)

ADS1110_PGA_8 = 0x0C, // 增益 8 (FSR = ±0.256V)

} ADS1110_PGA_t;

typedef enum {

ADS1110_MODE_CONTINUOUS = 0x00, // 连续转换模式

ADS1110_MODE_SINGLE = 0x10, // 单次转换模式(自动断电)

} ADS1110_Mode_t;

/* 读出的原始数据包:2字节ADC数据 + 1字节配置寄存器 */

typedef struct {

uint16_t adc_raw; // 16位转换结果(二进制补码格式)

uint8_t config_reg; // 当前的配置寄存器值

uint8_t dr : 2; // 解析出的数据速率

uint8_t pga : 2; // 解析出的增益

uint8_t mode : 1; // 解析出的模式

uint8_t reserved : 3;

} ADS1110_Data_t;

/* 公有函数声明 */

HAL_StatusTypeDef ADS1110_WriteConfig(I2C_HandleTypeDef *hi2c, uint8_t config);

HAL_StatusTypeDef ADS1110_ReadData(I2C_HandleTypeDef *hi2c, ADS1110_Data_t *adc_data);

HAL_StatusTypeDef ADS1110_SetMode(I2C_HandleTypeDef *hi2c, ADS1110_Mode_t mode);

HAL_StatusTypeDef ADS1110_SetDataRate(I2C_HandleTypeDef *hi2c, ADS1110_DataRate_t dr);

HAL_StatusTypeDef ADS1110_SetPGA(I2C_HandleTypeDef *hi2c, ADS1110_PGA_t pga);

float ADS1110_ConvertToVoltage(uint16_t adc_raw, ADS1110_PGA_t pga);

#endif

八、源文件:

#include "ads1110.h"

/**

* @brief 写配置寄存器(ADS1110唯一可写寄存器)

* @param hi2c: I2C句柄

* @param config: 8位配置值(ST/DR[1:0]/ PGA[1:0]/ MODE / 保留位)

* @retval HAL状态

*/

HAL_StatusTypeDef ADS1110_WriteConfig(I2C_HandleTypeDef *hi2c, uint8_t config)

{

// ADS1110无需子地址,直接发送设备地址+待写入的配置字节

return HAL_I2C_Master_Transmit(hi2c, ADS1110_ADDRESS << 1, &config, 1, HAL_MAX_DELAY);

}

/**

* @brief 读取ADC转换结果及当前配置寄存器状态

* @param hi2c: I2C句柄

* @param adc_data: 存储读取数据的结构体指针

* @retval HAL状态

* @note ADS1110连续读取3字节:MSB, LSB, Config

*/

HAL_StatusTypeDef ADS1110_ReadData(I2C_HandleTypeDef *hi2c, ADS1110_Data_t *adc_data)

{

uint8_t rx_buffer[3];

HAL_StatusTypeDef ret;

ret = HAL_I2C_Master_Receive(hi2c, ADS1110_ADDRESS << 1, rx_buffer, 3, HAL_MAX_DELAY);

if (ret == HAL_OK) {

// 组合16位ADC数据(二进制补码)

adc_data->adc_raw = (rx_buffer[0] << 8) | rx_buffer[1];

adc_data->config_reg = rx_buffer[2];

// 解析配置寄存器

adc_data->dr = (rx_buffer[2] >> 0) & 0x03; // bit0-1

adc_data->pga = (rx_buffer[2] >> 2) & 0x03; // bit2-3

adc_data->mode = (rx_buffer[2] >> 4) & 0x01; // bit4

}

return ret;

}

/**

* @brief 设置转换模式(连续/单次)

*/

HAL_StatusTypeDef ADS1110_SetMode(I2C_HandleTypeDef *hi2c, ADS1110_Mode_t mode)

{

uint8_t config;

ADS1110_Data_t current_status;

// 为保持PGA/DR设置不变,先读出当前配置

if (ADS1110_ReadData(hi2c, &current_status) != HAL_OK) {

return HAL_ERROR;

}

config = current_status.config_reg;

// 清除模式位并设置新值

config &= ~0x10;

config |= mode;

return ADS1110_WriteConfig(hi2c, config);

}

/**

* @brief 设置数据速率

*/

HAL_StatusTypeDef ADS1110_SetDataRate(I2C_HandleTypeDef *hi2c, ADS1110_DataRate_t dr)

{

uint8_t config;

ADS1110_Data_t current_status;

if (ADS1110_ReadData(hi2c, &current_status) != HAL_OK) {

return HAL_ERROR;

}

config = current_status.config_reg;

config &= ~0x03; // 清零DR位

config |= dr;

return ADS1110_WriteConfig(hi2c, config);

}

/**

* @brief 设置PGA增益

*/

HAL_StatusTypeDef ADS1110_SetPGA(I2C_HandleTypeDef *hi2c, ADS1110_PGA_t pga)

{

uint8_t config;

ADS1110_Data_t current_status;

if (ADS1110_ReadData(hi2c, &current_status) != HAL_OK) {

return HAL_ERROR;

}

config = current_status.config_reg;

config &= ~0x0C; // 清零PGA位

config |= pga;

return ADS1110_WriteConfig(hi2c, config);

}

/**

* @brief 将原始ADC值转换为电压(单位:伏特)

* @param adc_raw: 16位原始数据(二进制补码)

* @param pga: 当前使用的增益

* @retval 输入电压值(V)

* @note 内部基准为2.048V,满量程差分输入范围 = ±2.048 / PGA

* 代码范围 -32768 对应 -FS,+32767 对应 +FS

*/

float ADS1110_ConvertToVoltage(uint16_t adc_raw, ADS1110_PGA_t pga)

{

int16_t signed_code = (int16_t)adc_raw; // 转换为有符号数

float vref = 2.048f;

float gain;

switch (pga) {

case ADS1110_PGA_1: gain = 1.0f; break;

case ADS1110_PGA_2: gain = 2.0f; break;

case ADS1110_PGA_4: gain = 4.0f; break;

case ADS1110_PGA_8: gain = 8.0f; break;

default: gain = 1.0f; break;

}

// V_in = (signed_code / 32768.0) * (Vref / gain)

return (signed_code / 32768.0f) * (vref / gain);

}

九、应用示例:

#include "main.h"

#include "ads1110.h"

extern I2C_HandleTypeDef hi2c1;

void ADS1110_Example(void)

{

ADS1110_Data_t adc_data;

float voltage;

// 初始化ADS1110:配置为单次转换模式,15SPS,增益=1

ADS1110_SetMode(&hi2c1, ADS1110_MODE_SINGLE);

ADS1110_SetDataRate(&hi2c1, ADS1110_DR_15SPS);

ADS1110_SetPGA(&hi2c1, ADS1110_PGA_1);

while (1)

{

//触发单次转换:写入任意配置值(保持原有配置不变,仅ST位置1)

uint8_t trigger_cmd;

ADS1110_ReadData(&hi2c1, &adc_data); // 读取当前配置

trigger_cmd = adc_data.config_reg | 0x80; // 设置最高位ST = 1

ADS1110_WriteConfig(&hi2c1, trigger_cmd);

// 等待转换完成(根据数据速率等待适当时间,15SPS约需70ms)

HAL_Delay(70);

//读取转换结果

if (ADS1110_ReadData(&hi2c1, &adc_data) == HAL_OK) {

// 计算实际电压值

voltage = ADS1110_ConvertToVoltage(adc_data.adc_raw, ADS1110_PGA_1);

printf("ADC Raw: 0x%04X, Voltage: %.3f V\r\n", adc_data.adc_raw, voltage);

}

HAL_Delay(1000); // 每秒采集一次

}

}

相关推荐
道法自然|~2 小时前
BugCTF列移位密码(原理+C语言实现)
c语言·开发语言
广药门徒2 小时前
PADS Layout里的条件筛选在Router里在哪找
嵌入式硬件
風清掦2 小时前
【江科大STM32学习笔记-06】TIM 定时器 - 6.1 定时器的基本定时功能
笔记·stm32·学习
IvanCodes2 小时前
十、C语言文件与标准 I/O
c语言·开发语言
玩转单片机与嵌入式2 小时前
TinyML适合在哪些MCU上运行?怎么评估我们的MCU能不能运行TinyML?(赠评估手册)
单片机·嵌入式硬件
JiL 奥2 小时前
AWS之Gitlab增量架构(c/c++项目)
c语言·gitlab·aws
亿道电子Emdoor11 小时前
【Arm】Keil MDK 的Symbols窗口
stm32·单片机·嵌入式硬件
myron668812 小时前
基于STM32LXXX的模数转换芯片ADC(MCP3421A0T-E/CH)驱动C程序设计
c语言·stm32·嵌入式硬件
广药门徒12 小时前
PADS布局时放置同网络部件或过孔的节约空间技巧
嵌入式硬件