STM32CubeMX + HAL库搞定ADS1115:从I2C配置到多通道轮询采样的完整流程
2026/5/23 11:05:32 网站建设 项目流程

STM32CubeMX + HAL库搞定ADS1115:从I2C配置到多通道轮询采样的完整流程

在嵌入式开发中,模拟信号采集是一个常见但容易踩坑的环节。ADS1115作为一款16位精度的ADC芯片,凭借其I2C接口和内置可编程增益放大器(PGA),成为许多STM32项目中替代片内ADC的理想选择。本文将从一个真实的工业传感器采集项目出发,带你完整走通从硬件连接到软件实现的每个环节。

1. 硬件准备与环境搭建

1.1 元器件选型与电路设计

ADS1115典型应用电路需要关注几个关键点:

  • 参考电压:使用3.3V供电时,确保VDD与GND间并联0.1μF去耦电容
  • 地址引脚:ADDR引脚接法决定I2C地址(默认0x48)
  • 输入保护:在AIN0-AIN3输入端串联100Ω电阻并配合TVS二极管

注意:当测量负电压时,需确保共模电压在-0.3V~VDD+0.3V范围内

1.2 STM32CubeMX工程初始化

创建新工程时建议选择这些配置:

/* I2C配置示例 */ hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 400000; // 标准模式400kHz hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;

2. I2C通信层实现

2.1 HAL库函数封装

针对ADS1115的寄存器操作,建议封装以下基础函数:

HAL_StatusTypeDef ADS1115_WriteReg(I2C_HandleTypeDef *hi2c, uint8_t reg, uint16_t value) { uint8_t buf[3] = {reg, value >> 8, value & 0xFF}; return HAL_I2C_Master_Transmit(hi2c, ADS1115_ADDR, buf, 3, HAL_MAX_DELAY); } uint16_t ADS1115_ReadReg(I2C_HandleTypeDef *hi2c, uint8_t reg) { uint8_t buf[2]; HAL_I2C_Mem_Read(hi2c, ADS1115_ADDR, reg, I2C_MEMADD_SIZE_8BIT, buf, 2, HAL_MAX_DELAY); return (buf[0] << 8) | buf[1]; }

2.2 异常处理机制

实际项目中必须添加的健壮性设计:

  • 超时重试:当I2C通信失败时自动重试3次
  • CRC校验:对关键配置数据进行校验
  • 总线恢复:检测到总线锁死时执行时钟拉伸恢复

3. 多通道采样策略

3.1 配置寄存器详解

ADS1115的配置寄存器(0x01)各bit功能:

Bit位置字段名功能说明
15OS单次转换启动位
14:12MUX输入通道选择(000=A0-A1...)
11:9PGA增益设置(001=±4.096V)
8MODE工作模式(1=单次,0=连续)
7:5DR数据速率(100=1600SPS)
4:0COMP_*比较器相关配置

3.2 轮询采样实现

高效的多通道采样需要解决两个核心问题:

  1. 通道切换时序:等待当前转换完成后再切换通道
  2. 数据对齐处理:16位有符号数转实际电压值
float ADS1115_ReadChannel(I2C_HandleTypeDef *hi2c, uint8_t channel) { // 设置MUX位并启动转换 uint16_t config = ADS1115_DEFAULT_CONFIG | (channel << 12); ADS1115_WriteReg(hi2c, ADS1115_REG_CONFIG, config); // 等待转换完成(约1ms@860SPS) while (!(ADS1115_ReadReg(hi2c, ADS1115_REG_CONFIG) & 0x8000)); // 读取并转换结果 int16_t raw = (int16_t)ADS1115_ReadReg(hi2c, ADS1115_REG_CONVERSION); return raw * ADS1115_LSB_SIZE / 32768.0f; }

4. 实际项目集成技巧

4.1 抗干扰设计

在工业现场应用中特别有效的措施:

  • 数字滤波:采用滑动平均滤波算法
#define FILTER_DEPTH 8 float voltage_filter[FILTER_DEPTH]; float filtered_voltage = 0; void UpdateFilter(float new_val) { static uint8_t index = 0; filtered_voltage += (new_val - voltage_filter[index]) / FILTER_DEPTH; voltage_filter[index] = new_val; index = (index + 1) % FILTER_DEPTH; }
  • 接地隔离:对模拟和数字地采用磁珠隔离
  • 采样同步:配合硬件触发信号进行采集

4.2 低功耗优化

电池供电场景下的关键配置:

  1. 将DR设置为最低的8SPS
  2. 使用单次转换模式(MODE=1)
  3. 每次采样后使能ALERT/RDY引脚中断
  4. 主控MCU进入STOP模式等待唤醒

5. 调试与性能测试

5.1 常见问题排查

开发者最常遇到的三个问题及解决方案:

现象可能原因解决方法
读取值始终为0x7FFF输入超量程调整PGA增益或检查传感器输出
I2C通信无应答地址配置错误检查ADDR引脚电平
采样值跳动大参考电压不稳增加电源去耦电容

5.2 性能评估指标

使用信号发生器注入1kHz正弦波,测试得到:

参数测试结果
ENOB(有效位数)15.2位
THD(总谐波失真)-78dB
通道切换延时1.2ms@860SPS

在完成基础功能后,建议使用STM32的DMA功能进一步优化吞吐量。通过配置I2C DMA传输,可以实现后台自动读取转换结果,配合定时器触发可构建完整的无阻塞数据采集系统。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询