AD5933使用

频率发生器可以产生特定频率的信号激励外部复阻抗。复阻抗的响应信号由片上模数转换器ADC采样后,再通过片上上数字信号处理器进行离散傅立叶变换(DFT)。在每个输出频率,DFT运算处理后都会返回一个实值(R)和虚值(I)。校正后,扫频轨迹上的每个频点的阻抗幅值和阻抗相对相位很容易计算。

AD5933有一个电压输出引脚Vout (图2.2)。它能发出一定频率的正弦扫描信号(>1kHz)对外部阻抗 Z(ω) 进行激励。信号通过被测样品后,再经放大、滤波后被模数转换器取样,并进行离散傅立叶变换,最终计算出待测阻抗值。

AD5933是通过芯片内部的DDS(直接数字合成器)来产生正弦扫描信号,该信号具有小于1Hz(0.1Hz)的分辨率。为DDS提供时钟频率的,既可以是外部时钟,也可以是内置的振荡器,可通过软件进行设置。DDS合成的信号经过数模转换和放大后,即可变为测试需要的扫描激励信号。该正弦激励信号有四个幅值可供选择,其值分别为2v,1v,400mv,200mv。而这些信号的起始频率,频率的增加量,和增加的次数,必须预先确定,它们都可通过软件进行设定。
注意事项:
1 AD5933使用I2C配置寄存器,第一步确保i2c通讯正常。
2 参数设置:
1>起始频率,步进频率,频率点数。reg82-reg89等寄存器;
2>反馈电阻值、输出电压范围和增益PGA都需要合适的设置,不能超过ADC的线性范围。
3>系统时钟MCLK:可以选用内部时钟或外部时钟。默认内部是16.776 MHz, 选择外部需要编程(写寄存器)。而且时钟的数值在编程中要用到。
4> reg8F是状态寄存器,有数据有效标志位和数据扫描完成标志位等。
先配置寄存器。再读取reg8f判断状态位,然后读取数据寄存器(reg94-reg97)并输出。
5>其中最重要的是校准,如果校准值不对,出来的数据当然不对。
校准要选择合适的已知电阻,一般选择和RFB反馈电阻相同的阻值;校准值一般认为是线性的。
本人发现并不十分线性,有些波动。所以在需要的每个频率点都校准了一下,校准值通过uart输出,然后再以一个const static double的数组写到程序中,通过查表法设置每个点的校准值。
可以两点校准,然后插值(假设线性),文档是这样做的。
6> 扫描点数最大511,如果点数过多可以分段。
参考分段代码:

for(int i=0;i<10;i++){//10 segment
     AD5933_Init(sFreq[i],STEP_FREQ,IncNum[i]);
     sweep (i, sFreq[i] , eFreq[i]);    
}

初始化和扫描代码:

#define MCLK 16.776e6 //系统时钟
#define SFreq    5000   
#define IncFreq 100
#define IncNum 451

/* AD5933初始化函数 */
void AD5933_Init(void)
{       //Gain = 1;clk_internal;vol = 2v;
        /* 起始频率码 */
        code1=code1|((int)((SFreq/(MCLK/4))*pow(2,27))&0xFF);                       //低8位
        code2=code2|((((int)((SFreq/(MCLK/4))*pow(2,27)))>>8)&0xFF);        //中间8位
        code3=code3|((((int)((SFreq/(MCLK/4))*pow(2,27)))>>16)&0xFF);       //高8位

        /* 频率增量码 */
        code4=code4|((int)((IncFreq/(MCLK/4))*pow(2,27))&0xFF);                 //低8位
        code5=code5|(((int)((IncFreq/(MCLK/4))*pow(2,27))>>8)&0xFF);        //中间8位
        code6=code6|((int)((IncFreq/(MCLK/4))*pow(2,27))>>16);                  //高8位

        /* 增量数 */
        code7=code7|(IncNum & 0xFF);
        code8=code8|((IncNum>>8)&0x1);      

        delay_ms(100);

        /* 将起始频率码写入寄存器,此时使用内部16.776MHz时钟 */
        i2c_write ( 0x84, code1);
        i2c_write ( 0x83, code2);    
        i2c_write ( 0x82, code3);

        /* 将频率增量码写入寄存器,此时使用内部16.776MHz时钟 */
        i2c_write ( 0x87, code4);
        i2c_write ( 0x86, code5);    
        i2c_write ( 0x85, code6);

        /* 将增量数写入寄存器 */
        i2c_write ( 0x89, code7);
        i2c_write ( 0x88, code8);

        /* 将预激励周期数15写入寄存器 */
        i2c_write ( 0x8B, 0x0F);
        i2c_write ( 0x8A, 0x00);

        /* 将AD5933置于待命模式 */
        i2c_write ( 0x80, 0xB0);

        /* 选择使用内部时钟 */
        i2c_write ( 0x81, 0x00);

        /* 以用户所设定的参数进入初始化模式 */
        i2c_write ( 0x80, 0x11);

        delay_ms(10);//这里的延时是为了使电路在发出初始化命令后达到稳定状态

        /* 进入频率扫描模式 */
        i2c_write ( 0x80, 0x21);

}

