最近在做課題過程中用到28335實現FFT算法,分析的數據是由AD高速採樣得來,為減輕CPU的負擔,保證實時性,AD採樣的數據通過DMA直接送到存儲器,通過AD完成採樣的EOC信號啟動DMA傳輸。經過多次傳輸,當採樣數據達到一定數量時,產生DMA中斷,算法就在該中斷函數內完成。整個方案的大致框架如下圖:
算法每次更新的數據量為90點,而算法處理的數據長度為128點,這是因為計算過程中需要數據重疊。數據採樣頻率約為54kHz,DMA中斷間隔即90點數據採樣的時間約為1.6ms,所以算法時間要小於1.6ms才能保證實時性。
算法內需要4次計算FFT,而FFT時間是整個算法最耗時的部分。因此,需要對FFT的算法時間進行測試。
FFT算法實現有2種方案,一種是直接根據FFT原理編寫代碼實現,另一種是利用TI公司的FFT庫函數實現。
第1種方案直接利用例程中的FFT代碼,如下圖,它是根據FFT算法原理利用3重循環實現的:
對照FFT算法流圖(下圖),可以看出,該代碼完全是按照FFT算法流圖的原理來做的(下圖為8點,課題中用的是128點):
對該FFT算法的128點數據的處理時間測試,需要67206個機器時鐘(這似乎是DFT的算法次數,但分析代碼確實是FFT,為什麼需要這多時鐘周期?),而整個算法要用4次FFT,在系統時鐘150MHz的情況下,整個算法的FFT時間為:
4*67206*6.67ns = 1.793ms
該時間已經超出DMA中斷間隔時間,無法做到實時運算,從下圖的處理後曲線也可以看出,由於不能實時處理,結果存儲器的數據還沒得到完整的結果就被覆蓋,使算法結果錯誤。所以,這種情況下無法滿足算法的實時性。
第2種方案採用TI的FFT庫函數實現,庫函數利用壓縮算法實現FFT,使得計算效率得到了很大提高,庫函數的源碼在controlSUITE目錄下可以找到,基本都是採用彙編語言編寫,想了解細節的可以找來看看:
關於FFT庫函數的用法可以查看文檔C28x-FPU-LIB-UG.pdf,整個FPU庫除了FFT外,還有求IFFT和求幅值等函數,在使用過程中也有一些細節需要注意,如輸入數據是否對齊、處理結果存放緩衝區等。在工程中添加C28x_FPU_Lib.lib庫文件和FPU.h頭文件後,實現FFT就很簡單了。
在主程序做初始化:
在DMA中斷程序中調用FFT庫函數:
測試一次CFFT_f32( )函數的執行機器周期:
可以看到,CFFT庫函數計算128點FFT的機器周期為5926,整個算法的FFT時間為:
4*5926*6.67ns = 0.1581ms
不到第1種方案時間的十分之一。
所以,在實時性要求很高的情況下,建議採用庫函數計算FFT。