AD5933は外部クロックで動作していません


0

AD5933インピーダンス測定チップを使用しています。外部クロックを接続するオプションがあります。ファンクションジェネレーターを使用して250 kHz、2ボルトのピーク方形波信号をMCLKピンに供給していますが、機能しません。

コントローラーとAD5933間の通信(I2C)は良好です。

(a)内部発振器を使用しており、5 kHz〜100 kHzの周波数範囲でインピーダンスを測定できます。内部発振器を使用して、さまざまな抵抗とコンデンサの組み合わせを測定しました。ここで、5 kHzの周波数範囲より下のインピーダンスを測定することにし、UG-364アプリケーションノートによると、外部発振器を使用して250 kHzのクロック周波数を適用し、5 kHz未満の周波数範囲を使用する必要があります。

(b)添付の図に示されている外部クロック周波数を適用するためにファンクションジェネレータを使用しましたが、AD5933が応答しません。コードでwhileは、AD5933のステータスレジスタのフラグセット(2番目のビット)を読み取ることで、有効な実数値と虚数値を待機しているループを確認できます。ステータスレジスタの2番目のビットはHighになりません。つまり、AD5933は有効な実数値と虚数値を取得していません。

(c)私の回路の概略図を以下に示します。

(d)3.3 VDCを使用しており、出力励起範囲は1です。つまり、出力励起電圧は1.98 Vp-pで、DCオフセットは1.48 Vです。

外部クロックをAD5933 MCLKピンに接続する方法についての経験を共有してください。

これは私のコードシーケンスです:

  1. スタンバイモード

  2. 外部発振器を有効にする

  3. スイープを初期化する

  4. スイープを開始

関数発生器の波形

回路図

これは私のコードです:

#include "Wire.h"

#define SLAVE_ADD 0x0D
#define ADD_PTR 0xB0

#define START_FREQ_REG1 0x82
#define START_FREQ_REG2 0x83
#define START_FREQ_REG3 0x84

#define FREG_INCR_REG1 0x85
#define FREG_INCR_REG2 0x86
#define FREG_INCR_REG3 0x87

#define NUM_INCR_REG1 0x88
#define NUM_INCR_REG2 0x89

#define CYCLE_REG1 0x8A 
#define CYCLE_REG2 0x8B 

#define REAL_REG1 0x94
#define REAL_REG2 0x95

#define IMG_REG1 0x96
#define IMG_REG2 0x97


#define CRL_REG 0x80
#define CRL_REG1 0x81
#define STATUS_REG 0x8F


void programReg();
void runSweep();
void writeData(int addr, int data);
byte getFrequency(float freq, int n);
int readData(int addr);

const float MCLK = 250*pow(10,3); // AD5933 Internal Clock Speed 16.776 MHz for formula
const float start_freq = 100; // Set start freq, < 100Khz (for formula)
const float incre_freq = 10; // Set freq increment (for formula)
const int incre_num = 10; // Set number of increments; < 511

byte value;
 int count=0;
char state; 
double gain;
const double pi = 3.141592654;


void setup() {

    Wire.begin();
    Serial.begin(115200);


  //nop - clear ctrl-reg
 writeData(CRL_REG,0x0);



    programReg();
}


void loop(){

         if(Serial.available()>0) {
     state = Serial.read();


      switch(state) {
        case 'A':  
          programReg();
          break;

        case 'B':
          runSweep();

          break;




      }
    }

}




void programReg(){



    // Start frequency of 1kHz
    writeData(START_FREQ_REG1, getFrequency(start_freq,1));
    writeData(START_FREQ_REG2, getFrequency(start_freq,2));
    writeData(START_FREQ_REG3, getFrequency(start_freq,3));


    // Increment by 1 kHz
    writeData(FREG_INCR_REG1, getFrequency(incre_freq,1)); 
    writeData(FREG_INCR_REG2, getFrequency(incre_freq,2)); 
    writeData(FREG_INCR_REG3, getFrequency(incre_freq,3));




    // Points in frequency sweep (150), max 511
    //writeData(NUM_INCR_REG1,0x00 );
    //writeData(NUM_INCR_REG2, 0x96);

 writeData(NUM_INCR_REG1, (incre_num & 0x001F00)>>0x08 );
 writeData(NUM_INCR_REG2, (incre_num & 0x0000FF));

  // Set settling cycles
  writeData(CYCLE_REG1, 0x00);
  writeData(CYCLE_REG2, 0x64);


}


