当前位置: 首页 > news >正文

别再对着手册发愁了!STM32驱动ADS1115的完整配置流程与电压读取代码分享

从零玩转STM32与ADS1115:高精度ADC配置实战指南

1. 硬件连接与基础认知

当你第一次拿到ADS1115模块时,可能会被它小巧的尺寸和密密麻麻的引脚吓到。别担心,让我们先来认识这个16位精度ADC的核心特性。ADS1115采用I2C接口通信,这意味着你只需要连接4根线就能让它工作:

  • VDD:3.3V电源输入(注意:绝对不要超过5.5V)
  • GND:接地
  • SCL:I2C时钟线,连接STM32的PB6(以F103系列为例)
  • SDA:I2C数据线,连接STM32的PB7

提示:ADDR引脚接地时,器件地址为0x90(写)和0x91(读),这是最常见的配置方式。

ADS1115的三大核心优势使其在嵌入式领域广受欢迎:

  1. 16位分辨率:比常见的10位ADC(如STM32内置ADC)精度高出64倍
  2. 可编程增益:支持±6.144V到±0.256V的输入范围
  3. 内置基准:无需外接基准电压源
// 基础I2C初始化代码(HAL库示例) I2C_HandleTypeDef hi2c1; void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.ClockSpeed = 100000; // 100kHz标准模式 hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2; hi2c1.Init.OwnAddress1 = 0; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) { Error_Handler(); } }

2. 配置寄存器深度解析

Config寄存器是ADS1115的大脑,理解它的每一位含义是成功使用的关键。这个16位寄存器分为高字节(MSB)和低字节(LSB),每个bit都有特定功能:

位域名称功能描述典型值
15OS单次转换触发1(启动转换)
14-12MUX输入选择0x4(A0单端)
11-9PGA增益设置0x1(±4.096V)
8MODE工作模式0(连续转换)
7-5DR数据速率0x4(128SPS)
4-0比较器配置本文不使用0x03

MUX配置实战

  • 0x0: AIN0 vs AIN1(差分)
  • 0x1: AIN0 vs AIN3(差分)
  • 0x4: AIN0单端(最常用)
  • 0x5: AIN1单端
  • 0x6: AIN2单端
  • 0x7: AIN3单端
#define CONFIG_MSB 0xC2 // OS=1, MUX=0x4, PGA=0x1, MODE=0 #define CONFIG_LSB 0x83 // DR=0x4, 比较器禁用

3. 完整驱动代码实现

现在让我们把这些理论知识转化为可运行的代码。以下是一个经过实战检验的驱动实现:

// ads1115.h #ifndef __ADS1115_H #define __ADS1115_H #include "stm32f1xx_hal.h" #define ADS1115_ADDR 0x90 // 寄存器定义 #define REG_CONVERSION 0x00 #define REG_CONFIG 0x01 // 电压读取函数 float ADS1115_ReadVoltage(I2C_HandleTypeDef *hi2c, uint8_t channel); #endif
// ads1115.c #include "ads1115.h" void ADS1115_WriteConfig(I2C_HandleTypeDef *hi2c, uint8_t mux_config) { uint8_t config[3]; config[0] = REG_CONFIG; config[1] = 0xC2 | (mux_config << 4); // 保持其他配置不变,仅修改MUX config[2] = 0x83; HAL_I2C_Master_Transmit(hi2c, ADS1115_ADDR, config, 3, 100); } float ADS1115_ReadVoltage(I2C_HandleTypeDef *hi2c, uint8_t channel) { uint8_t reg = REG_CONVERSION; uint8_t data[2]; int16_t raw_value; float voltage; // 先配置输入通道 ADS1115_WriteConfig(hi2c, channel); // 启动转换(对于单次模式) if((CONFIG_MSB & 0x80) == 0x80) { HAL_Delay(10); // 等待转换完成 } // 读取转换结果 HAL_I2C_Master_Transmit(hi2c, ADS1115_ADDR, &reg, 1, 100); HAL_I2C_Master_Receive(hi2c, ADS1115_ADDR, data, 2, 100); // 组合16位数据 raw_value = (data[0] << 8) | data[1]; // 转换为实际电压(±4.096V量程) if(raw_value >= 0x8000) { voltage = (0xFFFF - raw_value) * -4.096 / 32768.0; } else { voltage = raw_value * 4.096 / 32768.0; } return voltage; }

4. 实际应用与调试技巧

在实际项目中,你可能会遇到各种意想不到的问题。以下是几个常见场景的解决方案:

场景1:读数不稳定

  • 检查电源是否干净(建议增加0.1μF去耦电容)
  • 降低I2C时钟速度(尝试100kHz→50kHz)
  • 在SCL/SDA线上增加4.7kΩ上拉电阻