/* 频率扫描函数 */
void sweep (void)
{
    unsigned int real_byte_high;
    unsigned int real_byte_low;

    unsigned int imag_byte_high;
    unsigned int imag_byte_low;

    signed short int imag_data;
    signed short int real_data;

    int m = 0;      //增益因子与系统相位数组递增变量

    printf ("Start of Frequency sweep\n");      
    delay_ms(10);
    for(;;){
      status_register = AD5933_read(0x8F);          //read Status Reg
      status_register = (status_register & 0x2);    //Get D1 bit(data valid bit)

      if( ((status_register)| 0xFD )==  0xFF){      //1:data valid       

         if( (AD5933_read(0x8F)| 0xFB )!=  0xFF){   //1:freq sweep over (D2 bit)
            LCD_Clear();
            real_byte_high = AD5933_read(0x94);     //读取实部寄存器高8位数据
            real_byte_low  =  AD5933_read(0x95);    //读取实部寄存器低8位数据
            imag_byte_high = AD5933_read(0x96);     //读取虚部寄存器高8位数据
            imag_byte_low  =  AD5933_read(0x97);    //读取虚部寄存器低8位数据

            real_data = ((real_byte_high << 8) |  real_byte_low);                           
            imag_data = ((imag_byte_high << 8) |  imag_byte_low);

            Re = (int) real_data;
            Im = (int) imag_data;
            Magnitude = sqrt(pow(Re,2) + pow(Im,2));        //计算DFT幅度 DFT_ amp     
            Impedance = 1/(Magnitude * (GAIN_FAC[m]));      //GainFactor_My 
//#define  CAL_5933
#ifdef     CAL_5933
            cal_value  = 50000.0/Magnitude;//1/20000=50000 res:20kou
            printf("Freq=%d,Magnitude=%f,GainFac=%f\n",freq1,Magnitude,cal_value);
         // printf("Freq=%d,Re=%d,Im=%d,GainFac=%f\n",freq1,Re,Im,cal_value);
#else
         // printf("m=%d,Freq=%d,Re=%d,Im=%d,Impedance=%fK\n",m,freq1,Re,Im,Impedance/1000);
         // printf("Freq=%d,Re=%d,Im=%d,Impedance=%fK\n",freq1,Re,Im,Impedance/1000);
            printf("%d , %fK\n",freq1,Impedance/1000);
#endif       

            delay_ms(1);
            if(m++>IncNum-1) m=0;           //增益因子与系统相位数组下标递增 TODO
            freq1 = freq1 + IncFreq;            // 频率递增

            i2c_write ( 0x80, 0x31);            //add freq gain=1 递增至下一个频率点

      } //Query D2_bit over 
      else{ // invalid data,break   
            continue;
        }
     } //Query D1_bit over       
   } // sweep loop over
}
  • 15
    点赞
  • 96
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
AD5933是一款由安捷伦(Analog Devices)公司生产的频率合成阻抗分析器(Frequency Synthesizer Impedance Analyzer)。该器件能够通过精确控制频率和相位来测量电阻、电感和电容等元件的阻抗。 要驱动AD5933,我们可以使用C语言编写一个适当的程序。首先,我们需要选择合适的开发平台和编译器,例如使用Arduino或Raspberry Pi开发板,并安装相应的开发环境。 准备工作完成后,我们需要引入AD5933的驱动库或编写自定义的底层驱动程序。该驱动程序包含了与AD5933通信的连接和指令发送等功能。 通常,AD5933使用SPI或I2C通信协议与MCU进行通信。我们需要编写相应的函数来初始化通信接口,设置通信参数并发送命令和数据。 对于AD5933的配置,我们需要设置参考电压、频率和增益等参数。这些参数决定了阻抗测量的精度和范围。根据具体需求,我们可以使用AD5933手册中提供的寄存器设置来进行配置。 在配置完成后,我们可以使用AD5933进行阻抗测量。通过发送启动命令,AD5933将自动选择合适的频率,并测量并计算出阻抗值。我们可以在程序中编写相应的函数以读取和处理测量结果,并将其用于后续的数据处理和分析。 编写完C程序后,我们可以利用程序中的函数和接口来控制AD5933并进行阻抗测量。根据需求,我们可以将测量结果输出到终端或存储在内存中,以便进一步处理。 总之,编写AD5933的C程序驱动需要熟悉C语言编程和AD5933的功能和通信协议。通过合适的驱动程序,我们可以轻松地控制AD5933并进行阻抗测量。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值