ADS131A04的驱动代码(STM32 HAL库)
一、硬件接线这是本项目中ADS131A04的原理图AIN1与AIN2为ADC芯片的模拟输入端AVDD、AVSS等引脚就按照典型应用连接本项目中M2接地、M1通过1k电阻接地、M0接到IOVDD高电平这三个引脚设置了SPI为异步中断模式通信一个命令字为24bit。CLKIN为芯片的工作时钟会影响采集速率与单片机相连用于SPI通信的引脚有CS、SCLK、DOUT、DIN、RADY用于硬件复位的引脚为RESETDONE引脚用于多机通信和同步通信本项目没有用到。可以看出M0、1、2不同的配置会影响命令与数据长度和通信模式二、引脚配置接下来需要配置引脚根据手册中引脚的功能配置单片机对应的IO口输入或输出比如DIN为芯片的输入单片机对应的引脚就要配置为outputDOUT为芯片的输出单片机对应的引脚就应该配置为input一般来说还需要上拉用于消除浮空不稳定状态但是在原理图中已经dout已经经过一个100k电阻上拉到iovdd了因此不需要配置单片机引脚上拉。DRDY为芯片用于通知单片机读取数据的引脚当数据准备好之后就会发出脉冲下降沿触发因此单片机对应引脚需要配置为EXIT下降沿触发。三、时钟设置根据下面三张图我们可以计算输入的时钟频率/晶振频率与ADC转换后的数字量输出频率假设使用默认的寄存器配置fDATAfMOD/400fICLK/8/400fCLKIN/8/8/400假设将CLKIN设为4.23MHz数字量转换的频率为4.23MHz/25600165Hz也就是大约每6ms会在DRDY上产生一个下降沿脉冲通知单片机进行数据接收。因此可以根据输入的时钟频率配置不同的寄存器值得到所需要的AD转换速率。四、启动流程接下来得看一下ADS131A04的启动流程可以看到要启动芯片以一定频率进行自动转换需要输入一系列的命令我们逐步来说明一下。在上电之后芯片会读取M0、1、2口的状态同时会将模拟和数字电源上电。之后你需要复位芯片你可以使用硬件时序进行复位本项目采用的方式或者使用复位指令根据下面两张图在硬件复位的时候你需要将RESET引脚拉低至少800ns然后高电平至少持续4.5ms接着你可以使用SPI协议读取到Ready状态字也就是0xff04五、通讯时序与格式对于SPI协议下面这一张图会解释它的时序简单来说先将CS拉低代表通讯开始接着SCLK控制每一个bit的读入与输出在SCLK上升沿时芯片DOUT锁存器存入新的bit供单片机读取同时单片机将缓存区bit输出至芯片的DIN因此对于外设来说每一个SCLK脉冲完成一个bit的读与写经过一定个数的SCLK上升沿后取决于字长一个字的传输完成最后以CS拉高结束。通过CSSCLKMISOMOSI四根线可以实现高速的双向数据传输前面我们说过硬件复位后可以通过SPI协议的时序读取到Ready状态字0xff04下面我们看看ADC芯片的字和帧是如何构成的我们可以看到一个字根据不同的设置可以是16,24,32bit在本项目中我们设置的是24bit也就是说需要读取一个字需要24个SCKL上升沿而一个帧的数据则是由多个字组成的。下面是ADC芯片的SPI命令字它们都是16bit的可以看到在启动流程中的所有命令都在下面用十六进制数写明了对应的还有每一个命令字的回复我们看一看Ready命令的回复是0xFFdd其中dd是设备型号ADS131A04对应的回复就是0xFF04这就是启动流程中所说的那个准备完成状态字。命令字的发送和接收相对简单对于读写寄存器操作需要增加一些前缀比如说RREG指令001a aaaa nnnn nnnnb它是以001开头其中a为寄存器地址范围是00h~14hn在读单个寄存器时为0在读多个寄存器值为需要读的寄存器数n再减1。而WREG010a aaaa nnnn nnnnb则需要以010开头a同样代表寄存器地址d代表需要写入到对应寄存器的8bit数据。还记得前面我们说过本次采用的是24bit字长可是命令字都是16位的这16位命令字在24bit字长的命令中如何分布呢可以看看下面这一张图应该说总的字长32bit如果采用24bit有效字长那么高位填0中间为16bit有效命令最右边8bit为汉明码实际上我们没有使用汉明码所以也填0。所以前面所说的0xff04在24bit字长模式下应该为0x00ff0400对应的UNLOCK命令为0x0655也就是0x00065500。这一点希望大家注意还有一点重要的是ADC芯片的响应是跨帧匹配的也就是说在SPI发送命令时接收到的数据不是当前命令的回应当前命令的回应会在下一次的读取中收到仔细看看下面的时序注意图中的箭头发送的UNLOCK命令对应着ACK在下一个帧才回复。对于这种方式如果想要收到UNLOCK命令的ACK只要在UNLOCK后发送一条NULL0x00命令即可此时读到的数据就是对应上一条的UNLOCK六、启动代码最后根据我们上面所说的一些原理编写stm32的启动代码按照流程启动后在DRDY上会出现周期性的脉冲用于通知单片机接收AD转换的结果代码附在下方根据自己的硬件接线配置一下SPI引脚就可以使用。ads131a04.c#include ads131a04.h static void delay_us(uint32_t us) { uint32_t cnt us * (SystemCoreClock / 1000000) / 12; while(cnt--); } // 功能发送 24bit 数据同时读取 24bit 响应 // 输入cmd16 16bit 命令函数内部自动左移8位变成 0x00XXYY00 格式 // 输出芯片返回的 24bit 数据格式0x00FFFFFF uint32_t resp 0; // 保存接收的24bit数据 uint32_t ADS_Send24Bit(uint16_t cmd16) { // 关键把16bit命令 → 左移8位 → 变成 24bit 格式 0x00XXYY00 // 完全匹配你说的 UNLOCK 0x00065500 格式 uint32_t cmd24 ((uint32_t)cmd16 8) 0x00FFFFFF; // CS拉低开始通信 HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); // 严格收发 24bit 一位发一位收同步进行 for(uint8_t i 0; i 24; i) { // 1. 输出当前最高位到 DIN if(cmd24 0x00800000) HAL_GPIO_WritePin(ADS_DIN_GPIO_Port, ADS_DIN_Pin, GPIO_PIN_SET); else HAL_GPIO_WritePin(ADS_DIN_GPIO_Port, ADS_DIN_Pin, GPIO_PIN_RESET); // 数据左移准备下一位 cmd24 1; // 2. SCLK 上升沿芯片锁存 DIN HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_SET); delay_us(1); // 3. 同时读取 DOUT 一位SPI标准同步收发 resp 1; if(HAL_GPIO_ReadPin(ADS_DOUT_GPIO_Port, ADS_DOUT_Pin) GPIO_PIN_SET) resp | 0x01; // 4. SCLK 下降沿 HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_RESET); delay_us(1); } // CS拉高结束 HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); // 返回接收的24bit数据格式 0x00FFFFFF return resp 0x00FFFFFF; } // 24bit 读取 uint32_t ADS_Read24Bit(void) { uint32_t data 0; HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); for(uint8_t i0; i24; i) { data 1; HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_SET); delay_us(1); if(HAL_GPIO_ReadPin(ADS_DOUT_GPIO_Port, ADS_DOUT_Pin)) data | 1; HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_RESET); delay_us(1); } HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); return data; } // 读单个寄存器RREG uint8_t ADS131A04_ReadReg(uint8_t addr) { // 指令格式(001a aaaa nnnn nnnn)b 读单个寄存器n0 uint16_t cmd 0x2000 | ((addr 0x1F) 8); uint32_t resp ADS_Send24Bit(cmd); return (resp 8) 0xFF; } // 写单个寄存器WREG void ADS131A04_WriteReg(uint8_t addr, uint8_t data) { // 指令格式(010a aaaa dddd dddd)b uint16_t cmd 0x4000 | ((addr 0x1F) 8) | data; ADS_Send24Bit(cmd); } // 读取数据帧 void ADS131A04_ReadDataFrame(uint8_t *buf) { HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_RESET); for(uint8_t i0; i13; i) { uint8_t d 0; for(uint8_t j0; j8; j) { d 1; HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_SET); delay_us(1); if(HAL_GPIO_ReadPin(ADS_DOUT_GPIO_Port, ADS_DOUT_Pin)) d | 1; HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_RESET); delay_us(1); } buf[i] d; } HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); } uint32_t ready_copy0; // 初始化100% 正确时序 void ADS131A04_Init(void) { // 初始电平 HAL_GPIO_WritePin(ADS_CS_GPIO_Port, ADS_CS_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(ADS_SCLK_GPIO_Port, ADS_SCLK_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(ADS_RST_GPIO_Port, ADS_RST_Pin, GPIO_PIN_SET); delay_us(10); // 硬件复位 HAL_GPIO_WritePin(ADS_RST_GPIO_Port, ADS_RST_Pin, GPIO_PIN_RESET); delay_us(2); HAL_GPIO_WritePin(ADS_RST_GPIO_Port, ADS_RST_Pin, GPIO_PIN_SET); // 等待复位完成 t_d(RSSC) delay_us(7000); for(int i0;i2;i) { // 读取 READY 状态字 uint32_t ready ADS_Read24Bit(); ready_copyready; } if((ready_copy 0x00FFFF00) ! ((uint32_t)READY_RESPONSE 8)) return; // 1. 读READYUNLOCK ADS_Send24Bit(UNLOCK_CMD); ADS_Send24Bit(0x00); //跨帧应答用null指令得到上次的回复 // 2. 配置系统寄存器 ADS131A04_WriteReg(ADS_A_SYS_CFG, 0x60); // 模拟系统配置 ADS_Send24Bit(0x00); ADS131A04_WriteReg(ADS_D_SYS_CFG, 0x3C); // 数字系统配置 ADS_Send24Bit(0x00); ADS131A04_WriteReg(ADS_CLK2, 0x86); // 时钟/过采样率配置 ADS_Send24Bit(0x00); // 3. 使能ADC通道流程图要求 ADS131A04_WriteReg(ADS_ADC_ENA, 0x0F); ADS_Send24Bit(0x00); ADS131A04_ReadReg(ADS_ADC_ENA); ADS_Send24Bit(0x00); // 4. 启动转换 锁定寄存器 ADS_Send24Bit(WAKEUP_CMD); ADS_Send24Bit(0x00); ADS_Send24Bit(LOCK_CMD); ADS_Send24Bit(0x00); }ads131a04.h#ifndef __ADS131A04_H #define __ADS131A04_H #include stm32f1xx_hal.h // 引脚定义 #define ADS_DOUT_Pin GPIO_PIN_5 #define ADS_DOUT_GPIO_Port GPIOA #define ADS_CS_Pin GPIO_PIN_6 #define ADS_CS_GPIO_Port GPIOA #define ADS_DIN_Pin GPIO_PIN_7 #define ADS_DIN_GPIO_Port GPIOA #define ADS_SCLK_Pin GPIO_PIN_11 #define ADS_SCLK_GPIO_Port GPIOB #define ADS_RST_Pin GPIO_PIN_10 #define ADS_RST_GPIO_Port GPIOB // 系统命令 #define NULL_CMD 0x0000 #define RESET_CMD 0x0011 #define STANDBY_CMD 0x0022 #define WAKEUP_CMD 0x0033 #define LOCK_CMD 0x0555 #define UNLOCK_CMD 0x0655 // 响应 #define READY_RESPONSE 0xFF04 // 寄存器命令前缀 #define RREG_CMD_PREFIX 0x20 #define WREG_CMD_PREFIX 0x40 // 官方正确寄存器地址100% 匹配你发的手册 #define ADS_CONFIG1 0x01 // 配置1 #define ADS_CLK2 0x0E // 时钟配置2OSR配置 #define ADS_A_SYS_CFG 0x0B // 模拟系统配置 #define ADS_D_SYS_CFG 0x0C // 数字系统配置Fixed/CRC帧格式 #define ADS_ADC_ENA 0x0F // ADC通道使能写0x0F // 函数声明 void ADS131A04_Init(void); uint32_t ADS_Send24Bit(uint16_t cmd16); uint32_t ADS_Read24Bit(void); uint8_t ADS131A04_ReadReg(uint8_t addr); void ADS131A04_WriteReg(uint8_t addr, uint8_t data); void ADS131A04_ReadDataFrame(uint8_t *buf); #endif接收ADC信息代码在外部中断回调函数里面调用void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin GPIO_PIN_1) { uint8_t buf[13]; ADS131A04_ReadDataFrame(buf); } }

