AD7190之STM32程序——STM32测试高精度ADC篇(三)

来源:互联网 发布:js判断等于0 编辑:程序博客网 时间:2024/05/29 04:22

1.  AD7190概述


        AD7190是一款适合高精密测量应用的低噪声完整模拟前端。它集成一个低噪声、24位Σ-Δ型模数转换(ADC)。片内低噪声增益级意味着可直接输入小信号。

        这款器件可配置为两路差分输入或四路伪差分输入。片内通道序列器可以使能多个通道,AD7190按顺序在各使能通道上执行转换,这可以简化与器件的通信。片内4.92 MHz时钟可以用作ADC的时钟源;或者,也可以使用外部时钟或晶振。该器件的输出数据速率可在4.7 Hz至4.8 kHz的范围内变化。

        这款器件提供两种数字滤波器选项。滤波器的选择会影响以编程输出数据速率工作时的均方根噪声和无噪声分辨率、建立时间以及50 Hz/60 Hz抑制。针对要求所有转换均需建立的应用,AD7190具有零延迟特性。该器件采用5 V模拟电源和2.7 V至5.25 V的数字电源供电,功耗为6mA,提供24引脚TSSOP封装。

        AD7190性价比很高,出货量大,用量也很大,供货很稳定,非常适用于中低速高精度的测试,如电子秤、应变计、气体分析、仪器仪表、压力传感器、血液分析、工业过程控制、医疗科学仪器等应用。本人对AD7190做了一次比较测试,分享下测试的结果


2.  硬件设计分析




           从结构图可以看出来,AD7190是模拟区域与数字区域完全独立的ADC,即AVDD给模拟区域供电,DVDD给数字区域供电,在原理图设计方面按照官方指导文档,需要对两个区域做独立的布线与隔离处理,才能让信噪比最佳。另可靠的基准电压是高精度ADC命根,本次试验选择TI公司推出的REF5025作基准参考,REF5025可低于3µVpp/V 噪声、3ppm/°C 漂移,性能是十分出色的。



        由于经常做高频类项目,十分讨厌杜邦线/飞线测试方式,在高精度的领域,24位ADC梯度值2的2416777216,如果接入基准电压是2.5v,理论分辨率可达到0.149μV,做过高频的工程师深知杜邦线的罪恶,根据上面的技术分析,哪怕线路被引入1μV的干扰,也可以让精度打上一定折扣。为了让ADS1232性能得以充分体现,特意做了一个测试载板,载板的设计也是很关键,分割模拟数字区域同时,连接地方大量使用钽电容做旁路电路,以把波纹抑制到最小,合理的布局与布线也很重要,敷铜区域也需要模数分离,以磁珠或者0-5R/电感隔开。





3.  时序图解说





        由时序图看出来,AD7190读写是简单的3线串行读数方式,属于Microwire串行接口,STM32的SPI接口可以完美的与之匹配,当然也可以采用软仿SPI替代STM32的硬件SPI,这样的程序更具移植性。SPI时序实现也相对简单,AD7190的CS线仅仅只是做片选使用(上图所示),而不用过多管理,保持低电平即可。特别需要注意的是在空闲时候,SCLK时钟信号需要保持高电平,在SCLK半个周期当DIN接收到0x58后转换的数据才传入到DOUT总线,这时候才能读取数据。从时序图上看,与AD7799十分类似的,只是延时上要稍做一些处理。


4.  核心源码


