简介:面向 STM32 单片机与 ARM 嵌入式开发者,这份 HAL 库驱动 ADS124S08 的例程包,专门解决高精度 24 位 ADC 在工业采集、传感器数据测量等项目中的快速接入问题,代码基于 SPI 通信实现,涵盖接口初始化、寄存器读写、转换启动、中断接收以及误差校正和数据处理等关键环节,移植性较强,可直接嵌入到现有 STM32 工程中使用。压缩包共 4 个文件,由 2 个 C 源文件和 2 个头文件组成,整体大小仅 6KB,结构简单,适合逐行阅读与二次修改,核心驱动函数做了模块化封装,便于将 ADS124S08 快速配置为 SPI 从设备并完成高精度数据读取,资源已有 891 人学习浏览,适合需要掌握 HAL 库 SPI 驱动写法、理解 ADS124S08 寄存器操作或开发高精度数据采集系统的开发者参考。通过该例程,读者可以拿到可直接调用的底层驱动框架,并从中获得 STM32 HAL 库 SPI 初始化、中断传输、读取 ADC 转换结果和基础误差校正的完整思路,能有效缩短从芯片手册到实际运行的调试周期。
1. STM32 HAL库驱动ADS124S08:一片24位ADC最少要写多少代码
某开发者第一次把ADS124S08接到STM32上,对着数据手册的SPI时序图抄了半天,读ID读出来的全是0x00,最后发现只是CPOL/CPHA配错了一位。这类“用HAL库驱动24位高精度ADC”的例程,听起来简单,但寄存器读写、片选时序、DRDY等待、配置顺序,任何一步走错,读回来的数据都像玄学。这套例程就是为了解决这个问题:一个能直接编译烧录的最小STM32单片机工程,覆盖从CubeMX生成工程、SPI初始化、ADS124S08寄存器配置,到把24位原始码换算成电压值的完整链路。适合刚接触ADS124S08的嵌入式开发者,也适合拿现成代码做二次开发的人。
2. 硬件与通信链路:SPI接线、电源和参考电压怎么摆
2.1 ADS124S08的关键参数
先看芯片本身。ADS124S08是一颗24位Delta-Sigma型ADC,内置8通道输入,可以配置成差分输入或单端输入,数据速率从2.5SPS到4000SPS可调,内置1到128倍可编程增益放大器PGA,还集成了两个可用于热电偶、RTD测量的恒流源IDAC。对做工业采集、温度测量、称重信号调理的嵌入式开发者来说,这颗芯片最大的吸引力是“单片集成度够高”:外部只需要配一个基准电压和几颗去耦电容,就能拿到24位分辨率的数据,不用像以前那样在前级堆仪表放大器。
| 参数 | 数值 | 说明 |
|---|---|---|
| 分辨率 | 24 bit | 二进制补码输出 |
| 通道数 | 8 | 支持差分/单端组合 |
| 数据速率 | 2.5 ~ 4000 SPS | CONFIG3低4位配置 |
| PGA | 1 ~ 128 倍 | 内部集成 |
| 参考电压 | 0.5V ~ AVDD | 内部2.048V或外部参考 |
| 接口 | SPI | 支持MODE1/MODE3 |
| IDAC | 2 路 | 50uA ~ 1500uA |
这颗芯片的输出数据格式是24位二进制补码,正满量程对应0x7FFFFF,负满量程对应0x800000,换算电压时把三字节拼成有符号数再乘以参考电压就行。注意输入共模范围和参考电压强相关,输入信号不能超过参考电压,这也是很多人初次上板时读数异常的原因之一。
2.2 最小接线:其实只需要六根线
芯片和STM32之间走SPI,最少需要SCLK、DIN、DOUT/DRDY、CS四根信号线,加上电源和地,一共六根。这里有一个容易被忽略的细节:ADS124S08没有独立的DRDY引脚,数据就绪信号和DOUT共用一根线,叫DOUT/DRDY。数据还没准备好时这根线输出高电平,转换完成会拉低,紧接着数据在SCLK驱动下从同一根线上移出来。所以硬件上可以把DOUT/DRDY同时接到SPI的MISO和一个普通GPIO,等待DRDY时读GPIO,读数据时交给SPI外设。如果引脚紧张,也可以不接GPIO,软件里轮询MISO的电平,但会占用SPI外设切换时间,不如接一颗GPIO省心。
以一块常见的STM32F4核心板为例,推荐这样分配:
| 信号 | ADS124S08引脚 | STM32引脚 | 备注 |
|---|---|---|---|
| SCLK | SCLK | SPI2_SCK | 时钟,分频后不超过4MHz |
| MOSI | DIN | SPI2_MOSI | 主机写从机 |
| MISO | DOUT/DRDY | SPI2_MISO | 数据输出 |
| DRDY | DOUT/DRDY | PE4 | 和MISO并联,下降沿表示数据就绪 |
| CS | CS | PE3 | 片选,低有效 |
| 电源 | DVDD/AVDD | 3.3V | 分开走线,去耦就近 |
注意:DOUT/DRDY在同一网络同时接了MISO和PE4,属于一根线分叉到两个MCU引脚,这种接法不影响SPI通信,但GPIO必须先配置成输入模式,否则输出模式会拉死SPI信号。CS不建议复用SPI的NSS硬件自动管理,ADC片选时序要求很高,用普通GPIO手动控制最稳。
2.3 电源和参考电压的摆放
ADS124S08的模拟电源AVDD和数字电源DVDD可以接同一路3.3V,但PCB上必须就近放去耦电容:每个电源引脚至少一颗100nF,靠近电源入口再加一颗10uF钽电容或MLCC。如果AVDD和DVDD直接短接不加任何隔离,SPI数字噪声会顺着电源平面窜进模拟部分,直接表现为转换结果在末几位跳来跳去。讲究一点的板子会在AVDD和DVDD之间串一颗磁珠或0欧电阻,让数字电流和模拟电流各走各的回路。
参考电压方面,芯片内置2.048V参考源,配置内部参考使能后REFP引脚会输出2.048V,REFN接模拟地就能用,省掉外部基准。但如果项目里需要对不同量程做精密测量,外部接一颗2.5V或4.096V精密基准更好,注意外部参考电压范围要求是0.5V到AVDD之间,接太高或太低都会让寄存器里的参考报警位拉起来。初次调试建议先启用内部参考,排除外部基准的干扰变量,等SPI链路和数据链路都通了再换外部基准。
2.4 5V电平系统的处理方式
如果MCU是3.3V,芯片也是3.3V供电,信号线直连即可。但有的老开发板上的GPIO引脚被外部上拉到5V,或者SPI总线上还挂着其他5V外设,这时SCLK高电平如果高于芯片电源电压,长时间工作可能损坏输入引脚。稳妥做法是在SPI线上串330欧电阻限流,或者加一颗电平转换芯片。只接一片ADC、MCU和ADC共用3.3V的话,这部分可以完全跳过。注意别把5V直接灌进DIN或SCLK,芯片手册里对绝对最大输入电压有严格要求,这个我吃过亏,第一次调试把SCLK接到了5V输出的引脚上,第二天芯片就烧了,后来规规矩矩用3.3V供电才稳定。
硬件链路讲清楚后,下一步的代码其实就是把接线关系翻译成HAL库配置。CS、DRDY、SPI三部分在CubeMX里分别对应GPIO输出、GPIO输入、SPI外设,接下来是最核心的驱动代码。
3. 核心代码拆解:从复位命令到24位数据换算
3.1 底层SPI收发的三个基础函数
HAL库里SPI发送接收非常简单,核心是HAL_SPI_TransmitReceive。但要驱动ADS124S08,不能直接调库函数裸收发,因为读写寄存器、读转换数据、发命令这三种操作的帧格式都不同,而且CS片选必须在一次完整事务里保持一致。先封装三个底层函数:
static void ADS124S08_CsLow(void) { HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_RESET); } static void ADS124S08_CsHigh(void) { HAL_GPIO_WritePin(CS_GPIO_Port, CS_Pin, GPIO_PIN_SET); } void ADS124S08_WriteByte(uint8_t txData) { uint8_t rxData; HAL_SPI_TransmitReceive(&hspi2, &txData, &rxData, 1, 10); }三个函数各干一件事:CsLow和CsHigh负责片选,WriteByte负责在CS有效的窗口内发一个字节。这样上层构造命令帧时就能保证CS在整个事务过程中不被拉高,避免芯片把一条命令拆成两半。
最常见的坑是直接用HAL_SPI_Transmit发完命令字节后,又调用HAL_SPI_Receive读返回数据,中间CS没有保持有效。ADS124S08的SPI时序是“CS低电平时SCLK驱动数据,CS高电平时命令终止”,所以CS在整个命令加数据阶段必须保持低。写成上面这样,每个操作都先拉低CS、再连续调用收发、最后拉高CS,就永远不会出现CS中途变高的问题。
3.2 寄存器读写命令的帧格式
ADS124S08的寄存器读写命令格式是:第一个字节是命令编码,RREG用0x20按位或寄存器地址,WREG用0x40按位或寄存器地址;第二个字节是访问寄存器数量减1。后面跟数据字节,写寄存器时跟随要写入的值,读寄存器时是芯片输出要读的值。
uint8_t ADS124S08_ReadRegister(uint8_t regAddr) { uint8_t txBuf[2]; uint8_t rxData; txBuf[0] = 0x20 | (regAddr & 0x1F); // RREG命令 txBuf[1] = 0x00; // 读1个寄存器,数量减1 ADS124S08_CsLow(); HAL_SPI_Transmit(&hspi2, txBuf, 2, 10); HAL_SPI_Receive(&hspi2, &rxData, 1, 10); ADS124S08_CsHigh(); return rxData; } void ADS124S08_WriteRegister(uint8_t regAddr, uint8_t regValue) { uint8_t txBuf[3]; txBuf[0] = 0x40 | (regAddr & 0x1F); // WREG命令 txBuf[1] = 0x00; // 写1个寄存器 txBuf[2] = regValue; // 要写入的值 ADS124S08_CsLow(); HAL_SPI_Transmit(&hspi2, txBuf, 3, 10); ADS124S08_CsHigh(); }参数说明:regAddr是寄存器地址,ADS124S08的寄存器从0x00的ID寄存器到0x0E的GPIO寄存器共15个,常用几个地址是0x00(ID)、0x02(CONFIG0)、0x03(CONFIG1)、0x05(CONFIG3)、0x06(MUX0)。txBuf[1]传0x00表示只读写一个寄存器,如果一次要连续读多个寄存器,比如读MUX0和MUX1,把txBuf[1]改成0x01即可,芯片会按地址递增连续输出数据。
注意0x20和0x40都是固定命令头,不能直接拿寄存器地址当命令字节发送。刚入门时容易把这两个搞混,写寄存器用0x20发出去,芯片完全没反应,寄存器值一直是复位默认值,查半天查不出问题。
3.3 复位、读ID、配置通道
芯片上电后首先要发RESET命令,然后等待内部振荡器稳定。复位完成后第一步就是读ID寄存器,这是判断SPI是否通的最快手段。代码实现如下:
uint8_t ADS124S08_Init(void) { uint8_t id; // 复位芯片,0x06是RESET命令 ADS124S08_WriteByte(0x06); HAL_Delay(5); // 读ID寄存器,SPI没通时读回0x00或0xFF id = ADS124S08_ReadRegister(0x00); if (id == 0x00 || id == 0xFF) { return 1; // 初始化失败 } // 配置CONFIG0:关闭两个IDAC,保持默认 ADS124S08_WriteRegister(0x02, 0x00); // 配置MUX0:差分输入AIN0/AIN1,PGA默认1倍 ADS124S08_WriteRegister(0x06, 0x00); return 0; }逻辑上分三段:复位命令0x06只需发一个字节,芯片内部自己完成复位,延时5ms等待内部振荡器起振和上电时序走完;接着读ID,ID值芯片不同批次可能不同,但只要不是0x00或0xFF,就说明DOUT/DRDY这根线能把数据送回来,SCLK时序也基本对了;最后写两个寄存器,CONFIG0写0x00关闭两个IDAC,MUX0写0x00选择差分输入AIN0和AIN1作为第一路转换通道。
复位后ADC内部寄存器大多是默认值,PGA默认就是1倍,20SPS的速率也是默认配置之一。上面的配置其实有两行是保险起见写上,真正必须改的是通道选择和IDAC开关。写代码时保持这种显式初始化关键寄存器的习惯很有用,改板子、换芯片时不用背复位默认值表,查代码就能看全配置。
3.4 启动转换并等待DRDY
接下来进入数据读取流程。芯片支持单次转换模式和连续转换模式两种跑法,连续模式适合周期性采样,代码省事;单次模式适合事件触发式采集,功耗更低。例程先用连续模式:
void ADS124S08_StartContinuous(void) { ADS124S08_WriteByte(0x08); // START命令 } uint8_t ADS124S08_ReadConversion(uint8_t *data) { uint8_t cmd = 0x12; // RDATA命令 uint32_t timeout = 1000; // 等待DRDY变低,转换结果就绪 while (HAL_GPIO_ReadPin(DRDY_GPIO_Port, DRDY_Pin) != GPIO_PIN_RESET) { if (--timeout == 0) return 1; // 超时退出,防止卡死 } ADS124S08_CsLow(); HAL_SPI_Transmit(&hspi2, &cmd, 1, 10); HAL_SPI_Receive(&hspi2, data, 3, 10); ADS124S08_CsHigh(); return 0; }START命令0x08发出去后,ADC开始连续转换。每次转换完成后DOUT/DRDY引脚拉低,此时主控发RDATA命令(0x12)把24位数据读回来。data指针指向一个三字节缓冲区,收到的是高字节在前、低字节在后的原始补码。
timeout变量是调试时加的安全阀。实际项目中DRDY卡死最常见的原因不是芯片坏了,而是上一次RDATA读完后没有等DRDY复位就再次尝试读数据,或者START根本没发出去。加上超时逻辑后,程序至少不会死循环,把timeout标志从串口打出来,就能定位是哪个环节卡住。
3.5 把24位原始码换算成电压
读回来的三字节不能直接用,需要先拼成有符号整数,再根据参考电压和PGA计算实际电压:
float ADS124S08_ToVoltage(uint8_t *data, float vref, uint8_t pga) { int32_t raw = ((int32_t)data[0] << 16) | ((int32_t)data[1] << 8) | (int32_t)data[2]; if (raw & 0x800000) { raw -= 0x1000000; // 负数补码转原值 } return (float)raw * vref / (0x7FFFFF * pga); }第一行把三字节拼成整数,注意强制类型转换必不可少。如果写成data[0] << 16,char类型会先整型提升为有符号int,当最高位是1时左移结果变成负数,最终拼出来的raw整体错位,换算电压时会出现奇怪的负跳变。这类写大端SPI多字节协议时特别容易踩到,建议所有SPI读多字节的驱动里都养成先转int32_t再移位的习惯。
if语句处理负数补码:24位补码的最高位是符号位,当raw大于等于0x800000时实际上表示负值,减去0x1000000把它还原成带符号负数。电压换算公式是:电压 = 原始码 × 参考电压 / (2^23 - 1) × PGA增益。分母是0x7FFFFF,因为24位正满量程的码值就是0x7FFFFF,对应电压值正好等于参考电压,前提是PGA为1。
到这里驱动最核心的部分已经完整:CS控制、寄存器读写命令、复位和初始化、启动转换、等待DRDY、读数、换算电压。剩下的工作就是把这一套函数接入CubeMX生成的工程,再把初始化调用和数据读取循环放进main函数。
4. 跑通例程:从CubeMX配置到串口打印电压
4.1 CubeMX中的外设配置
用CubeMX生成工程时,主要配置三部分:SPI2、GPIO和调试串口。SPI2在Mode里选择Full-Duplex Master,Parameter Settings里按下面表格设置时钟极性和相位:
| 配置项 | 值 | 原因 |
|---|---|---|
| Mode | Full-Duplex Master | 标准四线SPI |
| Data Size | 8 Bits | 芯片按字节处理命令 |
| First Bit | MSB First | 芯片要求高位在前 |
| Clock Polarity | High | 空闲时SCLK为高 |
| Clock Phase | 2 Edge | 数据在第二个边沿采样,对应MODE3 |
| Prescaler | 16分频 | 让SCLK落在芯片允许范围内 |
这里最容易踩的坑是CPOL和CPHA。ADS124S08数据手册里的SPI时序图,SCLK空闲时为高电平,数据在SCLK下降沿之后稳定、上升沿被采样,这对应SPI Mode 3,也就是CPOL=High、CPHA=2 Edge。有些开发者从网上抄了Mode 0配置,读ID永远返回0x00。CubeMX里改完这两项需要重新生成代码,HAL库的SPI初始化结构体才会更新。
GPIO方面再配置两个普通引脚:CS用输出模式,初始电平设为High;DRDY用输入模式,DOUT/DRDY空闲时本身是高电平,外部GPIO不用开上拉。串口用USART2或任意空闲串口,波特率115200,用于打印调试信息。
4.2 例程目录结构与移植清单
生成完CubeMX基础工程后,把驱动文件放进工程,目录结构大致如下:
- Core/Inc、Core/Src:CubeMX生成的main.c、中断处理文件等
- Drivers:HAL库源码和启动文件
- App/ads124s08.h:驱动头文件,声明寄存器地址和对外函数
- App/ads124s08.c:驱动实现,包含前面写的所有函数
- App/main_app.c:应用层,调用Init和ReadConversion并打印结果
把这套驱动移植到另一块板子上时,要改的点只有三个:ads124s08.c里引用的hspi2换成自己的SPI句柄,CS和DRDY引脚的GPIO宏定义换成新板子的引脚,时钟分频数根据主频重新算一遍。其余代码不需要动,这也是把驱动独立成模块而不是写进main.c的好处。
ads124s08.h里一般这样定义寄存器地址和对外接口:
// 常用寄存器地址 #define ADS124S08_REG_ID 0x00 #define ADS124S08_REG_CONFIG0 0x02 #define ADS124S08_REG_CONFIG3 0x05 #define ADS124S08_REG_MUX0 0x06 // 对外接口 uint8_t ADS124S08_Init(void); uint8_t ADS124S08_ReadConversion(uint8_t *data); float ADS124S08_ToVoltage(uint8_t *data, float vref, uint8_t pga);4.3 主流程验证步骤
main函数里的调用顺序很关键,按这个流程走一遍基本能确认板子和驱动都没问题:
int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_SPI2_Init(); MX_USART2_UART_Init(); if (ADS124S08_Init() != 0) { printf("[ERR] ADC init fail\n"); while (1); } printf("[OK] ADC init done\n"); ADS124S08_StartContinuous(); uint8_t buf[3]; while (1) { if (ADS124S08_ReadConversion(buf) == 0) { float v = ADS124S08_ToVoltage(buf, 2.048f, 1); printf("raw=0x%02X%02X%02X v=%.6f\n", buf[0], buf[1], buf[2], v); } HAL_Delay(100); } }把AIN0和AIN1两根输入引脚短接到GND,正常时串口应该打印接近0.000000的电压值。再接入一节1.5V干电池,串口输出的电压值会稳定在1.5V附近。如果这个流程通了,说明从CubeMX配置到驱动函数全链路没问题,后面接传感器就只改通道配置和量程换算。
发现串口打印的raw值恒为0x7FFFFF或0x800000时,不要急着改驱动,先用万用表量AIN0对GND电压,确认输入引脚真的被信号驱动了。ADC只管转换,输入悬空时读回满量程是完全正常的。
4.4 用逻辑分析仪确认SPI时序
软件上跑通后,建议用逻辑分析仪抓一次SCLK、CS、DOUT/DRDY三根线的波形,确认三件事:CS低电平期间SCLK输出完整且连续的脉冲,采样过程中不能有缺口;DOUT/DRDY在CS拉低之前已经处于低电平,说明DRDY等待逻辑生效;最后一个字节读完后CS拉高,SCLK停止。第一次抓波形时看到SCLK上有毛刺,后来发现是杜邦线太长,SPI速率又配得比较高,把Prescaler从8分频改成16分频后波形就干净了。这些经验写在代码注释里不值钱,但能省去后面接传感器时的大量排错时间。
5. 踩坑记录:ADS124S08 调试时最常见的五个问题
5.1 读ID全是0x00:SPI模式不是玄学是CPOL/CPHA没对齐
现象:串口打印ID寄存器读回值永远是0x00,换电源、换引脚都没用。
原因:ADS124S08要求SPI工作在模式1或模式3,即CPOL=0/CPHA=1或者CPOL=1/CPHA=1。很多从网上抄来的HAL配置用的是Mode0,CPOL=0/CPHA=0,SCLK空闲低电平且数据在第一个边沿采样,和芯片要求的时序完全对不上。
解决:在CubeMX里把Clock Polarity设为High、Clock Phase设为2 Edge,重新生成代码再试。如果还不能解决,用逻辑分析仪抓SCLK和DOUT,看芯片回应数据的边沿是否落在配置的采样点上。在这上面折腾过一整个晚上,最后发现是DIN和DOUT两根杜邦线在面包板上插反了,读回来当然全0。
5.2 等待DRDY卡死:START没发或者CS提前拉高
现象:程序跑进while等待DRDY变低的循环,timeout超时退出,串口没有任何输出。
原因:配置完寄存器后忘了发START命令0x08,或者CS在命令传输结束后过早拉高,芯片还没把DRDY拉低,后续转换结果根本没产生。
解决:确认调用顺序是Init、配置寄存器、发START、再进等待循环。同时检查CS的事务窗口:发START命令时CS低电平要完整覆盖命令字节的8个SCLK周期,命令结束后CS拉高,DRDY大约在一个转换周期后拉低。用示波器在DRDY线上能看到周期性的低脉冲,如果没有,说明START没生效。
5.3 输入悬空读回满量程:不是芯片坏了
现象:没接传感器时读回0x7FFFFF,接上信号后数据又正常了。
原因:ADS124S08是高输入阻抗ADC,PGA打开后输入引脚悬空时,引脚上微弱的噪声会被PGA放大到接近满量程,这是正常现象,不是芯片故障。
解决:调试时把AIN0和AIN1短接到GND读零点,再接入实际信号读量程。如果零点校准后数据还有一个固定偏置,用软件在SYS0寄存器里做系统校准,或者简单地在应用层按偏移量扣除。别在悬空状态下判断ADC好坏,会误判。
5.4 数据末位跳动大:电源去耦和PGA惹的祸
现象:输入接稳定的1.5V电池,读回数据末位跳几十个码,换算成电压在正负几个毫伏之间抖。
原因:三个因素可能叠加:AVDD去耦电容离芯片太远;PGA增益开得过大,噪声同时被放大;SCLK频率过高,数字噪声通过MISO和DIN线窜进模拟输入。
解决:先在每个电源引脚就近加100nF电容,AVDD入口加10uF,把PGA降到1倍再观察跳动幅度,SPI分频调低到1MHz左右。这样处理后大多数板子的跳动能控制在正负1到2个码。如果还不行,检查参考电压引脚有没有并联电容,参考源的噪声会直接进入转换结果。
5.5 连读模式下写寄存器不生效:先退出连续读模式
现象:程序里调用了写CONFIG3改数据速率的函数,串口测试发现实际输出速率完全没变。
原因:如果之前在代码里发过RDATAC命令(0x14)让芯片进入连续读模式,那么除了RDATAC及STOP等少数命令外,大部分寄存器写命令都不会执行,芯片会一直按进入连续读模式那一刻的配置工作。
解决:在执行WREG写寄存器之前,先发SDATAC命令(0x16)退出连续读模式,延时一小段时间让命令生效,再写寄存器。更省事的做法是例程里根本不用RDATAC,每次读数据都用RDATA命令单点读,虽然多一个命令字节开销,但和寄存器配置逻辑完全不冲突。
上面这五个问题基本覆盖了第一次调这块芯片会遇到的绝大多数故障,而且互相之间有连带关系:ID读不出,后面所有配置和读数都不会正常。建议调试时严格按“复位读ID、配置、START、读数据、换算”五步走,每一步都打印确认信息,不要跳过。
6. 二次开发方向:多通道轮询、中断读取与传感器对接
例程跑通之后,二次开发的入口基本都在MUX0和CONFIG3上。改成多通道轮询最简单:MUX0寄存器选通通道,每次切换通道后等待DRDY出现一次新的转换结果,再读数据。注意ADS124S08在连续转换模式下,切换通道后至少等一个转换周期再读数,否则读到的还是上一通道的量。循环里把MUX0写成0x00、0x10、0x20这种通道选通值,中间夹一个20ms延时就能扫描多路。
用DRDY外部中断替代轮询,是提高实时性的常见做法。把DOUT/DRDY引脚接到EXTI输入,下降沿触发中断,在中断回调里调用ADS124S08_ReadConversion,把原始三字节数据放进环形缓冲区,主循环只负责消费数据。中断服务函数里不要做浮点除法算电压,只保存原始码,浮点运算放到主循环,否则中断响应时间会被拉长。
接热电偶时,利用芯片内置IDAC恒流源可以省掉外部激励电路:配置CONFIG0把IDAC1电流设为500uA,输出接到RTD或热敏电阻一端,同时把该电阻接入差分通道,PGA开到16或32倍,再用内部2.048V参考,整个前端电路只需要两颗电阻。校准时用已知温度点做两点校准,把偏移和增益误差一起消掉。
最后一个建议:拿到任何新ADC,先按芯片手册里的时序图画一遍CS、SCLK、DOUT波形再动手写寄存器,比烧录后瞎猜快得多。从那以后我每次接新传感器芯片,都强制自己先做时序图笔记,再写驱动,踩坑率明显降下来。希望帮到你。
本文还有配套的精品资源,点击获取