ADS131A04的驱动代码(STM32 HAL库)

发布时间:2026/9/11 16:25:25

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); } }
延伸阅读

更多相关文章

2026/9/9 18:37:20

AI与高德MCP打造智能旅行规划系统

1. 项目概述:AI与高德MCP的旅行规划革命去年帮朋友规划云南自驾游时,我花了整整三天时间查攻略、排路线、算时间,最后做出的行程表还是漏洞百出。这种痛苦经历促使我探索用技术解决旅行规划难题,直到发现高德MCP(Model…

2026/9/8 8:29:23

基于IBM TSS库的BLS门限签名实战:从分布式密钥生成到签名验证

1. 项目概述:为什么我们需要BLS门限签名? 如果你在分布式系统、区块链或者多方计算领域摸爬滚打过一阵子,肯定对“签名”这件事又爱又恨。爱的是,它是数字世界里身份和授权的基石;恨的是,传统的单点签名&am…

2026/9/6 22:38:35

FPGA开发板PWM模块设计与Verilog实现

1. 盘古1K开发板与PWM模块设计概述盘古1K开发板作为国产FPGA学习平台,凭借其高性价比和丰富的外设接口,已成为数字电路设计入门的首选工具之一。本次练习聚焦PWM(脉冲宽度调制)模块设计,这是嵌入式系统和电机控制领域的…

2026/9/11 16:22:38

免密码进行SSH连接、Mac远程连接windows系统(拷贝本地文件)

文章目录 前言 I 免密码进行SSH连接 1.1 创建 rsa 1.2 配置 ssh config 1.3 测试连接 1.4 案例: 配置GitHub SSH keys II 远程连接windows系统。 2.1 Mac远程连接windows 2.2 windows远程连接windows 2.3 RustDesk开源远程桌面访问解决方案 III see also 移除私钥密码(Passph…

2026/9/11 16:22:37

DS18B20在ESP32上的单总线时序实现与优化

简介:面向ESP32开发者的DS18B20数字温度传感器驱动源码包,适用于智能家居、农业环境监测、工业过程控制等物联网测温场景。DS18B20支持高精度单总线通信,仅需一根数据线即可与ESP32的GPIO连接,电源与数据线供电方式灵活&#xff0…

2026/9/11 16:22:37

3步本地部署Duix.Avatar数字人视频生成工具

3步本地部署Duix.Avatar数字人视频生成工具 【免费下载链接】Duix-Avatar 🚀 Truly open-source AI avatar(digital human) toolkit for offline video generation and digital human cloning. 项目地址: https://gitcode.com/GitHub_Trending/he/Duix-Avatar …

2026/9/11 16:17:37

QGIS与Cesium瓦片地图集成开发指南

1. QGIS与Cesium瓦片地图数据集成概述在GIS开发领域,QGIS作为开源地理信息系统代表工具,与Cesium这一领先的Web三维地图引擎的协同使用正成为行业趋势。最近在完成一个智慧城市项目时,我需要将Cesium的二维瓦片地图服务集成到QGIS桌面环境中进…

2026/9/10 16:39:38

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/10 11:16:38

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 12:32:02

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/10 15:49:53

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码