AD5933使用

来源:互联网 发布:php对数组进行排序 编辑:程序博客网 时间:2024/04/29 23:51

频率发生器可以产生特定频率的信号激励外部复阻抗。复阻抗的响应信号由片上模数转换器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}
原创粉丝点击