//寄存器列表#define ComState_register               (0)<<3#define Mode_register          (1)<<3#define Config_register          (2)<<3#define Data_register           (3)<<3#define ID_register    (4)<<3#define GPOCON_register                (5)<<3#define Disorders_register              (6)<<3#define FullScale_register              (7)<<3//模式寄存器#define MODE_ADC_OneByOne         (0)<<21#define MODE_ADC_OnlyOne (1)<<21#define MODE_ADC_Free (2)<<21#define MODE_ADC_SavePower         (3)<<21#define MODE_ADC_AdjustZero             (4)<<21#define MODE_ADC_AdjustFull             (5)<<21#define MODE_ADC_SysAdjustZero          (6)<<21#define MODE_ADC_SysAdjustFull          (7)<<21#define MODE_MCLK_OUTosc(0)<<18#define MODE_MCLK_OUTclo(1)<<18#define MODE_MCLK_IN(2)<<18#define MODE_MCLK_INcloOut        (3)<<18#define MODE_SINC3(1)<<15#define MODE_ENPAR(1)<<13#define MODE_Single(1)<<11#define MODE_REJ60(1)<<10//#define MODE_Filter_Speed0//配置寄存器#define Config_Chop_EN(1)<<23#define Config_REFSEL_IO(1)<<20#define Config_Burn_EN(1)<<7#define Config_REFDET_EN(1)<<6#define Config_BUF_EN(1)<<4#define Config_UB_EN(1)<<3#define Config_Ch0_A1A2(1)<<8#define Config_Ch1_A3A4(1)<<9#define Config_Ch2_temp(1)<<10#define Config_Ch3_A2A2(1)<<11#define Config_Ch4_A1AC(1)<<12#define Config_Ch5_A2AC(1)<<13#define Config_Ch6_A3AC(1)<<14#define Config_Ch7_A4AC(1)<<15#define Config_ADC_Gain_10#define Config_ADC_Gain_83#define Config_ADC_Gain_164#define Config_ADC_Gain_325#define Config_ADC_Gain_646#define Config_ADC_Gain_1287typedef struct {u32 ADC_Mode;u32 Return_state;u32 ADC_SCLK;u32 SINC3_EN;u32 ENPAR;u32 Single_EN;u32 REJ60_EN;u32 Filter;}AD7190_MODE_SET;typedef struct {u32 Config_Channel;u32 Config_ADC_Gain;u32 Config_Chop;//斩波使能u32 Config_REFSEL;u32 Config_Burn;u32 Config_REFDET;u32 Config_BUF;u32 Config_UB;}AD7190_Config_SET;//基本配置void AD7190_config(void){AD7190_MODE_SET     Mode;AD7190_Config_SET   Config;Config.Config_Channel=Config_Ch1_A3A4;Config.Config_ADC_Gain=Config_ADC_Gain_1;Config.Config_Chop=1;Config.Config_REFSEL=0;Config.Config_Burn=0;Config.Config_REFDET=1;Config.Config_BUF=0;Config.Config_UB=1;Mode.ADC_Mode=MODE_ADC_AdjustZero;Mode.Return_state=0;Mode.ADC_SCLK=MODE_MCLK_IN;Mode.SINC3_EN=0;Mode.ENPAR=0;Mode.Single_EN=0;Mode.REJ60_EN=0;Mode.Filter=1;}//读取转换值void ReadAD7190(unsigned char count, unsigned char *buf){unsignedchari = 0;unsignedcharj = 0;unsignedchar  RotateData = 0;SET_SCL();delay_us(1);SET_CS();delay_us(1);CLR_CS();delay_us(1);for(j=count; j>0; j--){for(i=0; i<8; i++){    CLR_SCL();RotateData <<= 1;delay_us(1);RotateData |= GP0DAT;SET_SCL();delay_us(1);}*(buf + j - 1)= RotateData;RotateData=0;} SET_CS();}//初始化:void AD7799_INIT(void){    unsigned long command;    command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);    command &= ~AD7799_CONF_GAIN(0xFF);    command |= AD7799_CONF_GAIN(1);     AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);    AD7799_SetReference();    command = AD7799_GetRegisterValue(AD7799_REG_CONF,2);    command &= ~AD7799_CONF_CHAN(0xFF);    command |= AD7799_CONF_CHAN(2);     AD7799_SetRegisterValue(AD7799_REG_CONF,command,2);    command = AD7799_GetRegisterValue(AD7799_REG_MODE,2);    command &= ~AD7799_MODE_SEL(0xFF);    command |= AD7799_MODE_SEL(0);// 连续转换模式    AD7799_SetRegisterValue(AD7799_REG_MODE,command,2);}//读数程序:while (1){adcbuf=ADC_Num();if(ADC_Channel==1)//see datasheet AIN3 AIN4{adcA3A4[i++]=adcbuf;if(i>Num){i=0;adcA3A4value=GetAverage(adcA3A4,Num);AD7190_DataFormatting(adcA3A4value , 2.5 ,1);DataLCD(AD7190_DataFormatting(adcA3A4value , 2.5 ,1));}}}


5.  测试结果




        测试源是1.25v基准输出电压值,实际加入电压是:1.25000000v(8位半表实测),通过误差曲线的分析,摆幅稳定在2-8µV,效果还是很理想的。官方测试条件Gain=128,VREF=5V,下图是手册提供噪音图(Y轴单位LBS),在4.7Hz采样时候只有12个LBS的波动,但是在4.8kHz采样时候有将近450个LBS的波动,频率采集快了,会有一定失真,这是所有AD转换芯片的通病,当然阻抗匹配也有一定的原因。因此在使用前零度和满度校准是十分必要的。



6.  总结

           作为一款中低速高精度的ADC,AD7190有着4.8kHz的转换频率,两路差分输入或四路伪差分输入,是个不错的选择,相比于AD7799虽然价格略高一些,但是他比AD7799的性能提高不少,特别是采样速率,测试看来,超高的性价比和出色的性能让它在同级别的ADC中也有很强的竞争能力。欢迎大家多交流技术,Q Q:1625874998,可提供部分资料,供大家设计参考。



原创粉丝点击