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ピンに接続する方法についての経験を共有してください。
これは私のコードシーケンスです:
スタンバイモード
外部発振器を有効にする
スイープを初期化する
スイープを開始
これは私のコードです:
#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を外部発振器で動作させるのを手伝ってください。