完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用AD5934测量阻抗,电路和软件参照CN-0349设计
使用2点校准: Low range: μS to mS, R FB = 1 kΩ, R CAL =1 kΩ and 10 kΩ 这时测量1k、10k都是准确的,但测量2端和中间的阻值就偏差太大,例如:20k飘向50k+,15k飘向30k左右,12k飘向20k左右,看着这数据心哇凉哇凉的。 High range: mS to S, R FB = 100 Ω, R CAL = 100 Ω and 1 kΩ 同样是2个校准的OK,其它点都不行 ///////////////////////////////////Conductivity.h[size=13.3333330154419px]/////////////////////////////////// #ifndef __CONDUCTIVITY_H #define __CONDUCTIVITY_H #include "STM32l1xx.h" void TAST_COND(void); void Cond_Control(void* p); ErrorStatus SendFrame(u16 ADDR,u8 *buff,u8 len,u8 timeout); //ErrorStatus SendFrame(u8 *buff,u8 len,u8 timeout); void Receive_ADG715_AD5934(u8 ADDR,u8 regAddr,u8 *buff,u8 len); void Set_ADG715_Channel(u8 *Channel); void Write_AD5934_Register(u8 *Buff,u8 Len); void AD5934_Init(void); void Calculation_Gain_Factor(double Gain_Factor); float Read_Magnitude( void); void Adjust_AD5933(void); float Liner_Calbration(float Magnitude,u8 Channel); //void Change_AdjustChannel(u8 range); void Mul_Receive_AD5934(u8 ADDR,u8 regAddr,u8 *buff,u8 len); #endif [size=13.3333330154419px]/////////////////////////////////// Conductivity.c[size=13.3333330154419px]/////////////////////////////////// #include "Conductivity.h" #include "MB_Core.h" #include "SystemConfig.h" #include "i2c.h" #include "math.h" #include "uarts.h" #include "DataHandle.h" #include "flash_add.h" #define STK_COND_SIZE 256 #define I2C_CLOCK_Speed 100000 #define I2C2_ADDr 0x0001 #define ADG715_ADDr 0x48 //1001 0 00 #define AD5934_ADDr 0x0D //1010 0000 /***AD5934寄存器**/ #define Control_Low 0x80 #define Control_High 0x81 #define Start_Frequency_Low 0x82 #define Start_Frequency_Mid 0x83 #define Start_Frequency_High 0x84 #define Frequency_Increment_Low 0x85 #define Frequency_Increment_Mid 0x86 #define Frequency_Increment_High 0x87 #define Num_Increments_Low 0x88 #define Num_Increments_High 0x89 #define Num_TimeCyles_Low 0x8a #define Num_TimeCyles_High 0x8b #define Status_Register 0x8f #define Real_Data_Low 0x95 #define Real_Data_High 0x94 #define Imaginary_Data_Low 0x97 #define Imaginary_Data_High 0x96 #define Range_Quantity 2 #define Calibration_Range1_High_Set 0x22 #define Calibration_Range1_Low_Set 0x42 #define Calibration_Range2_High_Set 0x11 #define Calibration_Range2_Low_Set 0x21 #define Calibration_Range3_Low_Set 0x00 #define Calibration_Range3_High_Set 0x00 #define Range1_Measure_Channel 0x02 #define Range2_Measure_Channel 0x01 #define CalibrationRange1_Low_Conductivity 0.0001 //单位为西门子 #define CalibrationRange1_High_Conductivity 0.001 #define CalibrationRange2_Low_Conductivity 0.001 #define CalibrationRange2_High_Conductivity 0.01 typedef struct Register_AD5933 { u8 Register; u8 DATA; }Register_AD5933_Write; typedef struct Calibration_Magnitude { float Magnitude_FirstPoint; float Magnitude_SecondPoint; }Calibration_Magnitude_Read; typedef struct Calibration_Range_Num { Calibration_Magnitude_Read Magnitude_Range_First; Calibration_Magnitude_Read Magnitude_Range_Second; Calibration_Magnitude_Read Magnitude_Range_Third; }Calibration_Range_Magnitude; Calibration_Range_Magnitude Calibration_Range; Register_AD5933_Write Register_Data[15] = { /*{Control_High ,0x10}, // Transmit to start frequency register // program 30khz start frequency assuming exteral osc of 16Mhz {Start_Frequency_High,0x28}, {Start_Frequency_Mid,0x5c}, {Start_Frequency_Low,0x0f}, // Transmit to frequency increment register // program 1Khz frequency increment assuming exteral osc of 16Mhz {Frequency_Increment_High,0xf6}, {Frequency_Increment_Mid,0xc1}, {Frequency_Increment_Low,0x00}, // Transmit to NUMBER OF INCREMENTS register // program 10 frequency increments {Num_Increments_High,0x0A}, {Num_Increments_Low,0x00}, // Transmit to settling time cycles register // program 15 output cycles at each frequency before a adc conversion {Num_TimeCyles_High,0x28}, {Num_TimeCyles_Low,0x00}, // {Control_Low,0x11}, // Transmit to CONTROL register // place the AD5933 in standby mode {Control_Low,0xb0}, // Choose the exteral system clock {Control_High,0x08}, // Choose range 1 (2vp-p, 1.6v) PGA = x1 {Control_Low,0x03}, // initialise the sensor with contents of start frequency regsister with range 1 (2vp-p, 1.6v) PGA = x1 {Control_Low,0x10}, // start of frequency sweep (2vp-p, 1.6v) PGA = x1 {Control_Low,0x20},*/ // Transmit to start frequency register // program 30khz start frequency assuming exteral osc of 16Mhz {Start_Frequency_High,0x45}, {Start_Frequency_Mid,0xA6}, {Start_Frequency_Low,0x0E}, // Transmit to frequency increment register // program 1Khz frequency increment assuming exteral osc of 16Mhz {Frequency_Increment_High,0x02}, {Frequency_Increment_Mid,0x7D}, {Frequency_Increment_Low,0x00}, // Transmit to NUMBER OF INCREMENTS register // program 10 frequency increments {Num_Increments_High,0x0A}, {Num_Increments_Low,0x00}, // Transmit to settling time cycles register // program 15 output cycles at each frequency before a adc conversion {Num_TimeCyles_High,0x0F}, {Num_TimeCyles_Low,0x00}, // {Control_Low,0x11}, // Transmit to CONTROL register // place the AD5933 in standby mode {Control_Low,0xB0}, // Choose the exteral system clock {Control_High,0x00}, // Choose range 1 (2vp-p, 1.6v) PGA = x1 {Control_Low,0x01}, // initialise the sensor with contents of start frequency regsister with range 1 (2vp-p, 1.6v) PGA = x1 {Control_Low,0x10}, // start of frequency sweep (2vp-p, 1.6v) PGA = x1 {Control_Low,0x20}, }; static OS_STK STK_COND[STK_COND_SIZE]; void TAST_COND(void) { OSTaskCreate(Cond_Control,(void*)0,&STK_COND[STK_COND_SIZE-1],PRIO_TASK_COND); } //float Conductivity_Measure = 0; void Cond_Control(void* p) { // u8 Buff[2]; // u8 i = 0; float Magnitude = 0; u8 Buff_ADG715_Channel; u8 flag_Led=0; u8 startSweep[2] = {0x80, 0x41}; // I2C_Comm_Init(I2C2,I2C_CLOCK_Speed,0xa0); //I2C初始化 AD5934_Init(); Adjust_AD5933(); // Buff_ADG715_Channel = Calibration_Range1_High_Set; // Set_ADG715_Channel(&Buff_ADG715_Channel); Buff_ADG715_Channel = Calibration_Range1_High_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); Buff_ADG715_Channel = Range1_Measure_Channel; // SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); // OSTimeDlyHMSM(0,0,0,100); while(1) { Magnitude = Read_Magnitude(); Probe_Value.Conductivity_Measure = Liner_Calbration(Magnitude,Buff_ADG715_Channel); if(flag_Led==0) { GPIO_SetBits(GPIOH,GPIO_Pin_2); flag_Led = 1; } else { GPIO_ResetBits(GPIOH,GPIO_Pin_2); flag_Led = 0; } if(Probe_Value.Conductivity_Measure<=0) Probe_Value.Conductivity_Measure = 0; OSTimeDlyHMSM(0,0,0,500); } } void Adjust_AD5933(void) { u8 Range = 0; // u8 i; u8 Buff_ADG715_Channel; for(Range = 1;Range <= Range_Quantity;Range++) { switch(Range) { case 1: Buff_ADG715_Channel = Calibration_Range1_Low_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); // SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); // OSTimeDlyHMSM(0,0,2,0); Calibration_Range.Magnitude_Range_First.Magnitude_FirstPoint = Read_Magnitude(); Buff_ADG715_Channel = Calibration_Range1_High_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); // SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); // OSTimeDlyHMSM(0,0,2,0); Calibration_Range.Magnitude_Range_First.Magnitude_SecondPoint = Read_Magnitude(); break; case 2: Buff_ADG715_Channel = Calibration_Range2_Low_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); // SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); // OSTimeDlyHMSM(0,0,2,0); Calibration_Range.Magnitude_Range_Second.Magnitude_FirstPoint = Read_Magnitude(); Buff_ADG715_Channel = Calibration_Range2_High_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); // SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); // OSTimeDlyHMSM(0,0,2,0); Calibration_Range.Magnitude_Range_Second.Magnitude_SecondPoint = Read_Magnitude(); break; case 3: Buff_ADG715_Channel = Calibration_Range3_Low_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); Calibration_Range.Magnitude_Range_Third.Magnitude_FirstPoint = Read_Magnitude(); Buff_ADG715_Channel = Calibration_Range3_High_Set; Set_ADG715_Channel(&Buff_ADG715_Channel); Calibration_Range.Magnitude_Range_Third.Magnitude_SecondPoint = Read_Magnitude(); break; } } Updata_System_Parameter(); } u8 Buff_AD5933_Receive[4] ; float Read_Magnitude( void) { float MagnitudeArray = 0; s16 Real_High; s16 Real_Low; s16 Image_High; s16 Image_Low; u8 startSweep[2] = {0x80, 0x41}; static u8 Read_Status = 0; if(Read_Status == 0) { SendFrame(AD5934_ADDr<<1, startSweep, sizeof(startSweep), 50); OSTimeDlyHMSM(0,0,0,500); Read_Status = 1; } Receive_ADG715_AD5934(AD5934_ADDr<<1,Status_Register, Buff_AD5933_Receive,1); if(((Buff_AD5933_Receive[0] & 0x02) | 0xfd) == 0xff) { Receive_ADG715_AD5934(AD5934_ADDr<<1,Status_Register, Buff_AD5933_Receive,1); if((Buff_AD5933_Receive[0] & 0xfb) != 0xff) { Receive_ADG715_AD5934(AD5934_ADDr<<1,Real_Data_Low, Buff_AD5933_Receive,1); Receive_ADG715_AD5934(AD5934_ADDr<<1,Real_Data_Low+1, Buff_AD5933_Receive+1,1); Receive_ADG715_AD5934(AD5934_ADDr<<1,Real_Data_Low+2, Buff_AD5933_Receive+2,1); Receive_ADG715_AD5934(AD5934_ADDr<<1,Real_Data_Low+3, Buff_AD5933_Receive+3,1); Real_Low = Buff_AD5933_Receive[0]; Real_High = Buff_AD5933_Receive[1]; Image_Low = Buff_AD5933_Receive[2]; Image_High = Buff_AD5933_Receive[3]; MagnitudeArray = sqrt( pow((((Real_High<<8)& 0xff00) | Real_Low) ,2) + pow((((Image_High<<8)& 0xff00) | Image_Low) ,2) ); Read_Status = 0; } } return MagnitudeArray; } float GF_Value1 = 0; float Nos_Value1 = 0; float GF_Value2 = 0; float Nos_Value2 = 0; float Liner_Calbration(float Magnitude,u8 Channel) { float Conductivity = 0; float Y_H_Coordinate = 0; float Y_L_Coordinate = 0; float N_H_Coordinate = 0; float N_L_Coordinate = 0; switch(Channel) { case Range1_Measure_Channel : Y_L_Coordinate = CalibrationRange1_Low_Conductivity; Y_H_Coordinate = CalibrationRange1_High_Conductivity; N_L_Coordinate = Calibration_Range.Magnitude_Range_First.Magnitude_FirstPoint; N_H_Coordinate = Calibration_Range.Magnitude_Range_First.Magnitude_SecondPoint; GF_Value1 = (Y_H_Coordinate -Y_L_Coordinate) / (N_H_Coordinate - N_L_Coordinate); Nos_Value1 = N_H_Coordinate - (Y_H_Coordinate/GF_Value1); Conductivity = ( Magnitude - Nos_Value1) * GF_Value1; break; case Range2_Measure_Channel: Y_L_Coordinate = CalibrationRange2_Low_Conductivity; Y_H_Coordinate = CalibrationRange2_High_Conductivity; N_L_Coordinate = Calibration_Range.Magnitude_Range_Second.Magnitude_FirstPoint; N_H_Coordinate = Calibration_Range.Magnitude_Range_Second.Magnitude_SecondPoint; GF_Value2 = (Y_H_Coordinate - Y_L_Coordinate) / (N_H_Coordinate - N_L_Coordinate); Nos_Value2 = N_H_Coordinate - (Y_H_Coordinate/GF_Value2); Conductivity = ( Magnitude - Nos_Value2) * GF_Value2; break; } Conductivity = 1/Conductivity; return Conductivity; } //u8 ADG5934_Read_Register(u8 Register_Address) //{ // u8 Buff_AD5933_Receive[1] ; // //Receive_ADG715_AD5934(Real_Data_Low,Buff_AD5933_Receive,sizeof(Buff_AD5933_Receive)); // return Buff_AD5933_Receive[0]; //} void Set_ADG715_Channel(u8 *Channel) { SendFrame(ADG715_ADDr<<1,Channel,1,50); } void Receive_ADG715_AD5934(u8 ADDR,u8 regAddr,u8 *buff,u8 len) { //ErrorStatus err; //u8 timeout = 50; u8 regBuf[2]; regBuf[0] = 0xB0; regBuf[1] = regAddr; SendFrame(ADDR, regBuf, 2, 50); I2C_ReadByte(ADDR, buff, len); } void Mul_Receive_AD5934(u8 ADDR,u8 regAddr,u8 *buff,u8 len) { u8 regBuf[2]; u8 RegBuf_Re[2]; regBuf[0] = 0xB0; regBuf[1] = regAddr; SendFrame(ADDR, regBuf, 2, 50); RegBuf_Re[0] = 0xb1; RegBuf_Re[1] = 4; SendFrame(ADDR, RegBuf_Re, 2, 50); // I2C_MutiRead(ADDR, RegBuf_Re,buff, len); } ErrorStatus SendFrame(u16 ADDR,u8 *buff,u8 len,u8 timeout) { ErrorStatus err = 0; I2C_WriteByte(ADDR, buff, len); #if 0 I2C_Comm_MasterWrite(I2C2,ADDR,0xffffffff,buff,len); while(timeout) { if (MasterTransitionComplete==1) { err = SUCCESS; break; } else { OSTimeDlyHMSM(0,0,0,200); timeout--; } } if (0==timeout) { err=ERROR; } OSTimeDlyHMSM(0,0,0,200); #endif return err; } void AD5934_Init(void) { u8 i; u8 Register_Write[2]; for(i=0; i<(sizeof(Register_Data) /sizeof(Register_Data[0])) ;i++) { Register_Write[0] = Register_Data.Register; Register_Write[1] = Register_Data.DATA; Write_AD5934_Register(Register_Write,sizeof(Register_Write)); OSTimeDlyHMSM(0,0,0,10); } } void Write_AD5934_Register(u8 *Buff,u8 Len) { SendFrame(AD5934_ADDr<<1,Buff,Len,50); } |
|
相关推荐
10个回答
|
|
|
|
|
|
|
|
|
|
|
|
|
|
您好,采用的频率是30KHz,固定频率(30kHz)单次采样 |
|
|
|
你的校准频率是多少, 接收级是否工作在线性区域,如果接受级没有工作在线性区域,则也可能出现误差 |
|
|
|
校准频率也是30kHz, [size=13.3333330154419px]接收级工作在线性区:接收级增益为1,反馈电阻1k(校准电阻1k 10k),分别测量1.024k 12k 15k都根本不准(向上漂)。 |
|
|
|
gft2gf2 发表于 2018-12-24 12:41 从现象来看应当是反馈电阻/校准电阻/待测阻抗之间差距过大造成的误差。在别的参数不变的情况下, 推荐保持反馈电阻和校准电阻保持一样的数值,待测电阻和前两者之间的差距不要超过百分之十。如果无法做到这一点,需要调整增益和输出幅值来确保ADC端接受到的信号大体上处于2V pk-pk的范围内。若信号幅度太大会造成ADC饱和,若信号幅度太小会造成12位的ADC无法有效识别进而造成结果失准。 |
|
|
|
@susan,根据Circuit Note [size=13.3333330154419px]CN0394: 待测电阻与Rfb和Rcal之间的差距远超过百分之十,并且内部可选增益只有1和5的情况下它的测试精度还是很高的,它是怎么做到这个精度的, 另外Rfb可通过切换通道选择大小,可是数量总是有限的,如果AD5933/AD5934是怎么做到测量1 kΩ to 10 MΩ范围的阻抗? |
|
|
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
897 浏览 2 评论
给ADUM4223 增加信号驱动15V电压就不正常, 波动很大会被烧是什么情况?
1315 浏览 2 评论
ADP5092 SYS端口为2.09V,但是REG_OUT为0是什么原因?
1910 浏览 1 评论
ad7193差分输入ain1与ain2差是正值时,读到电压与实际值误差小,但为负值值,误差就变的很大
4248 浏览 2 评论
9010 浏览 1 评论
ADC3442采集,分析数据出现有规则毛刺,请问是哪方面的问题啊?
1441浏览 3评论
AD7190状态寄存器一直是0x80,连续转换模式下RDY不拉低
1663浏览 2评论
903浏览 2评论
1640浏览 2评论
给ADUM4223 增加信号驱动15V电压就不正常, 波动很大会被烧是什么情况?
1317浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-2 05:19 , Processed in 0.906705 second(s), Total 63, Slave 56 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号