相关新闻

嵌入式日志系统设计:SD NAND与文件系统选型实践

嵌入式日志系统设计:SD NAND与文件系统选型实践

1. 嵌入式日志系统的核心挑战与选型考量在嵌入式开发中,可靠的日志系统是调试和故障排查的生命线。不同于PC环境,嵌入式设备面临三大核心挑战:存储介质寿命有限(特别是Flash类存储)、突发掉电风险高、存储空间严格受限…

2026/7/17 6:50:33阅读更多 →
RP2040 PIO硬件状态机开发实战与优化技巧

RP2040 PIO硬件状态机开发实战与优化技巧

1. 认识RP2040的PIO外设:硬件状态机的革命第一次拿到BPI-Pico-RP2040开发板时,我注意到规格表里有个叫PIO的神秘外设。作为传统单片机开发者,我原以为这不过是又一个普通的外设接口,直到实际用它实现了一个精确定时的WS2812 LED驱…

2026/7/17 6:50:33阅读更多 →
ELF 1开发板实现exFAT/NTFS支持与优化实践

ELF 1开发板实现exFAT/NTFS支持与优化实践

1. 为什么ELF 1开发板需要支持exFAT/NTFS?在嵌入式Linux开发中,文件系统兼容性是个经常被忽视但实际影响巨大的问题。ELF 1开发板默认支持的FAT32文件系统有个致命缺陷——单个文件大小不能超过4GB。这个限制在以下场景会直接导致项目受阻:高…