void runSweep() {
    short re=0;
    short img=0;
    double freq=0;
  double mag=0;
  double  MAG=0;
  double phase=0;

  double impedance=0;

    int i=0;

  programReg();

    // 1. Standby '10110001'
    writeData(CRL_REG, 0xB0);




 // Enable external oscillator
 writeData(CRL_REG1, 0x8);




    // 2. Initialize sweep '00010001'
writeData(CRL_REG, 0x11);

     delay(20);

    // 3. Start sweep '00100000'
    writeData(CRL_REG, 0x21);   



while((readData(STATUS_REG) & 0x07) < 4 ) {  // Check that status reg != 4, sweep not complete

        delay(20); // delay between measurements

        int flag = readData(STATUS_REG)& 2;

        //Serial.println("");
        //Serial.println(readData(STATUS_REG));


        if (flag==2)

        {


            byte R1 = readData(REAL_REG1);
            byte R2 = readData(REAL_REG2);
            re = (R1 << 8) | R2;

            R1  = readData(IMG_REG1);
            R2  = readData(IMG_REG2);
            img = (R1 << 8) | R2;

            freq = start_freq + i*incre_freq;




     Serial.print(freq);
      Serial.print("\t");






        mag = sqrt(pow(double(re),2)+pow(double(img),2));


        if (count==0)
      {
       gain=1.0/(mag*34000);

       count=1;
      }


      if (count!=0)
      {
       impedance =1.0/(gain*mag);

       Serial.println(impedance);



        }


            //Increment frequency
            if((readData(STATUS_REG) & 0x07) < 4 ){
     // if((readData(STATUS_REG) & 0x04) == 0 ){
                writeData(CRL_REG,0x31);

       // writeData(CRL_REG,(readData(CRL_REG) | 0x01) | 0x30);
                i++;
      }
        }
             else {
      //Power down

   writeData(CRL_REG,0xA0);
  //writeData(CRL_REG,(readData(CRL_REG) & 0x07) | 0xA0);
             }
     p++;
        ///}
}
}










void writeData(int addr, int data) {

 Wire.beginTransmission(SLAVE_ADD);
 Wire.write(addr);
 Wire.write(data);
 Wire.endTransmission();
 delay(1);
}


int readData(int addr){
    int data;

    Wire.beginTransmission(SLAVE_ADD);
    Wire.write(ADD_PTR);
    Wire.write(addr);
    Wire.endTransmission();
  delay(1);

    Wire.requestFrom(SLAVE_ADD,1);

    if (Wire.available() >= 1){
        data = Wire.read();
    }
    else {
        data = -1;
    }

    delay(1);
    return data;    
}


byte getFrequency(float freq, int n){
    long val = long((freq/(MCLK/4)) * pow(2,27));
    byte code;

      switch (n) {
        case 1:
          code = (val & 0xFF0000) >> 0x10; 
          break;

        case 2:
          code = (val & 0x00FF00) >> 0x08;
          break;

        case 3:
          code = (val & 0x0000FF);
          break;

        default: 
          code = 0;
      }

    return code;  
}

double phase_sweep(double img, double re)
{
  double phase;
  if ((re>0)&(img>0))
  {
    phase = atan(double(img)/double(re));
    phase = (phase*180)/pi;  
  }
    else if((re>0)&(img<0))
    {
    phase = atan(double(img)/double(re));
    phase = (phase*180)/pi+360;  
    }
    else if ((re<0)&(img<0))
    {
      phase = -pi + atan(double(img)/double(re));
      phase = (phase*180)/pi;
    }
    else if ((re<0)&(img>0))
    {
      phase = pi + atan(double(img)/double(re));
      phase = (phase*180)/pi;
    }

    return phase;
  }

AD5933を外部発振器で動作させるのを手伝ってください。

回答:


1

関数発生器を使用して、250 kHz、2ボルトのピーク方形波信号をMCLKピンに供給しています

オシロスコープのトレースによると、それは実際にピンに供給しているものではありませんMCLK

オシロスコープのトレースに表示されるクロックは、として無効MCLKです。

トレースは、スコープによって測定されたバイポーラ信号を示します。スコープは、0 Vを中心とする3.88 Vp-p、つまり約+1.94 V〜- 1.94 Vです。その-1.94 Vは、MCLKピンの許容負電圧を超えています。AD5933のデータシートには、MCLKピンに供給される電圧が-0.3 V以下であってはならないことが示されています。


