ADS124S06驱动基于STM32L431芯片
·
这个芯片搞起来确实麻烦,主要是时序理解和各种注意事项,100多页的手册坑很多,官方的驱动理解起来困难,适配自己的工程很麻烦,如果第一次搞这个芯片,全按手册一点点开发不知道得猴年马月;网上搜了很多资料,总体来说很杂乱,我也是找了很多资料,最后可算是跑起来了。
我使用的是STM32L431RCT6,主频5.5296MHz,使用LL库。
比较重要的几个引脚:
CS ------ PA15 (手动控制)
START/SYNC ------ PB6
SCLK ------ PB3/SPI3_SCK
DIN ------ PB5/SPI3_MOSI
DOUT ------ PB4/SPI3_MISO
DRDY ------ PD2(很重要)
我使用命令读取数据格式,也就是发一次命令读取返回一次



当前读取流程
SPI全双工通信(发送与接收同时进行)
CS拉低 → 发送5字节 → 同时接收5字节 → CS拉高
具体时序:
发送(MOSI):
- 0x12 = RDATA命令(读取转换数据)
- 0x00 = 第一个NOP(用于时钟输出MSB)
- 0x00 = 第二个NOP(用于时钟输出中间字节)
- 0x00 = 第三个NOP(用于时钟输出LSB)
- 0x00 = 第四个NOP(用于完成传输,强制拉高DOUT)
同时接收(MISO):
- 0x00 = RDATA命令的响应(STATUS禁用时为0)
- 0x00 = 24位数据的MSB(高位字节)
- 0x26 = 24位数据的中间字节
- 0x72 = 24位数据的LSB(低位字节)
- 0x00 = 最后一个NOP的响应
SEGGER_RTT_printf打印效果:

