AD5933不同頻率下的轉換結果

 

01簡介


AD5933阻抗轉換模塊 是一款基於AD公司的 AD5933 芯片的測量 復阻抗 的電路模塊。在 AD5933阻抗轉換器、網絡分析儀初步實驗 中對該模塊進行了初步的實驗。

由於該芯片的基本原理是採集有芯片內部產生的正弦波電壓信號激勵下復阻抗相應的正弦電流信號,經由芯片內部的I-V轉換,有內部12bit-1Msps的ADC採樣1024的數據,通過DFT來獲電流的在該頻率下信號的實部RR和虛部II,最後可以計算出電流的幅度和相位,從而反映了復阻抗Z(ω)Z\left( \omega \right)在不同頻率下的取值。

下面是AD5933芯片內部的功能框圖。這部分可以想見該芯片的 數據手冊。

▲ AD5933內部功能圖

▲ AD5933內部功能圖

在初步試驗中,遇到以下問題需要通過實驗來回答:

  • AD5933採集數據的頻率和時長是多少?
    手冊給出了AD5933的ADC的轉換速率爲1Msps。採集到1024點的數據的時間就是1.024ms,這一點也從數據手冊中指出數據採集運算的時間大約是1ms左右。這個採集速率和總時間是否不受輸出信號頻率影響?

  • AD5933計算結果是否會受到信號截取的影響?
    這是典型的DFT分析信號頻譜所帶來的問題。當採集分析數據的長度不是週期信號的完整的整數週期的時候,輸出的結果會出現 頻率泄露 現象的影響。

  • 直接使用AD5933可以分析的最低頻率是多少?
    爲了保證DFT所得到的結果足夠精確,即需要在1ms的採集時間內採集到足夠多的週期的信號,就會限制AD5933能夠分析復阻抗的最低頻率。那麼這個最低頻率是多少呢?

  • 如何繼續降低AD5933分析頻率的下限?
    在一些分析中,如果希望進一步降低,可以通過使用外部的MCLK來實現。這對於測量是否有影響?

下面通過實驗逐一回覆上面的問題。

 

02採集數據的時長


在測試程序的串口命令中,增加一個通過STC8G1k定時器(週期爲1ms)來記錄執行 StartFrequency命令的時間測量。

通過設置AD5933 Settling Period=500,輸出頻率爲5000Hz,執行startf,可以看到返回的測量時間爲101ms。其中100ms是輸出500個Settling 週期信號所需要的時間,後面1ms則是數據採集和計算所需要的時間。

ad5933.init(500)
ad5933.setsweep(5000, 100, 100)
ad5933.startf(1)

通過設置不同的輸出頻率,會發現後面的1ms多出的時間始終保持不變,這就證明了AD5933的採集處理信號的時間週期就是1ms,固定的。

由於這個過程中,是通過讀取AD5933的Status寄存器中的D1來判斷是否數據採集處理完畢,所以更加精確的採集和處理時間的測量也就無法準確的判斷了。

 

03數據截取窗口的影響


分別進行不同頻率變化,觀察相應的輸出結果。

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

通過以上不同頻率下輸出的結果可以看出,計算的結果在輸出頻率低的情況下,會受到截取窗口的影響。下面對於在1000Hz左右的頻率前後200Hz內進行掃描,可以看到在頻率大約等於f0=1010.78Hzf_0 = 1010.78Hz左右時,實部接近於0。

▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

更進一步觀察可以看到,當輸出頻率在2048Hz左右的時候輸出的數值爲0。這也從另外一個解讀到AD5933採集數據的長度大約需要消耗1024us。
▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

下面時對於局部採樣結果放大之後顯示的情況。
▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

 

04最低頻率爲多少?


通過以上分析,輸出結果會受到採集數據時間長度的影響。下面顯示了輸出頻率從200Hz變換40200Hz過程中,在阻抗無窮大的情況下AD5933測量的結果。

從圖中可以看到,當輸出頻率大約3k以上,基本上就可以反映出測量電流結果的情況了。
▲ 在負載等於無窮大的時候,不同頻率下輸出的結果

▲ 在負載等於無窮大的時候,不同頻率下輸出的結果

