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, &regAddr, 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


Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