ADS124S06.C
#include "ads124s06.h"
#include "main.h"
#include "spi.h"
/*
ADS124S06模块 - STM32L431RCT6 SPI3配置:
模拟电源
AVDD ------ AVCC_3V3
AVSS ------ AGND
数字电源
DVDD ------ VDD_3V3
DGND ------ DGND
CS ------ PA15 (手动控制)
START/SYNC ------ PB6
SCLK ------ PB3/SPI3_SCK
DIN ------ PB5/SPI3_MOSI
DOUT ------ PB4/SPI3_MISO
DRDY ------ PD2
RST ------ PC12
ADS124S06基本特性:
1、模拟电源:单极(2.7V 到 5.25V)或双极 (±2.5V)
数字电源:2.7V 到 3.6V
2、参考电压2.5V,使用内部参考
SCLK下降沿写入数据, 每次传送24bit数据, 高位先传
转换或寄存器数据在 SCLK 上升沿通过 DOUT/DRDY 移出
*/
/**********************************************************************************************************
* 函 数 名: ADS124S08_WriteCmd
* 功能说明: 写命令,命令是独立的,即单字节
* 形 参: Cmd:写入ADS的命令
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_WriteCmd(uint8_t Cmd)
{
// 确保SPI3已使能
if (!LL_SPI_IsEnabled(SPI3)) {
LL_SPI_Enable(SPI3);
}
AD_nCS_LOW; //拉低片选线,使能SPI通信
for (volatile uint32_t d = 0; d < 10; d++) { __NOP(); } // 短暂延时
// 等待TXE就绪并发送数据
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd);
// 等待RXNE并读取(必须读取才能清空RXFIFO)
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
(void)LL_SPI_ReceiveData8(SPI3);
// 等待传输完成
while (LL_SPI_IsActiveFlag_BSY(SPI3)) {}
for (volatile uint32_t d = 0; d < 10; d++) { __NOP(); } // 短暂延时
AD_nCS_HIGH; //通信结束,拉高片选
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_ReadReg
* 功能说明: 读单个或多个寄存器
* 形 参: RegAddr:所要读取的寄存器地址
* Length:所要读取的寄存器数量
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_ReadReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length)
{
uint8_t Cmd[2]; //存放要发送的数据
uint8_t dummy;
(void)dummy; // 消除未使用变量警告
// 确保SPI3已使能
if (!LL_SPI_IsEnabled(SPI3)) {
LL_SPI_Enable(SPI3);
}
AD_nCS_LOW;
for (volatile uint32_t d = 0; d < 2000; d++) { __NOP(); } // ~4us延时
AD_START_HIGH; //在写寄存器时,需要将START拉高(不让其进入睡眠模式)
for (volatile uint32_t d = 0; d < 5000; d++) { __NOP(); } // ~10us延时
Cmd[0]=ADC_CMD_RREG|RegAddr; //读命令加上寄存器地址
Cmd[1]=Length-1; //读寄存器数量减一
// 发送读命令
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[0]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
// 发送寄存器数量
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[1]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
// 接收寄存器数据
for (uint8_t i = 0; i < Length; i++) {
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, ADC_CMD_NOP); // 发送NOP获取数据
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
Buffer[i] = LL_SPI_ReceiveData8(SPI3);
}
// 最后发送一个NOP,强制拉高DOUT
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, ADC_CMD_NOP);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
while (LL_SPI_IsActiveFlag_BSY(SPI3)) {}
for (volatile uint32_t d = 0; d < 5000; d++) { __NOP(); } // ~10us延时
AD_nCS_HIGH;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_WriteReg
* 功能说明: 写寄存器
* 形 参: RegAddr:所要写的寄存器地址
* Length:所要写的寄存器数量
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_WriteReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length)
{
uint8_t Cmd[2];
uint8_t dummy;
(void)dummy; // 消除未使用变量警告
// 确保SPI3已使能
if (!LL_SPI_IsEnabled(SPI3)) {
LL_SPI_Enable(SPI3);
}
AD_nCS_LOW;
for (volatile uint32_t d = 0; d < 2500; d++) { __NOP(); } // ~5us延时
AD_START_HIGH; //在写寄存器时,需要将START拉高(不让其进入睡眠模式),使器件开始转换
for (volatile uint32_t d = 0; d < 5000; d++) { __NOP(); } // ~10us延时
Cmd[0]=ADC_CMD_WREG|RegAddr;
Cmd[1]=Length-1;
// 发送写命令
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[0]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
// 发送寄存器数量
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[1]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
// 发送数据字节
for (uint8_t i = 0; i < Length; i++) {
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Buffer[i]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
dummy = LL_SPI_ReceiveData8(SPI3);
}
while (LL_SPI_IsActiveFlag_BSY(SPI3)) {}
for (volatile uint32_t d = 0; d < 5000; d++) { __NOP(); } // ~10us延时
AD_nCS_HIGH;
AD_START_LOW;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_WaitBusy
* 功能说明: 判断忙状态(等待DRDY变为低电平)
* 形 参: Timeout:超时时间 单位ms
* 返 回 值: 1:处于忙状态并超时
* 0:处于空闲状态(数据就绪)
**********************************************************************************************************/
uint8_t ADS124S08_WaitBusy(uint32_t Timeout)
{
uint32_t i = 0;
// DRDY低电平表示数据就绪,高电平表示忙
while(nAD_DRDY_STATE != 0) // 等待DRDY变为低电平
{
for (volatile uint32_t d = 0; d < 500; d++) { __NOP(); } // ~1ms延时
i++;
if(i > Timeout)
return 1;
}
return 0;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Reset
* 功能说明: 复位ADS124S06,通过引脚复位,重置数字滤波器并将所有配置寄存器值设置为默认设置,还将设备置于待机模式。
* 通过将 RESET 引脚置于低电平至少 4·tCLK·周期(约1ns),然后将引脚返回高电平来复位 ADC。
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_Reset()
{
LL_GPIO_ResetOutputPin(AD_nRST_GPIO_Port, AD_nRST_Pin);
for (volatile uint32_t d = 0; d < 100; d++) { __NOP(); } // 最小4tCLK
LL_GPIO_SetOutputPin(AD_nRST_GPIO_Port, AD_nRST_Pin);
for (volatile uint32_t d = 0; d < 2000; d++) { __NOP(); } // 最小4096tCLK,等待复位完成
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Chg_Channel
* 功能说明: ADS124S06输入通道选择(AIN0/AIN1)
* 形 参: channel:输入组数:0-5组(0对应AIN0/AIN1)
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_Chg_Channel(uint8_t channel)
{
uint8_t Cmd;
switch (channel)
{
case 0:
Cmd = (POSI_AIN(0)|NEGA_AIN(1)); // AIN0正极,AIN1负极
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
case 1:
Cmd = (POSI_AIN(2)|NEGA_AIN(3));
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
case 2:
Cmd = (POSI_AIN(4)|NEGA_AIN(5));
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
case 3:
Cmd = (POSI_AIN(6)|NEGA_AIN(7));
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
case 4:
Cmd = (POSI_AIN(8)|NEGA_AIN(9));
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
case 5:
Cmd = (POSI_AIN(10)|NEGA_AIN(11));
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
break;
default:break;
}
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Calibrate
* 功能说明: ADS124S08系统校准 校准顺序为:自偏移校准->偏移校准->增益校准
* 校准命令不能在设备处于待机模式时使用(当START/SYNC引脚低,或当停止命令发出时)。
* 形 参: 无
* 返 回 值: 无
* 注:此函数为静态函数,当前未使用,保留以备将来校准功能使用
**********************************************************************************************************/
__attribute__((unused)) static uint8_t ADS124S08_Calibrate(uint8_t Gain)
{
uint8_t R=0;
uint8_t Cmd;
// ADS124S08_WriteReg(ADC_REG_PGA,&Gain,1); // 设置增益值、ADC输出数据率
Cmd=0x10; //采样8次,失能CRC和STATUS byte
ADS124S08_WriteReg(ADC_REG_SYS,&Cmd,1); // 设置系统监测为自偏移测量
ADS124S08_WriteCmd(ADC_CMD_SELFOCAL); // 自偏移校准
R |= ADS124S08_WaitBusy(500); // 等待校准完成
// Cmd=0x21; //001 00 001
// ADS124S08_WriteReg(ADC_REG_SYS,&Cmd,1); // 设置系统监测为偏移测量
// ADS124S08_WriteCmd(ADC_CMD_SYSOCAL); // 系统偏移校准
// R |= ADS124S08_WaitBusy(500); // 等待校准完成
//
//
// Cmd=0x22; //001 00 010
// ADS124S08_WriteReg(ADC_REG_SYS,&Cmd,1); // 设置系统监测为增益测量
// ADS124S08_WriteCmd(ADC_CMD_SYSGCAL); // 系统增益校准
// R |= ADS124S08_WaitBusy(500); // 等待校准完成
return R;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Init
* 功能说明: ADS124S08初始化包括校准
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_Init(void)
{
uint8_t status;
uint8_t Cmd;
uint8_t Gain; //PGA增益
ADS124S08_Reset(); //系统复位
// 等待复位完成
for (volatile uint32_t d = 0; d < 50000; d++) { __NOP(); } // ~100ms延时等待复位稳定
ADS124S08_ReadReg( ADC_REG_STATUS, &status, 1);
// 检查POR标志位和nRDY位
if ( (status & ADS_FL_POR_MASK) ) {
// POR标志位已设置,清除它
Cmd = status & ~ADS_FL_POR_MASK; // 清除POR标志位
ADS124S08_WriteReg(ADC_REG_STATUS, &Cmd, 1);
}
// 等待设备就绪(nRDY = 0表示就绪)
uint32_t timeout = 0;
do {
ADS124S08_ReadReg( ADC_REG_STATUS, &status, 1);
timeout++;
if(timeout > 1000) {
// 超时,设备可能未就绪
return;
}
for (volatile uint32_t d = 0; d < 500; d++) { __NOP(); } // 短暂延时
} while ( (status & ADS_nRDY_MASK) != 0 ); // 等待nRDY变为0(就绪)
//初始化输入多路复用器寄存器,选择AIN0/AIN1差分输入
Cmd = (POSI_AIN(0)|NEGA_AIN(1)); // AIN0正极,AIN1负极
ADS124S08_WriteReg(ADC_REG_INPMUX,&Cmd,1);
//设置增益值、ADC输出数据率
// PGA寄存器:低3位设置增益,bit 3可能控制PGA使能
// 0x00 = 增益1 (PGA可能禁用)
// 0x08可能不是有效的增益值,使用0x00(增益1)
Gain = ADC_GAIN_1; // 0x00 = 增益1
ADS124S08_WriteReg(ADC_REG_PGA,&Gain,1);
Cmd=0x10|ADC_SPS_100 ;//关闭斩波模式,选择内部时钟,单次转换,低延迟滤波,5k采样,50hz有陷波 0X10连续转换
ADS124S08_WriteReg(ADC_REG_DATARATE,&Cmd,1);
//校准时Data Rate Register将被重新赋值,因此这里可以不用对其进行赋值
Cmd = 0x3A; //0011 1010 内部参考始终打开即使在掉电模式下,禁用参考缓冲器
ADS124S08_WriteReg(ADC_REG_REF,&Cmd,1);
Cmd=0x10; //采样8次,失能CRC和STATUS byte 00010000即为默认值
ADS124S08_WriteReg(ADC_REG_SYS,&Cmd,1);
// Cmd=0x07 ;//0000 0111 设置极大恒流源电流值1500uA(1.5mA)使用 IDAC,则必须打开内部基准电源
// ADS124S08_WriteReg(ADC_REG_IDACMAG,&Cmd,1);
//
// Cmd=0x17 ;//0010 0111 选择第一个恒流源输出引脚 (AIN2) 选择第二个电流源输出引脚(AIN7)
// ADS124S08_WriteReg(ADC_REG_IDACMUX,&Cmd,1);
//上电后,等待电源和参考电压完全稳定后再进行校准
// Cmd=ADS124S08_Calibrate(Gain); // 通道校准.配置转换参数
// Cmd = 0x03;
// ADS124S08_WriteReg(ADC_REG_GPIODAT,&Cmd,1);
//
// Cmd = 0x0f;
// ADS124S08_WriteReg(ADC_REG_GPIOCON,&Cmd,1);
//重新配置Data Rate Register
/* Cmd=0x20|ADC_SPS_4000; //0011 0000 关闭斩波模式,选择内部时钟,单次转换,低延迟滤波,数据转换速率4000
ADS124S08_WriteReg(ADC_REG_DATARATE,&Cmd,1);*/
AD_START_LOW; //START/SYNC保持低电平,等待启动命令或上升沿触发转换
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Start
* 功能说明: 启动转换
* 单次转换模式下完成转换时,器件进入待机模式,单次转换模式下拉低START引脚不会进入待机模式
* 形 参: CovMode: 转换模式(单次/连续)
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_Start(uint8_t CovMode)
{
ADS124S08_WriteCmd(ADC_CMD_WAKEUP);
AD_START_HIGH ; //启动ADC转换
for (volatile uint32_t d = 0; d < 500; d++) { __NOP(); } // ~1ms延时
if(CovMode==ADC_MODE_SINGLECOV)
AD_START_LOW; //产生启动脉冲(单次转换模式)
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Stop
* 功能说明: 停止转换
* 连续转换模式下发送 STOP 命令(或将 START/SYNC 引脚拉低)时进入待机模式
* 形 参: 无
* 返 回 值: 无
**********************************************************************************************************/
void ADS124S08_Stop()
{
ADS124S08_WriteCmd(ADC_CMD_STOP); // 发送STOP命令
AD_START_LOW; //停止转换
for (volatile uint32_t d = 0; d < 500; d++) { __NOP(); } // ~1ms延时
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Read_CMD
* 功能说明: 底层函数:指令读取ADS124S06中转换的24位数据
* 形 参: 无
* 返 回 值: 24位转换数据
**********************************************************************************************************/
int32_t ADS124S08_Read_CMD(void)
{
uint8_t Cmd[5]={ADC_CMD_RDATA,ADC_CMD_NOP,ADC_CMD_NOP,ADC_CMD_NOP,ADC_CMD_NOP}; //最后一个字节是为了强制拉高nDRDY
uint8_t Buf[5];
int32_t Data = 0;
// 确保SPI3已使能
if (!LL_SPI_IsEnabled(SPI3)) {
LL_SPI_Enable(SPI3);
}
AD_nCS_LOW;
for (volatile uint32_t d = 0; d < 2500; d++) { __NOP(); } // ~5us延时
// 发送命令并接收数据
for (uint8_t i = 0; i < 5; i++) {
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[i]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
Buf[i] = LL_SPI_ReceiveData8(SPI3);
}
while (LL_SPI_IsActiveFlag_BSY(SPI3)) {}
for (volatile uint32_t d = 0; d < 2500; d++) { __NOP(); } // ~5us延时
AD_nCS_HIGH;
//无STATUS和CRC字节数据(STATUS字节已禁用)
// RDATA命令时序:发送RDATA命令后,数据在后续的NOP传输中返回
// Buf[0] = RDATA命令响应(通常是0或状态,在STATUS禁用时为0)
// Buf[1] = 24位数据的MSB(第一个NOP时返回)
// Buf[2] = 24位数据的中间字节(第二个NOP时返回)
// Buf[3] = 24位数据的LSB(第三个NOP时返回)
// ADS124S06返回24位有符号数据,MSB在前
// 调试:打印接收到的所有字节(可选,用于调试)
SEGGER_RTT_printf(0, "RDATA Rx: %02X %02X %02X %02X %02X\r\n",Buf[0], Buf[1], Buf[2], Buf[3], Buf[4]);
Data = ((int32_t)Buf[1] << 16) | ((int32_t)Buf[2] << 8) | ((int32_t)Buf[3]);
// 符号扩展:如果最高位为1,扩展为32位有符号数
if (Data & 0x00800000) {
Data |= 0xFF800000; // 符号扩展(最高字节填充1)
}
return Data;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_Read_DIR
* 功能说明: 底层函数:直接读取ADS124S06中转换的24位数据(需在CS已拉低时调用)
* 形 参: 无
* 返 回 值: 24位转换数据
**********************************************************************************************************/
int32_t ADS124S08_Read_DIR(void)
{
uint8_t Cmd[3]={ADC_CMD_NOP, ADC_CMD_NOP,ADC_CMD_NOP};
uint8_t Buf[3];
int32_t Data = 0;
// 确保SPI3已使能
if (!LL_SPI_IsEnabled(SPI3)) {
LL_SPI_Enable(SPI3);
}
// SPI全双工:三次空命令对应三次数据
for (uint8_t i = 0; i < 3; i++) {
while (!LL_SPI_IsActiveFlag_TXE(SPI3)) {}
LL_SPI_TransmitData8(SPI3, Cmd[i]);
while (!LL_SPI_IsActiveFlag_RXNE(SPI3)) {}
Buf[i] = LL_SPI_ReceiveData8(SPI3);
}
while (LL_SPI_IsActiveFlag_BSY(SPI3)) {}
for (volatile uint32_t d = 0; d < 2500; d++) { __NOP(); } // ~5us延时
AD_nCS_HIGH;
//无STATUS和CRC字节数据(直接读取模式,Buf[0-2]是24位数据,MSB在前)
// ADS124S06返回24位有符号数据:Buf[0]=MSB, Buf[1]=中间字节, Buf[2]=LSB
Data = ((int32_t)Buf[0] << 16) | ((int32_t)Buf[1] << 8) | ((int32_t)Buf[2]);
// 符号扩展:如果最高位为1,扩展为32位有符号数
if (Data & 0x00800000) {
Data |= 0xFF800000; // 符号扩展(最高字节填充1)
}
return Data;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_GetADC_CMD
* 功能说明: 指令获取ADS124S06中转换的24位数据
* 形 参: mode: 转换模式(单次/连续)
* 返 回 值: 24位ADC数据
**********************************************************************************************************/
int32_t ADS124S08_GetADC_CMD(uint8_t mode)
{
int32_t adcVal = 0;
uint32_t delays = 0;
// 等待DRDY变为低电平(数据就绪),DRDY=0表示数据就绪
// 在连续转换模式下,等待时间应该根据数据率调整
while(nAD_DRDY_STATE != 0) // DRDY高电平表示忙,等待变为低电平
{
for (volatile uint32_t d = 0; d < 5000; d++) { __NOP(); } // ~10ms延时(根据100SPS,转换周期约10ms)
delays++;
if(delays > 200) {
// 超时(约2秒),返回0表示错误
return 0;
}
}
// DRDY已就绪,使用RDATA命令读取数据
adcVal = ADS124S08_Read_CMD();
// 注意:0是一个有效的ADC值(当输入为0V时),所以不能简单判断为错误
return adcVal;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_GetADC_DIR
* 功能说明: 直接获取ADS124S06中转换的24位数据(需DRDY已为低电平)
* 形 参: 无
* 返 回 值: 24位ADC数据
**********************************************************************************************************/
int32_t ADS124S08_GetADC_DIR(void)
{
int32_t adcVal = 0;
// 检查DRDY是否就绪(低电平表示数据就绪)
if (nAD_DRDY_STATE == 0) // DRDY低电平表示数据就绪
{
AD_nCS_LOW;
for (volatile uint32_t d = 0; d < 10; d++) { __NOP(); } // 短暂延时
adcVal = ADS124S08_Read_DIR();
}
else {
AD_nCS_HIGH; // 如果未就绪,确保CS拉高
}
if(adcVal==0) {
adcVal = 1; // 避免返回0(可能表示错误)
}
return adcVal;
}
/**********************************************************************************************************
* 函 数 名: ADS124S08_GetADC_Vol
* 功能说明: 把从ADC读来的24位有符号数据转换成对应的电压值
* 形 参: adc_data----ADC读出的24位有符号数据(已符号扩展为32位)
* 返 回 值: 电压值(伏特)
* 公式: Voltage = (ADC_Code / 2^23) * VREF / GAIN
* 其中:VREF = 2.5V, GAIN = 当前PGA增益
**********************************************************************************************************/
float ADS124S08_GetADC_Vol(int32_t adc_data)
{
// ADS124S06: 24位有符号数据,参考电压2.5V,增益根据配置
// 满量程:±VREF/GAIN = ±2.5V/GAIN
// 数据范围:-8388608 到 +8388607 (0x800000 到 0x7FFFFF)
// 电压计算公式:V = (ADC_Code / 8388608) * VREF / GAIN
const float VREF = 2.5f; // 内部参考电压 2.5V
const uint8_t GAIN = 1; // 当前PGA增益(如果PGA被禁用则为1,需要根据实际配置调整)
// 将24位有符号数转换为电压
// 注意:adc_data已经是32位有符号数(符号已扩展)
float voltage = ((float)adc_data / 8388608.0f) * VREF / (float)GAIN;
return voltage;
}
ADS124S06.H
//#include <stdio.h>
#include "main.h"
#include "spi.h"
#ifndef ADS124S06_H
#define ADS124S06_H
#endif //ADS124S06_H
//ADS124S08有关定义
//ADS124S08命令码列表
#define ADC_CMD_NOP 0x00 /*!< 空操作 */
#define ADC_CMD_WAKEUP 0x02 /*!< 退出睡眠模式 */
#define ADC_CMD_POWERDN 0x04 /*掉电*/
#define ADC_CMD_RESET 0x06 /*!< 芯片复位 */
#define ADC_CMD_START 0x08 /*开始转换*/
#define ADC_CMD_STOP 0x0A /*停止转换*/
//校准命令
#define ADC_CMD_SYSOCAL 0x16 /*!< 系统偏移校准 */
#define ADC_CMD_SYSGCAL 0x17 /*!< 系统增益校准 */
#define ADC_CMD_SELFOCAL 0x19 /*!< 系统自校准 */
//数据读命令
#define ADC_CMD_RDATA 0x12 /*!< 单次读取数据 */
//寄存器读写命令
#define ADC_CMD_RREG 0x20 /*!< 读寄存器001 00000后五位存寄存器地址 */
#define ADC_CMD_WREG 0x40 /*!< 写寄存器 */
//ADS124S08寄存器列表
#define ADC_REG_ICID 0x00
/*#define ADC_REG_STATUS 0x01*/
#define ADC_REG_INPMUX 0x02
#define ADC_REG_PGA 0x03
#define ADC_REG_DATARATE 0x04
#define ADC_REG_REF 0x05
#define ADC_REG_IDACMAG 0x06
#define ADC_REG_IDACMUX 0x07
#define ADC_REG_VBIAS 0x08
#define ADC_REG_SYS 0x09
#define ADC_REG_OFC0 0x0A
#define ADC_REG_OFC1 0x0B
#define ADC_REG_OFC2 0x0C
#define ADC_REG_FSC0 0x0D
#define ADC_REG_FSC1 0x0E
#define ADC_REG_FSC2 0x0F
#define ADC_REG_GPIODAT 0x10
#define ADC_REG_GPIOCON 0x11
/* ADS124S08 Register 0x1 (STATUS) Definition
*| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
*------------------------------------------------------------------------------------------------
*| FL_POR | nRDY | FL_P_RAILP| FL_P_RAILN| FL_N_RAILP| FL_N_RAILN| FL_REF_L1 | FL_REF_L0 |
*------------------------------------------------------------------------------------------------
*/
/** STATUS register address */
#define ADC_REG_STATUS ((uint8_t) 0x01)
/** STATUS default (reset) value */
#define STATUS_DEFAULT ((uint8_t) 0x80)
#define ADS_FL_POR_MASK 0x80
#define ADS_nRDY_MASK 0x40
#define ADS_FL_P_RAILP_MASK 0x20
#define ADS_FL_P_RAILN_MASK 0x10
#define ADS_FL_N_RAILP_MASK 0x08
#define ADS_FL_N_RAILN_MASK 0x04
#define ADS_FL_REF_L1_MASK 0x02
#define ADS_FL_REF_L0_MASK 0x10
//ADS124S08支持的增益列表
#define ADC_GAIN_1 0x00
#define ADC_GAIN_2 0x01
#define ADC_GAIN_4 0x02
#define ADC_GAIN_8 0x03
#define ADC_GAIN_16 0x04
#define ADC_GAIN_32 0x05
#define ADC_GAIN_64 0x06
#define ADC_GAIN_128 0x07
#define ADC_GAIN_EN 0x08
//ADS124S08支持的转换速率列表
#define ADC_SPS_5 0x01
#define ADC_SPS_10 0x02
#define ADC_SPS_16_6 0x03
#define ADC_SPS_20 0x04
#define ADC_SPS_50 0x05
#define ADC_SPS_60 0x06
#define ADC_SPS_100 0x07
#define ADC_SPS_100 0x07
#define ADC_SPS_400 0x09
#define ADC_SPS_1000 0x0b
#define ADC_SPS_2000 0x0c
#define ADC_SPS_4000 0x0d
//x代表AINX
#define POSI_AIN(x) (x<<4) //AIN_P PGA正极输入
#define NEGA_AIN(x) (x) //AIN_N PGA负极输入
//ADS124S08转换模式
#define ADC_MODE_SINGLECOV 0x00 //单次转换
#define ADC_MODE_CONTINUOUS 0x01 //连续转换
//Fixed timing delays
#define DELAY_4TCLK (uint16_t) (1) // 1usec ~= (4.0 /ADS124S08_FCLK) which is the minimum required low time for RESET or START/SYNC.
//定义引脚有关宏函数 - STM32L431RCT6 SPI3配置
// CS: PA15, DRDY: PD2, START: PB6, RST: PC12
#define AD_nCS_GPIO_Port GPIOA
#define AD_nCS_Pin LL_GPIO_PIN_15
#define AD_START_GPIO_Port GPIOB
#define AD_START_Pin LL_GPIO_PIN_6
#define nAD_DRDY_GPIO_Port GPIOD
#define nAD_DRDY_Pin LL_GPIO_PIN_2
#define AD_nRST_GPIO_Port GPIOC
#define AD_nRST_Pin LL_GPIO_PIN_12
#define AD_nCS_LOW LL_GPIO_ResetOutputPin(AD_nCS_GPIO_Port, AD_nCS_Pin)
#define AD_nCS_HIGH LL_GPIO_SetOutputPin(AD_nCS_GPIO_Port, AD_nCS_Pin)
#define AD_START_LOW LL_GPIO_ResetOutputPin(AD_START_GPIO_Port, AD_START_Pin)
#define AD_START_HIGH LL_GPIO_SetOutputPin(AD_START_GPIO_Port, AD_START_Pin)
#define nAD_DRDY_STATE LL_GPIO_IsInputPinSet(nAD_DRDY_GPIO_Port, nAD_DRDY_Pin)
//使用SPI3 (LL库,无需外部变量)
//函数定义,供主函数调用
//指令读取ADS124S08中的转换数据
int32_t ADS124S08_Read_CMD(void);
int32_t ADS124S08_Read_DIR(void);
//启动转换
void ADS124S08_Start(uint8_t CovMode);
//停止转换
void ADS124S08_Stop(void);
//ADS124S08初始化
void ADS124S08_Init(void);
//void ADS124S08_WriteReg(uint8_t RegAddr,uint8_t Data,uint8_t Length);
void ADS124S08_WriteReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length);
//读寄存器
void ADS124S08_ReadReg(uint8_t RegAddr,uint8_t *Buffer,uint8_t Length);
//复位ADS124S08
void ADS124S08_Reset(void);
void ADS124S08_Chg_Channel(uint8_t channel);
int32_t ADS124S08_GetADC_CMD(uint8_t mode);
int32_t ADS124S08_GetADC_DIR(void);
float ADS124S08_GetADC_Vol(int32_t adc_data);
//判断忙状态
uint8_t ADS124S08_WaitBusy(uint32_t Timeout);
void ADS124S08_WriteCmd(uint8_t Cmd);
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)