AD5933データシートのMCLKの絶対最大定格

(画像ソース:AD5933データシート、7ページ


SFG-2010関数発生器の取扱説明書をざっと見てみると、通常の波形出力を使用していると思います。次のいずれかが必要です。

  1. 信号発生器の通常の出力を設定する方法を知っている場合、以下で説明する電圧範囲内で信号出力をユニポーラにします。または
  2. 代わりに関数発生器のTTL / CMOS出力を使用し、回路図に示されている50Ω負荷抵抗を取り外し、このユニポーラ出力信号が0 VからVddの間にあることを確認してください。

    ファンクションジェネレーターのユーザーマニュアルによると、「TTL」出力に切り替えると、出力電圧は3V以上になります。3.3Vを超えると問題になります。また、「CMOS」出力に切り替えると、出力電圧を調整できます。ただし、言及されている最低値は4 Vで、プラスまたはマイナス1 Vの許容誤差があります。したがって、「CMOS」出力電圧も高すぎて3.3 V Vddを超える可能性があります。バランスのとれた立ち上がり/立ち下がり時間の場合、この場合、CMOS出力設定が私の優先オプションです。

そのため、信号発生器からのTTLおよびCMOSモード出力電圧の測定を行う必要があり、スコープで見たものに応じて、外部減衰またはプッシュプルレベル変換を追加する必要があります(高速な立ち上がり/立ち下がりで)MCLK入力に適したVddに対して0 Vを超えないクロック信号振幅を確保するために)。

または、周波数精度、安定性などの要件に応じMCLKて、適切なCMOS出力段を備えた信号を生成するために別のクロックジェネレータを使用して調査することができます。

最悪の場合、誤ったバイポーラ信号をMCLKピンに接続すると、例えば過電流によりそのピンのESD入力保護が短絡するなどして、AD5933のその部分がすでに損傷している可能性があります。もし適当生成する場合MCLK、私が正常範囲を(0 V 3.3 V MAX)を示しており、上記示唆したように信号はないに接続MCLKピンが、これは、それがときに大きく変化されるに接続MCLKピン、その予兆であろうそのMCLKAD5933 ICの入力が既に破損していること。

回路図のもう1つのポイント:必要な電源バイパスコンデンサ(データシートの 34ページで説明)が回路図から欠落しており、データシートで説明されているように、物理的な位置も重要です。これらのバイパスコンデンサを省略すると、デバイスの動作に影響する場合があります。

(私はあなたのコードを調査していません- MCLK信号が修正されるまで、他の考えられる問題を見る意味はありません。同じコード(外部クロックを選択するための変更を除く)が内部クロックの実験で使用されたと仮定し、働いた)。


SamGibsonは返信に感謝します。データシートのMCLK信号に応じて(-0.3〜VDD + 0.3)である必要がありますが、データシートの最後にAD5933を使用して開発された評価ボードの回路図があり、外部発振器と信号をMCLKピンに直接適用しました。オシロスコープでこの発振器の出力を見ましたが、その出力はVDD 3.3ボルトで(6.08)Vp-pです。
Ati

@Atiは- 「オシロスコープ上で、この発振器の出力は、[...]のVDD 3.3voltで(6.08)VP-Pである。」私は、標準的な水晶発振器がVDDより高いO / Pの電圧を生成見たことがありません。ボードを手に入れずに結果を説明することはできません。私はより多くの研究を行ってきました(ここにリストするには長すぎます)MCLKアナログデバイスフォーラムこの質問をしていることがわかりましたので、そこで回答が得られることを願っています。幸運を!
サムギブソン

私の問題を解決し、4脚発振器の出力はユニポーラであり、評価ボードに取り付けられたこの16MHZ発振器を使用し、AD5933チップが外部発振器で動作するようになりました。あなたの指導のために。
Ati

@Ati-アップデートをありがとう。「4レッグオシレーターの出力はユニポーラです」申し上げたとおり、それはまさに私が期待したものです。昨日、オシロスコープでバイポーラ 6.08 Vp-p発振器出力信号を報告した理由を説明してください。原因は何ですか?次に、これらの詳細を回答に追加して、より完全なものにすることができます。ありがとう。
サムギブソン

SamGibson問題のオシロスコープでACカップリングを選択しました。コメントを読んだ後、オシロスコープの設定をDCカップリングに変更し、データを視覚化します。出力波形はユニポーラで、振幅は3.3V
Ati
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.