2026/7/17 6:50:33阅读更多 →
GLM-5.2与GPT-5.5编程任务对比:开源模型成本优势与工程实践

GLM-5.2与GPT-5.5编程任务对比:开源模型成本优势与工程实践

上周,我在本地机器上同时跑了三个模型来处理同一批18个编程任务:Z.ai刚发布的GLM-5.2、OpenAI的GPT-5.5,以及开源可下载的DeepSeek V4-Pro。结果让我有点意外——那个可以合法下载、在MIT协议下跑在自己硬件上的GLM-5.2,总成本只有…

2026/7/17 7:55:37阅读更多 →
星火应用商店:Linux软件安装的终极解决方案,三步搞定应用管理

星火应用商店:Linux软件安装的终极解决方案,三步搞定应用管理

星火应用商店:Linux软件安装的终极解决方案,三步搞定应用管理 【免费下载链接】星火应用商店Spark-Store 星火应用商店是国内知名的linux应用分发平台,为中国linux桌面生态贡献力量 项目地址: https://gitcode.com/spark-store-project/spa…

2026/7/17 7:55:37阅读更多 →
CANN/asc-devkit半精度比较函数

CANN/asc-devkit半精度比较函数

__hge 【免费下载链接】asc-devkit 本项目是CANN 推出的昇腾AI处理器专用的算子程序开发语言,原生支持C和C标准规范,主要由类库和语言扩展层构成,提供多层级API,满足多维场景算子开发诉求。 项目地址: https://gitcode.com/cann…

