AD7124-4 实测热电偶数据读取,电压精度到稳定到±1uV, 电压波动260nV, 温度精度到±0.01℃
- AD7124_STM32_ADI官网例程
- 使用stm32 和ad7124做温控调试,发现效果还是不错的,至少比ads1256的效果好多啦!
- Chapter1 AD7124-4 实测热电偶数据读取,电压精度到稳定到±1uV, 电压波动260nV, 温度精度到±0.01℃
- Chapter2 24Bit Σ-Δ ADC——AD7124的多通道初始化配置
- Chapter3 STM32的硬件SPI驱动AD7124的方法
- Chapter4 AD7124的调试总结
- AD7124芯片的调试闭坑总结
- 1、SPI通讯速率尽量不要大于5M,但是实测,短线情况下9M通讯正常。
- 2、SYNC引脚一定要拉高,拉低的话不转换。
- 3、无法通过ADC_CONTROL寄存器控制内部基准
- 4、注意选择参考电压
- 5、REFOUT引脚,需要对地接一个0.1uF电容,否则会出问题。
- 6、在初始化写入AD7124寄存器前,最好一定读一次状态寄存器,否则可能写入寄存器失败。
- 7、测内部20mV信号时,请断开外部AI连接,否则可能AD芯片死机
- 8、精度问题
- 9、AD工作模式及校准
- 10、REFIN(+) 与 REFIN(-)之差的范围是 1V到3.3V ,这个一定要注意,低于1V,芯片可能会不转换,这个问题折磨了我很久。
- 11、在实际使用过程中,注意 AI通道的对AVSS的绝对电压范围
- 12、电源问题:AVSS 与 IVSS ,最好单独供电,
- 13、还是紧接着电源问题
AD7124_STM32_ADI官网例程
https://wiki.analog.com/resources/tools-software/product-support-software/ad7124-stm32
使用stm32 和ad7124做温控调试,发现效果还是不错的,至少比ads1256的效果好多啦!
原文链接:https://blog.csdn.net/zhengwenbang/article/details/133308700
Chapter1 AD7124-4 实测热电偶数据读取,电压精度到稳定到±1uV, 电压波动260nV, 温度精度到±0.01℃
CH0 CH1两通连续转换模式,PGA 64: SPS: 8.89 使用快速建立模式, Sinc3 + Sinc1
(偏置与增益寄存器均使用原厂默认参数,这2个寄存器未配置)
CH0(AIN0 AIN1)对应 CONFIG0 CH1(AIN2 AIN3)对应CONFIG1。 两个通道均是双极性配置,AIN0上使能了内部偏置电压。(为了热电偶应用)
当然,要让ADC运行稳定 首先硬件上ADC电路,供电电路要稳定,AD7124-4我是自己针对客户应用的做的隔离模块。AD7124 SPI通讯使用隔离SPI芯片。
ADC的电源 是这样。 ADDC+DCDC隔离模块B0505+LDO最终到3.3V, 还有其它包括不限于 共模滤波 三端滤波器 等等。高精度外部2.5V参考电压源。
ACDC:是从市电转成5V
DCDC隔离模块用的B0505。5V转成隔离5V 专供ADC模块。
LDO:RTQ2520GQW(这个不好买,建议用其它的超低噪声LDO): 隔离后5V再降压成3.3V专供AD7124
///AD7124多通道连续转换模式初始化
///1对1映射
void Ad7124_Multichannel_Continuous_Conversion_Init( void )
{
///uint32_t temp_32bit=0;
Ad7124_Sofe_Reset(); ///上电后一定要复位,否则ADC会运行异常。
uint8_t temp[2]={0XFF,0XFF};
vTaskDelay( 100 );
Ad7124_Read_Regs( Ad7124Regs[AD7124_ID_REG].addr, temp, Ad7124Regs[AD7124_ID_REG].size );
temp[0]&=0XF0; ///去掉低4位才是DEVICE_ID
if( temp[0] == AD7124_DEVICE_ID )
{
DBG_PRINTF( "ad7124 read Id ok\r\n" );
}
else
{
DBG_PRINTF( "ad7124 read Id ERROR\r\n" );
}
vTaskDelay( 100 );
Read_Ad7124_State_Reg(); ///上电后要先读取一次状态寄存器
vTaskDelay( 100 );
///写AD7124 控制寄存器 ///连续转换 AD7124_ADC_CTRL_REG_DATA_STATUS
Ad7124Regs[AD7124_ADC_CTRL_REG].value=AD7124_ADC_CTRL_REG_DATA_STATUS |AD7124_ADC_CTRL_REG_DOUT_RDY_DEL
| AD7124_ADC_CTRL_REG_REF_EN | AD7124_ADC_CTRL_REG_POWER_MODE( CTRL_FULL_POWER )\
| AD7124_ADC_CTRL_REG_MODE( CTRL_CONTINUOUS_CONVERSION_MODE ) | AD7124_ADC_CTRL_REG_CLK_SEL( 0 );
Ad7124_Write_Regs( AD7124_ADC_CTRL_REG, Ad7124Regs[AD7124_ADC_CTRL_REG].value,Ad7124Regs[AD7124_ADC_CTRL_REG].size );
///写AD7124 通道0寄存器,0号通道开启
Ad7124_Write_Regs( AD7124_CH0_MAP_REG, AD7124_CH_MAP_REG_CH_ENABLE\
| AD7124_CH_MAP_REG_SETUP( CH_SETUP0 ) | AD7124_CH_MAP_REG_AINP( CH_AIN0 ) | AD7124_CH_MAP_REG_AINM( CH_AIN1 ), SIZE_BYTE2 );
///写AD7124 通道1寄存器
Ad7124_Write_Regs( AD7124_CH1_MAP_REG, AD7124_CH_MAP_REG_CH_ENABLE \
| AD7124_CH_MAP_REG_SETUP( CH_SETUP1 ) | AD7124_CH_MAP_REG_AINP( CH_AIN2 ) | AD7124_CH_MAP_REG_AINM( CH_AIN3 ), SIZE_BYTE2 );
///写AD7124 配置1寄存器 64 ±39.06 mV
Ad7124_Write_Regs( AD7124_CFG0_REG, AD7124_CFG_REG_BIPOLAR \
| AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM \
| AD7124_CFG_REG_REF_SEL( CFG_REF_REFIN1 ) | AD7124_CFG_REG_PGA( CFG_PGA_64 ), SIZE_BYTE2 );
///写AD7124 配置2寄存器 64 ±39.06 mV
///双极性 | 打开ADC+缓冲 | 打开ADC-缓冲 | REF_SEL(x) x=2 外部REF1基准 | REG_PGA(AD7124_PGA_64) 6对应增益64(±39.06mV)
Ad7124_Write_Regs( AD7124_CFG1_REG, AD7124_CFG_REG_BIPOLAR
| AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM \
| AD7124_CFG_REG_REF_SEL( CFG_REF_REFIN1 ) | AD7124_CFG_REG_PGA( CFG_PGA_64 ), SIZE_BYTE2 );
///写AD7124 滤波寄存器0 sinc3+SIN1 快速模式 120 8.89Hz 以16为基数计算均值)
Ad7124_Write_Regs( AD7124_FILT0_REG, AD7124_FILT_REG_FILTER( FILT_FILTER_SINC3_SIN1 )\
| AD7124_FILT_REG_REJ60 | AD7124_FILT_REG_POST_FILTER( 0 ) | AD7124_FILT_REG_FS( 120 ), SIZE_BYTE3 );
///写AD7124 滤波寄存器1 sinc3+SIN1 快速模式 120 8.89Hz 以16为基数计算均值)
Ad7124_Write_Regs( AD7124_FILT1_REG, AD7124_FILT_REG_FILTER( FILT_FILTER_SINC3_SIN1 )\
| AD7124_FILT_REG_REJ60 | AD7124_FILT_REG_POST_FILTER( 0 ) | AD7124_FILT_REG_FS( 120 ), SIZE_BYTE3 );
Ad7124_Write_Regs( AD7124_IO_CTRL2_REG, AD7124_IO_CTRL2_REG_GPIO_VBIAS0, Ad7124Regs[AD7124_IO_CTRL2_REG].size );
}
因终端客户保密,发不了全部代码头文件及宏定义(这些宏定义就是寄存器配置参数值,请自行参考手册)。AD7124寄存器读写寄存用 STM32硬件SPI读取
实测K热电偶电压读取。 uV小数点后面丢弃。电压稳定在±1uV
转换成K热电偶温度,温度稳定在±0.01℃
实测 uV小数量点后面3位 ,实测数据波动 260nV. 与手册所写Sinc3 + Sinc1滤波器 SPS8.89配置 噪声0.036(RMS)X6.6=0.2376uV 结果比较接近。(当然用ADC自行读取,比不上示波器更精准)
Chapter2 24Bit Σ-Δ ADC——AD7124的多通道初始化配置
原文链接:https://blog.csdn.net/m0_46369352/article/details/127381641
一、前言
AD7124是目前常用的一种24位ADC,在全功率模式、9.4SPS的速率、gain = 128的状态运行,均方根(rms)可达到23nV;信号误差在±10uV左右,单片价格在¥135~150,对于测控仪器中采集芯片的选型来说,该芯片价位处于中端层面,性价比较高。
AD7124的引脚排布、硬件SPI的驱动方式我已经在上一篇文章发布过,这里不再做过多赘述,链接如下:
使用stm32的硬件SPI驱动AD7124的方法
二、ADC寄存器介绍
首先介绍一下AD7124几个常用寄存器的基本功能。我们以AD7124-4BRUZ为例,它有8个独立的设置,每个设置都包含了如下寄存器:
配置寄存器(Configuration register)
滤波寄存器(Filter register)
偏置寄存器(Offset register)
增益寄存器(Gain register)
1. 配置寄存器
配置寄存器允许用户选择ADC设置为双极性或单极性模式时的输出编码。
在双极性模式下,ADC可以采集到负电压,输出编码为偏移二进制(offset binary),采集范围是-VREF/gain ~ +VREF/gain
在单极性模式下,ADC只能采集正电压,输出编码为标准二进制(straight binary),采集范围是0 ~ +VREF/gain
在这两种情况下, 输入电压必须包含AVDD和AVSS。用户可以使用这些寄存器选择参考源,四个选项都是可用的:
1个内部2.5V参考源、1个连接REFIN1(+)和REFIN1(-)的外部参考源、1个连接REFIN2(+)和REFIN2(-)的外部参考源或以AVDD-AVSS作为参考。PGA提供了1、2、4、8、16、32、64和128倍增益。模拟输入缓存(buffer)和参考输入缓存都可以用寄存器使能。
下图为滤波寄存器0的寄存器位,Bit[15:12]是保留位,默认0;Bit11 =0为单极性,为1双极性;
2. 滤波寄存器
是一个24bit寄存器,滤波寄存器下选为数字滤波器被用于ADC调制器的输出。滤波器型号和数据输出速率在设置寄存器位时被选择。
最高3位是滤波器组数,可以用000-111代表Filter0-7;REJ60为60Hz开启数字抑制器位,写1开启,默认为50Hz抑制器;高8位的Bit[3:1]设置前置滤波器,Bit0为1开启单循环;中8位的Bit[7:4]为保留位,默认0,FS[10:8]至FS[7:0]是过滤器寄存器中要写进去的的十进制数,可以从1到2047。
不同的设置会影响输出数据速率、处理时间。
3. 偏置寄存器
增益寄存器是保持ADC增益校准系数的24位寄存器。增益寄存器是读/写寄存器。在gain=1时增益系数被校准;因此,默认值因设备而异。如果一个内部或系统全范围校准被用户初始化,默认值被自动覆写。更多信息,请看偏置滤波器部分。
4. 增益寄存器
AD7124-4有八个增益寄存器,从GAIN_0到GAIN_7。每个增益寄存器都与一个设置相关联,GAIN_x与设置x相关联。增益寄存器是24位寄存器,并保存ADC的满量程校准系数。AD7124-4的出厂校准增益为1。增益寄存器在上电和复位后包含这个工厂生成的值。
增益寄存器是读/写寄存器。
然而,当写入寄存器时,ADC必须处于待机模式或空闲模式。如果用户发起内部或系统满量程校准,则默认值将自动覆盖
或者写入满量程寄存器。
5. 诊断寄存器
又叫ERROR Registers,ERROR_EN寄存器可以使能或失能AD7124的众多诊断程序。默认下,SPI_IGNORE功能是使能的,这个位可以指示写ADC时不恰当的次数(例如,在上电和复位期间)其他诊断包括:
SPI读和写检查,确保只有合法的寄存器才能被访问
SCLK计数器,确保正确的SCLK脉冲数被使用
SCLK CRC校验
内存分布 CRC校验
LDO检查
当一个诊断被使能,在错误寄存器内包含相应的标志位。所有的使能标志位在状态寄存器内被命令去控制ERR flag。因此,如果发生一个错误(例如,SPI CRC校验检测到1个错误),在错误寄存器中有关的标志位会被设置(例如SPI_CRC_ERR标志位)。在状态寄存器中ERR标志位总是被置位的。ERR位表示是否发生错误。用户可以读取错误寄存器以获得关于错误源的更多信息。
三、通道与CONFIG_x的映射
图70是ADC配置寄存器与滤波、增益和偏置寄存器的关系,按照逻辑来说需要一步步地去配置,且他们之间存在几种不同的对应关系,不同的配置组合会对采样造成不同的影响,首先我们需要理解配置的灵活性(Flexibility)。
多对1映射
图71展示了CH0~CH3的通道配置,被称为Single Setup用灰色字体显示的寄存器暂时用不上。这4个差分通道均采用同一组配置寄存器,CONFIG_0的配置被4个通道共用。
Single Setup适合单通道采集,若不同的通道均采集同一范围的信号,也适用Single Setup。
下列代码展示了如何配置Single Setup:
void AD7124_Multiple_INIT(uint8_t SamHz)//多通道初始化函数
{
AD7124_Reset();
AD_Delay(500);
//写AD7124 控制寄存器
AD7124_Write_Reg(AD7124_ADC_CTRL_REG,2,AD7124_ADC_CTRL_REG_REF_EN | AD7124_ADC_CTRL_REG_POWER_MODE(3) | AD7124_ADC_CTRL_REG_MODE(0) | AD7124_ADC_CTRL_REG_CLK_SEL(0) | AD7124_ADC_CTRL_REG_CS_EN);
AD7124_Write_Reg(AD7124_CH0_MAP_REG,2,AD7124_CH_MAP_REG_CH_DISABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(0) | AD7124_CH_MAP_REG_AINM(1));
AD7124_Write_Reg(AD7124_CH1_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(2) | AD7124_CH_MAP_REG_AINM(3));
AD7124_Write_Reg(AD7124_CH2_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(4) | AD7124_CH_MAP_REG_AINM(5));
AD7124_Write_Reg(AD7124_CH3_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(6) | AD7124_CH_MAP_REG_AINM(7));
//写AD7124 配置0寄存器
AD7124_Write_Reg(AD7124_CFG0_REG,2,AD7124_CFG_REG_UNIPOLAR | AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM | AD7124_CFG_REG_REF_SEL(2) | \
AD7124_CFG_REG_PGA(7));
//单极性 | 打开ADC+缓冲 | 打开ADC-缓冲 | REF_SEL(x) x=0 REFIN1(+)/REFIN1(-) x=1 REFIN2(+)/REFIN2(-) x=2 内部基准电压源 x=3 AVDD
//REG_PGA(x) 0-7对应增益1(±2.5V) 2(±1.25V) 4(± 625mV ) 8(±312.5 mV ) 16(±156.25 mV) 32(±78.125 mV) 64(±39.06mV) 128(±19.53mV)
Samprate=SamHz;
switch(SamHz)
{
case Samprate_2Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(384));
break;
case Samprate_5Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(200));
break;
case Samprate_10Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(100));
break;
case Samprate_20Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(50));
break;
case Samprate_50Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(22));
break;
case Samprate_100Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(11));
break;
case Samprate_200Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(5));
break;
case Samprate_500Hz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(0) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(2));
break;
case Samprate_1kHz:
AD7124_Write_Reg(AD7124_FILT0_REG,3,AD7124_FILT_REG_FILTER(2) | AD7124_FILT_REG_REJ60 | \
AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(1));
break;
}
}
注意观察被红框标注的部分,AD7124_CH_MAP_REG_SETUP(0)代表地址0x19;AD7124_CH_MAP_REG_SETUP(x)和AD7124_CFGx_REG之间,"x"的数字必须匹配,否则采集到的信号会是全F。
1对1映射
//函数: 多通道初始化函数,初始1号AD7124的1-3通道
//变量: 无
//返回值: 无
void AD7124_Multiple_INIT(void)//多通道初始化函数
{
AD7124_Reset();
AD_Delay(500);
//写AD7124 控制寄存器
AD7124_Write_Reg(AD7124_ADC_CTRL_REG,2,AD7124_ADC_CTRL_REG_DATA_STATUS | AD7124_ADC_CTRL_REG_REF_EN | AD7124_ADC_CTRL_REG_POWER_MODE(3) | AD7124_ADC_CTRL_REG_MODE(0) | AD7124_ADC_CTRL_REG_CLK_SEL(0) | AD7124_ADC_CTRL_REG_CS_EN);
//通道指示 | 内部参考打开 | POWER_MODE(x) x=0 低功耗 x=1 中功率 x=2、3全功率 | CTRL_REG_MODE(x) x=0 连续转换模式 x=1 单次转换模式 其他模式请看手册 | CLK_SEL(x) x=0 内部 x=2 外部
//写AD7124 通道0寄存器,0号通道不开启
//使能通道0 | 用配置0 | AINP(x) ADC+选择 0-15对应通道0-15 | AINM(x) ADC-选择 0-15对应通道0-15 其他通道请查看手册
AD7124_Write_Reg(AD7124_CH0_MAP_REG,2,AD7124_CH_MAP_REG_CH_DISABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(0) | AD7124_CH_MAP_REG_AINM(1));
//写AD7124 通道1寄存器
//使能通道1 | 用配置1 | AINP(x) ADC+选择 0-7对应通道0-7 | AINM(x) ADC-选择 0-7对应通道0-7 其他通道请查看手册
AD7124_Write_Reg(AD7124_CH1_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(1) | AD7124_CH_MAP_REG_AINP(2) | AD7124_CH_MAP_REG_AINM(3));
//写AD7124 通道2寄存器
//使能通道2 | 用配置2 | AINP(x) ADC+选择 0-7对应通道0-7 | AINM(x) ADC-选择 0-7对应通道0-7 其他通道请查看手册
AD7124_Write_Reg(AD7124_CH2_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(4) | AD7124_CH_MAP_REG_AINM(5));
//写AD7124 通道3寄存器
//使能通道3 | 用配置3 | AINP(x) ADC+选择 0-7对应通道0-7 | AINM(x) ADC-选择 0-7对应通道0-7 其他通道请查看手册
AD7124_Write_Reg(AD7124_CH3_MAP_REG,2,AD7124_CH_MAP_REG_CH_ENABLE | AD7124_CH_MAP_REG_SETUP(0) | AD7124_CH_MAP_REG_AINP(6) | AD7124_CH_MAP_REG_AINM(7));
//写AD7124 配置1寄存器
AD7124_Write_Reg(AD7124_CFG1_REG,2,AD7124_CFG_REG_UNIPOLAR | AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM | AD7124_CFG_REG_REF_SEL(2) | \
AD7124_CFG_REG_PGA(7));
//单极性 | 打开ADC+缓冲 | 打开ADC-缓冲 | REF_SEL(x) x=0 REFIN1(+)/REFIN1(-) x=1 REFIN2(+)/REFIN2(-) x=2 内部基准电压源 x=3 AVDD
//REG_PGA(x) 0-7对应增益1(±2.5V) 2(±1.25V) 4(± 625mV ) 8(±312.5 mV ) 16(±156.25 mV) 32(±78.125 mV) 64(±39.06mV) 128(±19.53mV)
//写AD7124 配置2寄存器
//单极性 | 打开ADC+缓冲 | 打开ADC-缓冲 | REF_SEL(x) x=2 内部基准电压源 | REG_PGA(6) 6对应增益64(±39.06mV)
AD7124_Write_Reg(AD7124_CFG2_REG,2,AD7124_CFG_REG_UNIPOLAR | AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM | AD7124_CFG_REG_REF_SEL(2) | \
AD7124_CFG_REG_PGA(6));
//写AD7124 配置3寄存器
//单极性 | 打开ADC+缓冲 | 打开ADC-缓冲 | REF_SEL(x) x=2 内部基准电压源 | REG_PGA(5) 5对应增益32(±78.125 mV)
AD7124_Write_Reg(AD7124_CFG3_REG,2,AD7124_CFG_REG_UNIPOLAR | AD7124_CFG_REG_AIN_BUFP | AD7124_CFG_REG_AINN_BUFM | AD7124_CFG_REG_REF_SEL(2) | \
AD7124_CFG_REG_PGA(5));
//写AD7124 滤波寄存器1 500Hz
//FILTER(x)x=0 sinc4 x=2 sinc3 x=7 后置滤波器 其他请查看手册 | 打开60Hz陷波 | POST_FILTER(x) 后置滤波器设置查看手册 | FS(x)具体滤波配置查看网址
AD7124_Write_Reg(AD7124_FILT1_REG,3,AD7124_FILT_REG_FILTER(2)|AD7124_FILT_REG_REJ60|AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(2));
//写AD7124 滤波寄存器2 500Hz
//FILTER(x)x=0 sinc4 x=2 sinc3 x=7 后置滤波器 其他请查看手册 | 打开60Hz陷波 | POST_FILTER(x) 后置滤波器设置查看手册 | FS(x)具体滤波配置查看网址
AD7124_Write_Reg(AD7124_FILT2_REG,3,AD7124_FILT_REG_FILTER(2)|AD7124_FILT_REG_REJ60|AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(2));
//写AD7124 滤波寄存器3 500Hz
//FILTER(x)x=0 sinc4 x=2 sinc3 x=7 后置滤波器 其他请查看手册 | 打开60Hz陷波 | POST_FILTER(x) 后置滤波器设置查看手册 | FS(x)具体滤波配置查看网址
AD7124_Write_Reg(AD7124_FILT3_REG,3,AD7124_FILT_REG_FILTER(2)|AD7124_FILT_REG_REJ60|AD7124_FILT_REG_POST_FILTER(0) | AD7124_FILT_REG_FS(2));
}
混合映射
配置原理和上述相同,不同的是AIN6/AIN7可以被配置到CHANNEL2,也就是说3号通道可以被被知道通道1的寄存器上,
四、实验数据
下列是几个不同通道,设置不同组Config后采集的数据(照片拍得有点糊,见谅……),2通道使用CINFIG_1的配置,3通道使用CONFIG_2,而PT1000的通道采用CONFIG_0。
在实际应用中,不同的通道应配置不同的组数,以防配置信息代码产生耦合。
Chapter3 STM32的硬件SPI驱动AD7124的方法
原文链接:https://blog.csdn.net/m0_46369352/article/details/125237380
一、芯片介绍
AD7124是一款适合高精度测量应用的低功耗、低噪声、完整模拟前端。该器件内置一个低噪声24位Σ-Δ型模数转换器(ADC),可配置来提供8个差分输入或15个单端或伪差分输入。片内低噪声级确保ADC中可直接输入小信号。可用于温度测量、压力测量、工业过程控制、仪器仪表和只能发射器。
二、引脚排布
AD7124的接口属于标准4线SPI,DOUT是从设备输出至主设备的,连接单片机SPI模块的MISO(主输入从输出);DIN是主设备数据输出至从设备的,连接单片机SPI模块的MOSI(主输出从输入)。SYNC和CLK悬空。
本项目我们使用SPI2模块。
三、时序图与驱动程序
调试数字设备,我们需要一边查看技术手册的时序图写代码,一边挂上逻辑分析仪。
1. 芯片初始化
我们打开AD7124的DataSheet,对其时序图进行分析,如下:
下图为AD7124的单次和连续转换时序图,由图可知,SCLK在空闲状态下是高电平。
下图是AD7124的读&写时序图,无论是读时序还是写时序,均在第二个时钟沿进行数据转换。
所以AD7124初始化时,需要将SPI模式设置为时钟悬空高、数据捕获于第2个时钟沿
void AD7124_SPI_Config(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_12);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主机
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //发送接收8位帧结构
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //时钟悬空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //数据捕获于第2个时钟沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信号由软件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定义波特率预分频的值:波特率预分频值为256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //数据传输从MSB位开始
SPI_InitStructure.SPI_CRCPolynomial = 0; //CRC值计算的多项式
SPI_Init(SPI2, &SPI_InitStructure); //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
SPI_Cmd(SPI2, ENABLE);
AD7124_CS_H; //片选拉高,失能AD7124
}
2. SPI读写函数
SPI读写是驱动SPI设备的基础。SPI的原理为
第一步:通过硬件或软件NSS拉低从设备片选(CS),使能从设备。
第二步:通过MOSI引脚,发送8个时钟周期,每个周期发送1个bit的数据;通过写入不同的地址,来决定对从设备的读操作/写操作。
第三步:8个倍数的时钟周期发送完毕后,拉高片选,结束“发送/接收数据”。
这里我们把读和写都放在一个函数里面,因为SPI如果只读取,都需要发送8个时钟周期和指令0XFF。
/**
* @brief AD7124的读写SPI操作
* @param Data : 需要传输的数据
* @retval SPI读到的数据
*/
uint8_t AD7124_SPI_ReadWrite(uint8_t Data)
{
uint16_t retry=0;
//超时等待
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, Data); //MOSI主机发送给从机
retry=0;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //MISO接收从机数据
}
3. AD7124复位
芯片上电初始化前,必须复位才能使用。
CS = 0 和 DIN = 1 的 64 个 SCLK。这会复位 ADC 和所有寄存器内容。也就是说,只要在AD7124 CS拉低的期间,在64个时钟周期内MOSI不断输出高电平,即可复位。代码如下:
void AD7124_Reset(void)
{
AD7124_CS_L;
//提供大于64个写操作,复位AD7124
for(uint8_t a=0; a<9; a++)
{
AD7124_SPI_ReadWrite(0XFF); //MOSI拉高
}
delay_us(60);
AD7124_CS_H;
}
加入延时delay_us()的目的是,防止在硬件SPI还未发送完最后几个时钟周期,CS提前拉高,造成复位失败。在读写操作中,同样加入了延时处理。
逻辑分析仪采集到的波形如下:
AD7124读取ID
复位完成后需要读取芯片的ID号,不同封装的ID号也不同,AD7124-4通常为0x14,而AD7124-8是0x12或0x04。SPI写入命令0x40为读寄存器,读ID为0x05,故写入0x45就可以读出ID。
0x40是发送读取ID指令返回的字节,0x14是ID号。
AD7124写入配置
写入配置需要根据写时序图编写,读时序如下
我们复位后先对ADC_CTRL进行操作,以开启ADC控制寄存器,AD7124_ADC_CTRL_REG地址是0X01,如下图DIN的第一个Byte,之后再把2字节的配置信息依次写入,这个根据用户需求配置,不在赘述。
通道和内置滤波器配置方法相同。
读取数据
本次实验我们采用单次读取模式。在读取数据之前先要写入命令0x42,之后需要读取多少个Byte的字节,就修改形式参数byte的数量即可。读取一次单次采集到的数据,需要3次SPI读写(24个时钟周期),DIN输出全高即可读取。
uint32_t DATA=0;
uint32_t Rd_Ary[3];
uint32_t AD7124_Read_Data(uint8_t byte)
{
for(uint8_t i=0; i<byte; i++)
{
Rd_Ary[i] = AD7124_SPI_ReadWrite(0xFF);
}
DATA = (Rd_Ary[0]<<16) + (Rd_Ary[1]<<8) + Rd_Ary[2];
return DATA;
}
主函数读取代码如下:
while(1)
{
AD7124_CS_L;
AD7124_SPI_ReadWrite(0x42); //读操作
Data = AD7124_Read_Data(3); //Data采集结果
AD7124_CS_H;
data_temp = Data;
data_last1 = (float)Vref/AD_Gain * (float)data_temp/(2*0X800000); //单极性模式电压转换公式,单位mV
// data_last1 = (float)Vref/AD_Gain * ((float)data_temp/0X800000-1); //双极性模式电压转换公式,单位mV
data_last1 = data_last1 * 1000.0f; //转换为uV
printf("%X\r\n", Data); //打印原始16进制数据
printf("%2f uV\r\n", data_last1); //打印微伏
delay_ms(100);
}
让我们采集11mV的直流信号,下图分别为实际测量和逻辑分析仪读取到的数据,为0x928D11。
为了验证数据是否正确,我们查看此次串口读取到的值:
原16进制数据读取正确,万用表实际测量11.0mV,实际读取值为11.180mV,误差在±100~200uV。因为信号发生器的线过长,影响了此次的精度。在PCB Layout时,尽可能将ADC输入的线路缩短,且圆弧布线,可以有效降低误差。
资料链接
代码可以在此处下载:
链接: https://download.csdn.net/download/m0_46369352/85612772
Chapter4 AD7124的调试总结
原文链接:https://blog.csdn.net/weixin_44224303/article/details/121940545
AD7124芯片的调试闭坑总结
AD7124的评估板资料 https://www.analog.com/media/en/technical-documentation/user-guides/EVAL-AD7124-8SDZ_UG-856.pdf
1、SPI通讯速率尽量不要大于5M,但是实测,短线情况下9M通讯正常。
2、SYNC引脚一定要拉高,拉低的话不转换。
(之前我的电路,本引脚直接悬空,我本来调通了,然后运行了几天,居然停止转换了,实际读寄存器,都是正常的,检查电路也没有损坏,多放查找,这个引脚需要拉高才行,在官方的评估板资料里,也是这样接的,MGR坏得很,说明书里面并没说,如下图)。
3、无法通过ADC_CONTROL寄存器控制内部基准
有好多网友用官方驱动发现无法通过ADC_CONTROL寄存器控制内部基准,设置完以后,读取其他寄存器数据正常,唯独该寄存器读取为0.解决方法:寄存器写入的时候前后加10ms左右即可,太快会导致control寄存器写入失败。具体原因没有深究。所以对芯片初始化完成后务必要重新读取寄存器看是否写入成功。
4、注意选择参考电压
如果选择外部参考电压,首先保证外部连接了外部基准;如果选择内部基准,要保证ADC_CONTROL寄存器里把内部基准电压打开。否则的话转换会失败,结果出错。为了测试方便刚开始可以选择AVDD为基准。
5、REFOUT引脚,需要对地接一个0.1uF电容,否则会出问题。
(这个我也是在网上看的,出什么问题,我也忘了,但是我记得,确实必须接0.1uF电容。在官方的评估板里,也是这样接的,MGR坏得很,说明书里面并没说,如下图)
6、在初始化写入AD7124寄存器前,最好一定读一次状态寄存器,否则可能写入寄存器失败。
我在使用中,AD7124-8就不用读状态寄存器,每次AD重新上电,或者只是MCU重启,都能写入寄存器数据;但是同样的程序,只是芯片换成AD7124-4,就不许,后发现只要读一次状态寄存器,就正常了。实际就是读状态寄存器,清除上电复位标志。
7、测内部20mV信号时,请断开外部AI连接,否则可能AD芯片死机
AI引脚可以配置为读取内部20mv信号,我配置成读内部20mv信号,基准也采用内部基准2.5V(可以配置内部基准从REFOUT输出,我测量过,确实比较准),计算得出应该是18.9mv,也有网友说是就18mv,看来这一点和官方数据有点出入,不过也不算什么了,还需要注意的是,测内部20mV信号时,请断开外部AI连接,否则可能AD芯片死机。
8、精度问题
按官方文档,最高也就能到22位精度。我用本芯片做RTD测量电路,感觉也就能达到18位精度而已,这一点和官方文档说法其实还是比较吻合的了。更多精度分析,请看我另一篇文章。总体来讲,精度可达21至22位。
9、AD工作模式及校准
连续转换模式(默认):就是一直转换
单次转换模式: 当ADC_CONTROL寄存器配置为单次模式,就对当前通道进行一次转换,然后转入待机模式。我拿来做了低功耗,需要测量时,就配置成单次转换模式,然后就不用管AD芯片了,它转换完会自动进入待机模式。
待机模式: 寄存器内容会保持,具体看说明书吧,我只说一点,待机模式时,激励电流源会自动关断(不会修改IO_CONTROL_1寄存器内容,不要理解错了)。
关断模式: 全部功能关闭,寄存器会复位,退出关断模式时,所有寄存器必须重新编程。
空闲模式: 在内部零电平(失调)校准、系统零电平(失调)校准完成后,会自动进入空闲模式,(除失调寄存器外)寄存器内容不会改变。
内部满量程(增益)校、零电平(失调)校准: 这两种模式,一般都是要同时执行的,一般不会单独只执行一个。所谓内部校准,就是在芯片内部,将 AI 输入端正负,分别与基准REF正负端短接,然后得出内部的偏移值、或定值。
执行 内部满量程(增益)校、零电平(失调)校准的过程:如果是单通道模式,先把其他寄存器配置好(如果不是单通道模式,那就一个一个通道的关闭吧),设置为 中功率 --> 空闲模式 --> 对应通道失调寄存器 写入0x800000(或上电复位值本身就是) --> 设置为 内部满量程(增益)校准模式 --> 校准完成自动进入空闲模式 --> 设置为 内部零电平(失调)校准 --> 校准完成自动进入空闲模式; 应当在校准完成后,读取 失调寄存器、增益寄存器的值,保存起来,然后以后上电、重启后,应在设置为 空闲模式/待机模式 时,才准写入这二个寄存器的值。
系统校准,也就是外部校准,需要在外部手动短接零电平 或 满量程电平,不过不需要设置 空闲模式、中功率那些,按理说,外部校准应该比内部校准准确度更好。
满量程校准,会重新设置 增益寄存器的值,零电平校准,会设置 失调寄存器的值。
10、REFIN(+) 与 REFIN(-)之差的范围是 1V到3.3V ,这个一定要注意,低于1V,芯片可能会不转换,这个问题折磨了我很久。
并且就算转换,也会导致精度不稳定。。我做RTD测量时,选定过2K电阻,横流500uA,刚好1V,实际测试中,刚开始没问题,一二个小时、几小时、几十小时后,芯片会停止转换,一会行一会不行。
11、在实际使用过程中,注意 AI通道的对AVSS的绝对电压范围
在实际使用过程中,注意 AI通道的对AVSS的绝对电压范围,REFIN(+) (-) 对AVSS的绝对电压范围,恒流输出通道对对AVSS的绝对电压范围,这个请查看手册参数。
12、电源问题:AVSS 与 IVSS ,最好单独供电,
电源问题:AVSS 与 IVSS ,最好单独供电,比如用2个LDO电源分开供电, 我是直接用了2个独立的隔离电源3.3V。在我最开始使用时,采用1个3.3V给AVSS和 IVSS一起供电,直接连接在一起,并且有1mA的恒流输出,运行一段时间后(可能是几天),测电流变成了0.2mA了,好像恒流源坏掉了,重启也是0.2mA;虽然是不是AVSS和 IVSS共同供电导致,无从考证,但是可以想象,这种同时供电,又有恒流输出,极有可能会影响到内部的供电问题;并且说明书上也有建议,有条件的话,最好单独供电。并且我采用单独供电后,就没再出现过这种情况了。
13、还是紧接着电源问题
当我用2个独立电源时,最开始,我买错了电源芯片,导致用了2个3.6V给AD芯片供电,然后MCU与其通信,好像没有什么问题,然后用了1天后,就开始通信故障,经过我反复不停重复,发现居然报了ROM故障(AD7124的ERR寄存器)。重启,或者MCU重新配置后,又可以用一段时间了。后面这颗芯片就算采用3.3V供电了,还是会出问题。最后,我采用了新的芯片+2个3.3V电源,就再没出现过了。很显然,这个问题就是3.6V供电造成的。。。
综上所述,可见该芯片,并没有想象中那么NB。