ADS1115 封装驱动分享
ADS1115 驱动分享,驱动结构支持多芯片管理与用户自定义接口,适合用于项目中进行精确模拟量采集。如有错误,欢迎私信交流~作者:Jafi。
·
ADS1115驱动源码以及调试分享
芯片简介: ADS1115 是一款由 Texas Instruments (TI) 出品的 16 位高精度模数转换器(ADC),具备 I2C 接口,支持多通道差分/单端输入,内部集成 PGA 可变增益放大器,具备高分辨率、低功耗、支持单次与连续采样等特性。适用于传感器信号采集、电池监控、工业自动化等领域。
本文分享ADS1115 多通道、多芯片支持驱动,采用结构体封装,支持用户自定义 I2C 接口与延迟函数。附带完整源码与调试注意事项,适合项目直接集成使用。
注:
本文示例基于 STM32 HAL + FreeRTOS ,其他平台自行替换
一、功能概述
- 支持多颗 ADS1115 芯片(I2C 地址不同)
- 每颗芯片支持4通道模拟电压读取
- 可配置PGA、采样率、输入通道、支持单次采样模式(低功耗)等
- 抽象 I2C 接口、延迟接口(兼容阻塞/非阻塞环境)
二、源码结构
源码共包含三部分:
ADS1115.h:驱动头文件,包含寄存器定义、结构体定义、宏配置等ADS1115.c:驱动实现,包括初始化、读取电压等核心函数- 示例调用代码:实现3颗芯片并行读取、初始化及调度
三、头文件 ADS1115.h
// 作者:Jafi
#ifndef ADS1115_H
#define ADS1115_H
#include "stdint.h"
// ADS1115 I2C地址定义
#define ADS1115_ADDRESS_GND (0x48 << 1) // 地址引脚接GND
#define ADS1115_ADDRESS_VDD (0x49 << 1) // 地址引脚接VDD
#define ADS1115_ADDRESS_SDA (0x4A << 1) // 地址引脚接SDA
#define ADS1115_ADDRESS_SCL (0x4B << 1) // 地址引脚接VDD
// 配置寄存器地址定义
#define ADS1115_REG_CONVERT 0x00 // 转换寄存器
#define ADS1115_REG_CONFIG 0x01 // 配置寄存器
#define ADS1115_REG_LO_THRESH 0x02 // 低阈值寄存器
#define ADS1115_REG_HI_THRESH 0x03 // 高阈值寄存器
// 配置寄存器位定义
#define ADS1115_CONFIG_OS_SINGLE (0x01 << 15) // 单次转换开始
#define ADS1115_CONFIG_OS_NO_EFFECT (0x00 << 15) // 无效
#define ADS1115_CONFIG_MUX_OFFSET 12 // 多路复用器选择位偏移
#define ADS1115_CONFIG_PGA_OFFSET 9 // PGA设置位偏移
#define ADS1115_CONFIG_MODE_OFFSET 8 // 模式选择位偏移
#define ADS1115_CONFIG_DR_OFFSET 5 // 数据速率选择位偏移
#define ADS1115_CONFIG_COMP_MODE_OFFSET 4 // 比较器模式选择位偏移
#define ADS1115_CONFIG_COMP_POL_OFFSET 3 // 比较器极性选择位偏移
#define ADS1115_CONFIG_COMP_LAT_OFFSET 2 // 比较器锁存行为选择位偏移
#define ADS1115_CONFIG_COMP_QUE_OFFSET 0 // 比较器队列设置位偏移
// 多路复用器配置(单端输入)
#define ADS1115_CONFIG_MUX_SINGLE_0 (0x04 << ADS1115_CONFIG_MUX_OFFSET) // 单端输入A0
#define ADS1115_CONFIG_MUX_SINGLE_1 (0x05 << ADS1115_CONFIG_MUX_OFFSET) // 单端输入A1
#define ADS1115_CONFIG_MUX_SINGLE_2 (0x06 << ADS1115_CONFIG_MUX_OFFSET) // 单端输入A2
#define ADS1115_CONFIG_MUX_SINGLE_3 (0x07 << ADS1115_CONFIG_MUX_OFFSET) // 单端输入A3
// PGA设置(满量程范围)
#define ADS1115_CONFIG_PGA_6_144V (0x00 << ADS1115_CONFIG_PGA_OFFSET) // ±6.144V
#define ADS1115_CONFIG_PGA_4_096V (0x01 << ADS1115_CONFIG_PGA_OFFSET) // ±4.096V
#define ADS1115_CONFIG_PGA_2_048V (0x02 << ADS1115_CONFIG_PGA_OFFSET) // ±2.048V
#define ADS1115_CONFIG_PGA_1_024V (0x03 << ADS1115_CONFIG_PGA_OFFSET) // ±1.024V
#define ADS1115_CONFIG_PGA_0_512V (0x04 << ADS1115_CONFIG_PGA_OFFSET) // ±0.512V
#define ADS1115_CONFIG_PGA_0_256V (0x05 << ADS1115_CONFIG_PGA_OFFSET) // ±0.256V
// 模式选择
#define ADS1115_CONFIG_MODE_CONTIN (0x00 << ADS1115_CONFIG_MODE_OFFSET) // 连续转换模式
#define ADS1115_CONFIG_MODE_SINGLE (0x01 << ADS1115_CONFIG_MODE_OFFSET) // 单次转换模式
// 数据速率设置
#define ADS1115_CONFIG_DR_8SPS (0x00 << ADS1115_CONFIG_DR_OFFSET) // 8 samples per second
#define ADS1115_CONFIG_DR_16SPS (0x01 << ADS1115_CONFIG_DR_OFFSET) // 16 samples per second
#define ADS1115_CONFIG_DR_32SPS (0x02 << ADS1115_CONFIG_DR_OFFSET) // 32 samples per second
#define ADS1115_CONFIG_DR_64SPS (0x03 << ADS1115_CONFIG_DR_OFFSET) // 64 samples per second
#define ADS1115_CONFIG_DR_128SPS (0x04 << ADS1115_CONFIG_DR_OFFSET) // 128 samples per second
#define ADS1115_CONFIG_DR_250SPS (0x05 << ADS1115_CONFIG_DR_OFFSET) // 250 samples per second
#define ADS1115_CONFIG_DR_475SPS (0x06 << ADS1115_CONFIG_DR_OFFSET) // 475 samples per second
#define ADS1115_CONFIG_DR_860SPS (0x07 << ADS1115_CONFIG_DR_OFFSET) // 860 samples per second
// 比较器模式设置
#define ADS1115_CONFIG_COMP_MODE_TRAD (0x00 << ADS1115_CONFIG_COMP_MODE_OFFSET) // 传统比较器
#define ADS1115_CONFIG_COMP_MODE_WINDOW (0x01 << ADS1115_CONFIG_COMP_MODE_OFFSET) // 窗口比较器
// 比较器极性设置
#define ADS1115_CONFIG_COMP_POL_LOW (0x00 << ADS1115_CONFIG_COMP_POL_OFFSET) // 低电平有效
#define ADS1115_CONFIG_COMP_POL_HIGH (0x01 << ADS1115_CONFIG_COMP_POL_OFFSET) // 高电平有效
// 比较器锁存设置
#define ADS1115_CONFIG_COMP_LAT_NONLATCH (0x00 << ADS1115_CONFIG_COMP_LAT_OFFSET) // 非锁存
#define ADS1115_CONFIG_COMP_LAT_LATCH (0x01 << ADS1115_CONFIG_COMP_LAT_OFFSET) // 锁存
// 比较器队列设置
#define ADS1115_CONFIG_COMP_QUE_1CONV (0x00 << ADS1115_CONFIG_COMP_QUE_OFFSET) // 1次转换
#define ADS1115_CONFIG_COMP_QUE_2CONV (0x01 << ADS1115_CONFIG_COMP_QUE_OFFSET) // 2次转换
#define ADS1115_CONFIG_COMP_QUE_4CONV (0x02 << ADS1115_CONFIG_COMP_QUE_OFFSET) // 4次转换
#define ADS1115_CONFIG_COMP_QUE_NONE (0x03 << ADS1115_CONFIG_COMP_QUE_OFFSET) // 禁用比较器
// 芯片接口结构体
typedef struct {
uint8_t chip_id; // 芯片唯一标识符
uint8_t i2c_address; // I2C 地址
uint8_t init_Status;//初始化是否成功
uint16_t config_register_value[4]; // 每个通道的配置寄存器值
int (*I2C_Write)(uint8_t deviceAddr, uint8_t *data, uint16_t size); // I2C 写接口(新增长度参数)
int (*I2C_Read)(uint8_t deviceAddr, uint8_t regAddr, uint8_t *data, uint16_t size); // I2C 读接口
void (*Delay_ms)(uint32_t ms); // 外部延迟函数
} ADS1115;
// 芯片操作函数结构体
typedef struct {
int (*init)(ADS1115 *chip); // 初始化函数
float (*read_channel)(ADS1115 *chip, uint8_t channel); // 单通道读取函数
} ADS1115_OPS;
// 函数声明
ADS1115_OPS Create_ADS1115_chip_ops(ADS1115 *chip);
#endif // ADS1115_H
四、源文件 ADS1115.c
// 作者:Jafi
#include "ADS1115.h"
#include "stdio.h"
float ADS1115_ReadChannel(ADS1115 *chip, uint8_t channel);
/**
* @brief 写入配置寄存器
* @param chip ADS1115 芯片指针
* @param regAddr 寄存器地址
* @param data 要写入的数据(16位)
* @return int 成功返回 0,失败返回 -1
*/
int ADS1115_WriteRegister(ADS1115 *chip, uint8_t regAddr, uint16_t data) {
uint8_t txData[3];
txData[0] = regAddr; // 寄存器地址
txData[1] = (data >> 8) & 0xFF; // 数据高位
txData[2] = data & 0xFF; // 数据低位
// 使用外部提供的 I2C 写接口,写入 3 字节数据
return chip->I2C_Write(chip->i2c_address, txData, 3);
}
/**
* @brief 初始化 ADS1115 芯片
* @param chip ADS1115 芯片指针
* @return int 成功返回 0,失败返回 -1
*/
int ADS1115_Init(ADS1115 *chip) {
// 检查是否提供了 I2C 和延迟函数接口
if (chip->I2C_Write == NULL || chip->I2C_Read == NULL || chip->Delay_ms == NULL) {
printf("ADS1115 id %d: Initialization failed, invalid function pointers\n", chip->chip_id);
chip->init_Status = 0;
return -1;
}
chip->init_Status = 1;/*先默认保持初始化成功,方便读取函数运行*/
if (ADS1115_ReadChannel(chip, 0) <= - 999.0) {/*尝试进行一次读取转换,如果正常返回,则初始化成功*/
printf("ADS1115 id %d: Initialization failed,Chip NotFound\n", chip->chip_id);
chip->init_Status = 0;
return -1;
}
// 初始化成功
printf("ADS1115 id %d initialized successfully\n", chip->chip_id);
chip->init_Status = 1;
return 0;
}
/**
* @brief 读取 ADS1115 单个通道的电压值
* @param chip ADS1115 芯片指针
* @param channel 要读取的通道号(0-3)
* @return float 返回通道电压值(单位:V)
*/
float ADS1115_ReadChannel(ADS1115 *chip, uint8_t channel) {
if (channel > 3) {
printf("ADS1115 id %d: Invalid channel number\n", chip->chip_id);
return -999.0;
}
/*芯片初始化未成功或未初始化*/
if(chip->init_Status != 1)
{
printf("ADS1115 id %d: init_Status != 1 \n", chip->chip_id);
return -999.0;
}
// 根据通道选择配置寄存器值
uint16_t config = chip->config_register_value[channel] | ADS1115_CONFIG_OS_SINGLE;
// 写入配置寄存器,启动单次转换
if (ADS1115_WriteRegister(chip, ADS1115_REG_CONFIG, config) != 0) {
printf("ADS1115 id %d: Failed to write config register\n", chip->chip_id);
return -999.0;
}
// 根据配置的速率自动计算延迟时间
uint16_t delay_time = 0;
switch (config & (0x07 << ADS1115_CONFIG_DR_OFFSET)) {
case ADS1115_CONFIG_DR_8SPS: delay_time = 125; break;
case ADS1115_CONFIG_DR_16SPS: delay_time = 63; break;
case ADS1115_CONFIG_DR_32SPS: delay_time = 31; break;
case ADS1115_CONFIG_DR_64SPS: delay_time = 16; break;
case ADS1115_CONFIG_DR_128SPS: delay_time = 8; break;
case ADS1115_CONFIG_DR_250SPS: delay_time = 4; break;
case ADS1115_CONFIG_DR_475SPS: delay_time = 2; break;
case ADS1115_CONFIG_DR_860SPS: delay_time = 1; break;
default: delay_time = 8; break; // 默认使用 128 SPS
}
// 使用外部提供的延迟函数等待转换完成
chip->Delay_ms(delay_time + 2);
// 读取转换结果
uint8_t data[2] = {0};
chip->I2C_Read(chip->i2c_address, ADS1115_REG_CONVERT, data, 2);
// 合并读取到的 16 位数据
int16_t raw_adc = (data[0] << 8) | data[1];
// 根据配置的 PGA 计算 LSB 对应的电压值
float lsb = 0.0;
switch (config & (0x07 << ADS1115_CONFIG_PGA_OFFSET)) {
case ADS1115_CONFIG_PGA_6_144V: lsb = 0.1875; break;
case ADS1115_CONFIG_PGA_4_096V: lsb = 0.125; break;
case ADS1115_CONFIG_PGA_2_048V: lsb = 0.0625; break;
case ADS1115_CONFIG_PGA_1_024V: lsb = 0.03125; break;
case ADS1115_CONFIG_PGA_0_512V: lsb = 0.015625; break;
case ADS1115_CONFIG_PGA_0_256V: lsb = 0.0078125; break;
default: lsb = 0.0625; break; // 默认使用 2.048V 满量程
}
// 将 ADC 结果转换为实际电压
float voltage = raw_adc * lsb / 1000.0;
return voltage;
}
/**
* @brief 创建并初始化 ADS1115 操作对象
* @param chip ADS1115 芯片指针
* @return ADS1115_OPS 返回操作对象
*/
ADS1115_OPS Create_ADS1115_chip_ops(ADS1115 *chip) {
ADS1115_OPS chip_ops;
chip_ops.init = ADS1115_Init; // 初始化函数
chip_ops.read_channel = ADS1115_ReadChannel; // 单通道读取函数
return chip_ops;
}
五、调用示例代码
/该示例基于Freertos + STM32 HAL库,相关接口函数自行替换/
- 申请变量
/*多芯片调用记录*/
ADS1115 ADS1115_MAIN_1;
ADS1115 ADS1115_MAIN_2;
ADS1115 ADS1115_MAIN_3;
ADS1115_OPS ADS1115_MAIN_1_ops ;
ADS1115_OPS ADS1115_MAIN_2_ops ;
ADS1115_OPS ADS1115_MAIN_3_ops ;
float MAIN_ADS1115_CHIP_0_ADC[4];
float MAIN_ADS1115_CHIP_1_ADC[4];
float MAIN_ADS1115_CHIP_2_ADC[4];
//初始化标志位数组,可省略
uint8_t ADS1115_MAIN_InitFlags[3] = {0};
- 定义自己所需的配置,具体参考手册
// 配置寄存器值
uint16_t MAIN_ADS1115_Config_Default = ADS1115_CONFIG_OS_SINGLE | // 单次转换模式触发
ADS1115_CONFIG_MODE_SINGLE | // 单次转换模式
ADS1115_CONFIG_PGA_2_048V | // 设置PGA为±2.048V
ADS1115_CONFIG_DR_16SPS | // 数据速率设置为16SPS
ADS1115_CONFIG_COMP_MODE_TRAD | // 比较器设置为传统模式
ADS1115_CONFIG_COMP_POL_LOW | // 比较器输出为低电平有效
ADS1115_CONFIG_COMP_LAT_NONLATCH | // 比较器非锁存模式
ADS1115_CONFIG_COMP_QUE_NONE | // 禁用比较器,使用ALERT/RDY引脚
0; // 选择多路复用器的输入通道
- 定义接口函数,根据自己需求定义
// 定义实际的 I2C 写操作函数
int I2C2_Write(uint8_t deviceAddr, uint8_t *data, uint16_t size) {
// 使用 HAL 库的 I2C 写入函数
if (HAL_I2C_Master_Transmit(&hi2c2, deviceAddr, data, size, 1000) != HAL_OK) {
I2C_ResetBus(&hi2c2);/*I2C总线死锁解锁*/
printf("I2C2 Write Failed\n");
return -1;
}
return 0;
}
// 定义实际的 I2C 读操作函数
int I2C2_Read(uint8_t deviceAddr, uint8_t regAddr, uint8_t *data, uint16_t size) {
// 发送寄存器地址
if (HAL_I2C_Master_Transmit(&hi2c2, deviceAddr, ®Addr, 1, 1000) != HAL_OK) {
I2C_ResetBus(&hi2c2);/*I2C总线死锁解锁*/
printf("I2C2 Read Failed (Address Send)\n");
return -1;
}
// 读取数据
if (HAL_I2C_Master_Receive(&hi2c2, deviceAddr, data, size, 1000) != HAL_OK) {
I2C_ResetBus(&hi2c2);/*I2C总线死锁解锁*/
printf("I2C2 Read Failed (Data Receive)\n");
return -1;
}
return 0;
}
// 延迟回调函数实现
void MAIN_ADC_Delay_callback(uint32_t ms) {
if (xTaskGetSchedulerState() == taskSCHEDULER_RUNNING) {
// FreeRTOS 已启动,使用 vTaskDelay
vTaskDelay(pdMS_TO_TICKS(ms));
//printf("Delay_callback: %d V\n", ms);
} else {
// FreeRTOS 未启动,使用忙等待
HAL_Delay(ms); // usleep takes microseconds
}
}
- 初始化 并调用
// 包装初始化,多次初始化失败后返回 -1
static int Initialize_ADS1115_Chip(ADS1115 *chip, ADS1115_OPS *ops) {
*ops = Create_ADS1115_chip_ops(chip);
for (int retry = 0; retry < 5; retry++) {
if (ops->init(chip) == 0) {
printf("MAIN ADS1115 Chip %d Initialized Successfully\n", chip->chip_id);
return 0 ;
}
osDelay(1);
}
printf("MAIN ADS1115 Chip %d Initialization Failed\n", chip->chip_id);
return -1 ;
}
void Read_main_adc_task_init(void)
{
/*初始化参数*/
ADS1115_MAIN_1.chip_id = 1; // 自定义芯片唯一 ID
ADS1115_MAIN_1.i2c_address = ADS1115_ADDRESS_GND; // 使用地址引脚接 GND,I2C 地址为 0x48
ADS1115_MAIN_1.I2C_Write = I2C2_Write;
ADS1115_MAIN_1.I2C_Read = I2C2_Read;
ADS1115_MAIN_1.Delay_ms = MAIN_ADC_Delay_callback;
ADS1115_MAIN_1.config_register_value[0] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_0; // 定义 ADS1115 通道的配置寄存器值
ADS1115_MAIN_1.config_register_value[1] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_1;
ADS1115_MAIN_1.config_register_value[2] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_2;
ADS1115_MAIN_1.config_register_value[3] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_3;
ADS1115_MAIN_2.chip_id = 2; // 自定义芯片唯一 ID
ADS1115_MAIN_2.i2c_address = ADS1115_ADDRESS_VDD; // 使用地址引脚接 VDD...
ADS1115_MAIN_2.I2C_Write = I2C2_Write;
ADS1115_MAIN_2.I2C_Read = I2C2_Read;
ADS1115_MAIN_2.Delay_ms = MAIN_ADC_Delay_callback;
ADS1115_MAIN_2.config_register_value[0] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_0; // 定义 ADS1115 通道的配置寄存器值
ADS1115_MAIN_2.config_register_value[1] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_1;
ADS1115_MAIN_2.config_register_value[2] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_2;
ADS1115_MAIN_2.config_register_value[3] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_3;
ADS1115_MAIN_3.chip_id = 3; // 自定义芯片唯一 ID
ADS1115_MAIN_3.i2c_address = ADS1115_ADDRESS_SDA; // 使用地址引脚接 SDA...
ADS1115_MAIN_3.I2C_Write = I2C2_Write;
ADS1115_MAIN_3.I2C_Read = I2C2_Read;
ADS1115_MAIN_3.Delay_ms = MAIN_ADC_Delay_callback;
ADS1115_MAIN_3.config_register_value[0] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_0; // 定义 ADS1115 通道的配置寄存器值
ADS1115_MAIN_3.config_register_value[1] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_1;
ADS1115_MAIN_3.config_register_value[2] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_2;
ADS1115_MAIN_3.config_register_value[3] = MAIN_ADS1115_Config_Default|ADS1115_CONFIG_MUX_SINGLE_3;
// 创建并初始化 ADS1115 操作对象
ADS1115_MAIN_1_ops = Create_ADS1115_chip_ops(&ADS1115_MAIN_1);
ADS1115_MAIN_2_ops = Create_ADS1115_chip_ops(&ADS1115_MAIN_2);
ADS1115_MAIN_3_ops = Create_ADS1115_chip_ops(&ADS1115_MAIN_3);
// 初始化芯片
osDelay(100);
if(Initialize_ADS1115_Chip(&ADS1115_MAIN_1, &ADS1115_MAIN_1_ops) != -1)ADS1115_MAIN_InitFlags[0] = 1;
else ADS1115_MAIN_InitFlags[0] = 0;
osDelay(1);
if(Initialize_ADS1115_Chip(&ADS1115_MAIN_2, &ADS1115_MAIN_2_ops) != -1)ADS1115_MAIN_InitFlags[1] = 1;
else ADS1115_MAIN_InitFlags[1] = 0;
osDelay(1);
if(Initialize_ADS1115_Chip(&ADS1115_MAIN_3, &ADS1115_MAIN_3_ops) != -1)ADS1115_MAIN_InitFlags[2] = 1;
else ADS1115_MAIN_InitFlags[2] = 0;
osDelay(1000);
}
void Read_main_adc_task(void)
{
/*单个adc芯片有转换等待时间,同一根i2c总线上如果有多个芯片,可以利用等待时间交替操作提高效率*/
/*这里只是举例采用单一task,实际可以选择使用多个task管理多个芯片,但是i2c需要记得加锁避免资源竞争产生异常*/
// 读取 ADC 数据并计算相关参数
for (int i = 0; i < 4; i++) {
MAIN_ADS1115_CHIP_0_ADC[i]= ADS1115_MAIN_1_ops.read_channel(&ADS1115_MAIN_1,i);
}
for (int i = 0; i < 4; i++) {
MAIN_ADS1115_CHIP_1_ADC[i]= ADS1115_MAIN_2_ops.read_channel(&ADS1115_MAIN_2,i);
}
for (int i = 0; i < 4; i++) {
MAIN_ADS1115_CHIP_2_ADC[i]= ADS1115_MAIN_3_ops.read_channel(&ADS1115_MAIN_3,i);
}
}
/**
* @brief Function implementing the RD_MAIN_ADC_TASK thread.
* @param argument: Not used
* @retval None
*/
void RD_MAIN_ADC_TASK_RUN(void const * argument)
{
osDelay(10);
Read_main_adc_task_init();
osDelay(100);
/* Infinite loop */
for(;;)
{
Read_main_adc_task();
osDelay(10);
}
}
六、FreeRTOS适配说明
- 延迟函数:支持
vTaskDelay()和HAL_Delay()自适应选择,适用于系统启动前和运行中两个阶段 - 建议为每颗芯片创建独立Task进行采样调度,提高并行性
- 建议访问I2C时使用互斥锁,避免多Task同时访问同一I2C总线产生冲突
七、调试建议
| 问题 | 可能原因 | 解决办法 |
|---|---|---|
| 电压返回始终为负值 | 初始化失败 | 检查 I2C 地址、连接、供电情况 |
| HAL_I2C 接口返回错误 | 总线死锁 | 增加 I2C_ResetBus() 调用解锁 |
| 电压值明显偏小或偏大 | PGA设置不匹配 | 检查满量程范围设置(±2.048V推荐) |
| 多芯片仅1个能读取 | 地址冲突 | 确保每颗芯片地址唯一(GND/VDD/SDA/SCL) |
| 所有通道读取电压为0V | 模拟输入未连接或悬空 | 确保通道连接了有效电压信号 |
| 某通道偶尔读数跳变 | 输入阻抗过高或布线干扰 | 尝试添加滤波电容或降低采样速率 |
| 单通道读取成功,多通道失败 | 配置复用器MUX错误 | 检查配置寄存器中的MUX位设置是否正确 |
| FreeRTOS下卡死 | 任务阻塞或资源竞争 | 使用互斥锁保护I2C访问,并避免任务内长时间阻塞 |
| 电压读数为最大或最小值 | 输入超过PGA设定范围或溢出 | 降低输入信号或调整 PGA 增益范围 |
| 延迟不准确影响读数 | 系统未正确调用 Delay_ms | 确保 Delay_ms 实现与当前调度器状态一致 |
八、结语
该驱动结构支持多芯片管理与用户自定义接口,适合用于 项目中进行精确模拟量采集。
欢迎大家留言交流,也欢迎点赞、收藏支持!如有错误,欢迎私信交流~
作者:Jafi
更多推荐



所有评论(0)