下面顯示了頻率從200Hz變化到4000Hz的情況,如果頻率在2048H左右,測量得到的電流幅值也基本上接近於0。綜合以上分析,可以看到使用AD5933測量復阻抗,實際上可能達到的最頻率是2048Hz。
▲ 在沒有負載情況下,不同頻率下轉換的結果

▲ 在沒有負載情況下,不同頻率下轉換的結果

 

※ 結論


通過實際測量,可以看到AD5933在測量復阻抗的時候,在內部時鐘oscf=16.776MHz的驅動下,採集數據的頻率大約是1Msps,採集數據的時長爲1024us。

由於受到數據長度對DFT的影響,在選取測量復阻抗頻率的時候需要:

  • 頻率儘可能的高,最高大於1024Hz的5倍以上;
  • 頻率儘可能選擇爲1024Hz的整數倍數,這是在內部osc=16.776MHz作用下的頻率。
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# TEST1.PY                     -- by Dr. ZhuoQing 2020-06-25
#
# Note:
#============================================================
from headm import *
import ad5933
from tsmodule.tsstm32       import *
#------------------------------------------------------------
printf('\a')
ad5933.init(20)
startf = 200
stepf = 100
numf = 400
#------------------------------------------------------------
ad5933.setsweep(startf, stepf, numf, oscf=16.776)
ad5933.sweep(1)
time.sleep(10)
R,I = stm32memo(2)
f = linspace(startf, startf + stepf * numf, numf + 1, endpoint=True)
A = [sqrt(r**2+i**2) for r,i in zip(R,I)]
plt.plot(f, R, label="Real")
plt.plot(f, I, label="Imaginary")
plt.plot(f, A, label='Amplitude')
plt.xlabel("Frequency(Hz)")
plt.ylabel("Value")
plt.grid(True)
plt.legend(loc="upper right")
plt.show()
#------------------------------------------------------------
#        END OF FILE : TEST1.PY
#============================================================
#!/usr/local/bin/python
# -*- coding: gbk -*-
#============================================================
# AD5933.PY                    -- by Dr. ZhuoQing 2020-06-25
#
# Note:
#============================================================
from head import *
from tsmodule.tsstm32       import *
#------------------------------------------------------------
def init(settletime=100):
    stm32cmd('writeb 81 0')
    time.sleep(0.02)
    stm32cmd('writeb 80 b1')    # Enter standby mode
    stm32cmd('writei 8a %x'%settletime)
    time.sleep(0.02)
    stm32cmd('reada')
    time.sleep(0.02)
def temperature():
    data = stm32cmdata('readt', wait=200)
    if len(data) > 0: return data[0]*0.03
    else: return 0
def setsweep(startf, incf, num=100, oscf=16.557):
    startn = int(startf * (2**27) / (oscf*1e6/4))
    incn   = int(incf * (2**27) / (oscf*1e6/4))
#    printff('%x %x %x'%(startn, incn, num))
    stm32cmd('writel 82 %x'%startn)
    time.sleep(.02)
    stm32cmd('writel 85 %x'%incn)
    time.sleep(.02)
    stm32cmd('writei 88 %x'%num)
    time.sleep(.02)
    stm32cmd('writeb 81 0')         # D3: 0:Internal system clock 1:External
    time.sleep(.02)
    stm32cmd('writeb 80 b1')        # Standby
    time.sleep(.02)
    stm32cmd('writeb 80 11')
    time.sleep(.02)
def startf(resultflag = 0):
    if resultflag > 0:
        stm32cmd('writeb 80 21 1')
    else:
        stm32cmd('writeb 80 21')
def incf(resultflag = 0):
    if resultflag > 0:
        stm32cmd('writeb 80 31 1')
    else:
        stm32cmd('writeb 80 31')
def repeatf(resultflag = 0):
    if resultflag > 0:
        stm32cmd('writeb 80 41 1')
    else:
        stm32cmd('writeb 80 41')
def readdata():
    return stm32cmdata('readd', wait=100)
def sweep(code=0x1):
    stm32cmd('CLEAR')
    time.sleep(.02)
    stm32cmd('sweep %x'%code)
#------------------------------------------------------------
if __name__ == '__main__':
    tdim = []
    for i in range(10):
        data = temperature()
        tdim.append(data)
        time.sleep(.1)
    printf(tdim)
#------------------------------------------------------------
#        END OF FILE : AD5933.PY
#============================================================
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章