场景2:I2C通信失败

  • 确认地址正确(0x90或0x48左移一位)
  • 用逻辑分析仪抓取I2C波形
  • 检查HAL_I2C_Master_Transmit返回值

场景3:电压读数偏差大

  • 确认PGA设置与实际输入电压匹配
  • 检查参考电压是否稳定
  • 使用万用表对比测量结果

注意:当输入电压接近量程上限时,建议选择更大的PGA值(如±2.048V),这样可以获得更好的分辨率。

多通道轮询示例

void ReadAllChannels(void) { float voltages[4]; const uint8_t channels[] = {0x04, 0x05, 0x06, 0x07}; // A0-A3单端 for(int i=0; i<4; i++) { voltages[i] = ADS1115_ReadVoltage(&hi2c1, channels[i]); printf("AIN%d: %.3fV\r\n", i, voltages[i]); HAL_Delay(100); } }

5. 进阶应用:数据采集系统搭建

当你掌握了基础读数后,可以尝试构建更完整的采集系统:

  1. 定时采样:利用STM32定时器触发定期读取
  2. DMA传输:减少CPU开销
  3. 数据滤波:实现简单的移动平均滤波
#define SAMPLE_COUNT 10 float GetFilteredVoltage(uint8_t channel) { static float buffer[SAMPLE_COUNT]; static uint8_t index = 0; float sum = 0; // 采集新数据 buffer[index] = ADS1115_ReadVoltage(&hi2c1, channel); index = (index + 1) % SAMPLE_COUNT; // 计算平均值 for(int i=0; i<SAMPLE_COUNT; i++) { sum += buffer[i]; } return sum / SAMPLE_COUNT; }

在电源监测项目中,我发现ADS1115的连续转换模式配合DMA可以构建极低功耗的数据记录仪。通过合理配置DR位(数据速率),可以在精度和功耗之间取得平衡——对于缓慢变化的温度信号,8SPS的速率就足够了,这能显著降低系统功耗。

http://www.jsqmd.com/news/738590/

相关文章:

  • 3dMax脚本小白福音:手把手教你用Octopus的Chronos宏记录器自动化重复操作
  • Moltis:构建安全可控的个人AI智能体服务器全指南
  • 教育科技公司利用 Taotoken 构建自适应学习辅导系统
  • 终极指南:如何用applera1n轻松绕过iOS激活锁
  • 高效Word到LaTeX转换:docx2tex实战配置指南
  • 明日方舟MAA自动化助手:5步快速上手终极指南
  • 从零搭建 AI 应用时 Taotoken 在模型选型与快速验证上带来的效率提升
  • Seraphine:如何用这个终极智能BP助手3分钟提升你的排位胜率?
  • 逆向分析实战:如何用Frida Hook掉iOS App的代理检测函数(以CFNetworkCopySystemProxySettings为例)
  • Kilo极简网络隧道工具:基于WireGuard的轻量级点对点组网实践
  • Windows热键冲突终结者:Hotkey Detective帮你3分钟定位“元凶“
  • ROS机器人GPS数据解析实战:从sensor_msgs/NavSatFix消息到地图定位的完整流程
  • SpringBoot项目里,用Dynamic-Datasource和Druid搞定多数据库读写(附完整配置)
  • 从NCBI下载fna到画出进化树:一条龙完成细菌泛基因组分析(Prokka+Roary实战)
  • 用Python复刻经典AI实验:手把手教你实现一个动物识别专家系统
  • Source Han Serif CN:7字重开源宋体终极解决方案
  • 对比直接使用厂商API体验Taotoken在计费透明性上的优势
  • 契约式AI编程框架:基于OpenClaw与Codex的可验证开发流水线设计
  • 从一条CAN报文讲起:手把手带你用Python脚本模拟UDS 3E服务,实现ECU会话保活
  • NCL30000 LED驱动设计:CrM模式与漏感优化实践
  • VMware VSAN集群关机重启,我踩过的那些坑(附7.0U3版本功能实测)
  • 告别杂乱桌面!用Start11在Win11上复活全屏磁贴菜单的保姆级教程
  • 终极指南:3步免费绕过iOS 15-16激活锁的完整教程
  • Jmeter计数器配置全解析:从‘线程组迭代重置’到‘用户独立跟踪’的完整测试流程搭建
  • 别只盯着顶刊!这些Q1/Q2的医学图像处理SCI期刊,或许更适合你‘上岸’
  • Equalizer APO完整指南:如何免费获得专业级Windows音频均衡效果
  • 分期乐用户福音:支付宝立减金快速回收的超简单方法 - 团团收购物卡回收
  • 3分钟掌握SignatureTools:安卓开发者必备的图形化签名神器
  • 终极Obsidian模板指南:30分钟搭建你的Zettelkasten知识库系统
  • 从STM32F103到GD32F103:一个真实项目移植的完整避坑记录(含源码)