2026/7/17 7:55:37阅读更多 →
具身智能的Skill进化机制:可组合、可演化、可审计的物理技能架构

具身智能的Skill进化机制:可组合、可演化、可审计的物理技能架构

1. 项目概述:当“具身智能”不再只拼参数,而是比谁更懂怎么学技能“具身智能”这个词最近半年在技术圈和产业端的热度,已经明显压过了单纯讨论大模型参数量的旧叙事。但很多人还没意识到——真正拉开差距的,根本不是谁家的模型又多…

2026/7/17 7:55:37阅读更多 →
Python+Selenium自动化抢票脚本实战:从原理到部署的完整指南

Python+Selenium自动化抢票脚本实战:从原理到部署的完整指南

1. 项目概述:为什么我们需要自动化抢票? 每次热门演唱会、话剧或者体育赛事开票,守在手机或电脑前,心跳加速、手指颤抖,结果页面一刷新就显示“缺货登记”——这种经历,相信很多人都深有体会。手速再快&am…

2026/7/17 7:55:37阅读更多 →
palera1n实战指南:iOS 15.0+设备越狱深度解析与完整解决方案

palera1n实战指南:iOS 15.0+设备越狱深度解析与完整解决方案

palera1n实战指南:iOS 15.0设备越狱深度解析与完整解决方案 【免费下载链接】palera1n Jailbreak for A8 through A11, T2 devices, on iOS/iPadOS/tvOS 15.0, bridgeOS 5.0 and higher. 项目地址: https://gitcode.com/GitHub_Trending/pa/palera1n palera1…

2026/7/17 7:50:37阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/16 8:28:11阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/16 6:53:04阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/16 12:02:41阅读更多 →
VS Code 高效配置与个性化定制全攻略

VS Code 高效配置与个性化定制全攻略

1. VS Code 高效配置基础作为一款轻量级但功能强大的代码编辑器,VS Code 的默认配置已经能满足基本需求,但通过合理调整设置可以大幅提升编码效率。我使用 VS Code 已经有五年多时间,期间尝试过各种配置方案,总结出这套适合大多数…

2026/7/17 0:00:01阅读更多 →
从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

从竞赛代码到桌面工具:让 SuperADD 与 SubspaceAD 真正跑进自己的图像

在异常检测领域,很多优秀算法最初都是以研究代码的形式发布的。它们能够在固定测试集上复现实验结果,却不一定能被普通用户直接拿来测试自己的图片。尤其是最近很多算法仅提供在固定测试集的测试环境,而gradio的demo演示也不会提供。 对工程应用和在自己的图片上进行测试来…

2026/7/17 0:00:01阅读更多 →
WinRAR高效配置指南:从基础安装到高级压缩实战

WinRAR高效配置指南:从基础安装到高级压缩实战

前几天帮同事处理一个客户发来的压缩包,解压时系统自带的工具弹出一串乱码,换用 WinRAR 却顺利打开了。这种看似简单的场景,恰恰暴露了不同压缩工具在处理非标准编码、分卷压缩或加密文件时的差异。WinRAR 作为一款老牌工具,真正价…

2026/7/17 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/16 20:13:14阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/16 8:58:42阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/16 17:10:26阅读更多 →