使用STM32 的DSP庫進行FFT變換

2021-01-10 電子產品世界
/*

*********************************************************************************************************
FileName:dsp_asm.h
*********************************************************************************************************
*/

#ifndef __DSP_ASM_H__
#define __DSP_ASM_H__
*********************************************************************************************************
* FUNCTION PROTOTYPES
*********************************************************************************************************
*/

void dsp_asm_test(void);
void dsp_asm_init(void);

#endif /* End of module include. */
/*8888888888888888888888888888888888888888888888888888888888888888*/
/*8888888888888888888888888888888888888888888888888888888888888888*/
/*
* FileName:dsp_asm.c
* Author:Bobby.Chen
* Email:heroxx@163.com
* Date:2010-08-11
* Description:This file showes how to use the dsp library in mdk project.
* 使用三角函數生成採樣點,供FFT計算
* 進行FFT測試時,按下面順序調用函數即可:
* dsp_asm_init();
* dsp_asm_test();
*/
#include "stm32f10x.h"
#include "dsp_asm.h"
#include "stm32_dsp.h"
#include "table_fft.h"
#include
#include


/*
*********************************************************************************************************
* LOCAL CONSTANTS
*********************************************************************************************************
*/
#define PI2 6.28318530717959
// Comment the lines that you dont want to use.
// 要模擬FFT,請注釋掉其他的預定義
// 此處也可以全部注釋掉,在MDK的工程屬性->"C/C++"->"Preprocessor Symbols"-"Define:"中添加NPT_XXX項目
// 但是這樣做法的缺點是每次修改XXX數據,都會導致MDK下次編譯時會編譯全部文件,速度太慢。
//#define NPT_64 64
#define NPT_256 256
//#define NPT_1024 1024

// N=64,Fs/N=50Hz,Max(Valid)=1600Hz
// 64點FFt,採樣率3200Hz,頻率解析度50Hz,測量最大有效頻率1600Hz
#ifdef NPT_64
#define NPT 64
#define Fs 3200
#endif

// N=256,Fs/N=25Hz,Max(Valid)=3200Hz
// 256點FFt,採樣率6400Hz,頻率解析度25Hz,測量最大有效頻率3200Hz
#ifdef NPT_256
#define NPT 256
#define Fs 6400
#endif

// N=1024,Fs/N=5Hz,Max(Valid)=2560Hz
// 1024點FFt,採樣率5120Hz,頻率解析度5Hz,測量最大有效頻率2560Hz
#ifdef NPT_1024
#define NPT 1024
#define Fs 5120
#endif

/*
*********************************************************************************************************
* LOCAL GLOBAL VARIABLES
*********************************************************************************************************
*/
extern uint16_t TableFFT[];
long lBUFIN[NPT]; /* Complex input vector */
long lBUFOUT[NPT]; /* Complex output vector */
long lBUFMAG[NPT];/* Magnitude vector */
/*
*********************************************************************************************************
* LOCAL FUNCTION PROTOTYPES
*********************************************************************************************************
*/
void dsp_asm_powerMag(void);

/*
*********************************************************************************************************
* Initialize data tables for lBUFIN
* 模擬採樣數據,採樣數據中包含3種頻率正弦波:50Hz,2500Hz,2550Hz
* lBUFIN數組中,每個單元數據高字(高16位)中存儲採樣數據的實部,低字(低16位)存儲採樣數據的虛部(總是為0)
*********************************************************************************************************
*/
void dsp_asm_init()
{
u16 i=0;
float fx;
for(i=0;i {
fx = 4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs);
lBUFIN[i] = ((s16)fx)<<16;
}
}

/*
*********************************************************************************************************
* Test FFT,calculate powermag
* 進行FFT變換,並計算各次諧波幅值
*********************************************************************************************************
*/
void dsp_asm_test()
{
// 根據預定義選擇合適的FFT函數
#ifdef NPT_64
cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);
#endif

#ifdef NPT_256
cr4_fft_256_stm32(lBUFOUT, lBUFIN, NPT);
#endif

#ifdef NPT_1024
cr4_fft_1024_stm32(lBUFOUT, lBUFIN, NPT);
#endif

// 計算幅值
dsp_asm_powerMag();

// printf("No. Freq Power\n");
// for(i=0;i// {
// printf("%4d,%4d,%10d,%10d,%10d\n",i,(u16)((float)i*Fs/NPT),lBUFMAG[i],(lBUFOUT[i]>>16),(lBUFOUT[i]&0xffff));
// }
// printf("*********END**********\r\n");
}
/*
*********************************************************************************************************
* Calculate powermag
* 計算各次諧波幅值
* 先將lBUFOUT分解成實部(X)和虛部(Y),然後計算賦值(sqrt(X*X+Y*Y)
*********************************************************************************************************
*/
void dsp_asm_powerMag(void)
{
s16 lX,lY;
u32 i;
for(i=0;i {
lX = (lBUFOUT[i] << 16) >> 16;
lY = (lBUFOUT[i] >> 16);
{
float X = NPT * ((float)lX) /32768;
float Y = NPT * ((float)lY) /32768;
float Mag = sqrt(X*X + Y*Y)/NPT;
lBUFMAG[i] = (u32)(Mag * 65536);
}
}
}


// 筆者使用的是金牛開發板,CPU為STM32F107VC;JLink V8,MDK-ARM 4.10

本文引用地址:http://www.eepw.com.cn/article/201611/315882.htm

// 注意FFT運算結果的對稱性,也即256點的運算結果,只有前面128點的數據是有效可用的。
// 64點FFT運算結果圖(局部):

上圖中,數組下標X對應的諧波頻率為:N×Fs/64=N×3200/64=N*50Hz.

lBUFMAG[1] 對應 50Hz諧波幅值

上圖中由於FFT解析度50HZ,最大只能識別1600Hz諧波,導致結果中出現錯誤的數據。
// 256點FFT運算結果圖(局部):

上圖中,數組下標X對應的諧波頻率為:N×Fs/256=N×6400/256=N*25Hz.

lBUFMAG[2] 對應 2×25 =50Hz諧波幅值

lBUFMAG[100] 對應 100×25=2500Hz諧波幅值

lBUFMAG[102] 對應 102×25=2550Hz諧波幅值


// 1024點FFT運算結果圖(局部):

上圖中,數組下標X對應的諧波頻率為:N×Fs/1024=N×5120/1024=N*5Hz.

lBUFMAG[10] 對應 10×5 =50Hz諧波幅值

lBUFMAG[500] 對應 500×5=2500Hz諧波幅值

lBUFMAG[510] 對應 510×5=2550Hz諧波幅值

該工程中模擬信號源為:4000 * sin(PI2*i*50.0/Fs) + 4000 * sin(PI2*i*2500.0/Fs) + 4000*sin(PI2*i*2550.0/Fs)

信號為1個50Hz、1個2500Hz、1個2550Hz的正弦波混合信號,幅值為均為4000。

相關焦點

  • 使用FastAI 和即時頻率變換進行音頻分類
    FastAI 是一個構建在 PyTorch 之上的高級庫,用這個庫進行圖像分類非常容易,其中有一個僅用四行代碼就可訓練精準模型的例子。隨著v1版的發布,該版本中帶有一個data_block的API,它允許用戶靈活地簡化數據加載過程。
  • 第六講 DSP在雷達信號處理中的應用
    引言 dsp是一種基於精簡指令集的可編程數學計算晶片,可以對數位訊號進行時頻域變換、頻譜分析、濾波、估值、增強、壓縮等處理,廣泛應用於家用電器、多媒體系統、雷達、衛星系統、移動通信、網絡會議、醫學儀器、實時圖像識別與處理、語音處理、自適應制導控制、模式識別、定位、導航、聯合戰術無線電系統和智能基站等領域。
  • 基於小波變換與DSP的實時音頻視頻處理系統
    小波變換充分利用人眼的視覺特性,克服了重構圖像會出現的塊效應、蚊子效應、模糊等現象。由於小波變換技術能充分地利用人眼的視覺特性,因此因而用小波變換視頻編碼將會獲得比現在標準得多的壓縮效果。本文介紹一種基於adv611,ct8021晶片同時結合ti公司的tms320c6201晶片實現音/視頻實時處理系統。
  • 史上最簡單的FFT(快速傅立葉變換)
    這個就需要傅立葉變換了。3 複數複數是數學上一個很常見的概念,複數的特點是對負數進行開方。負數相加的規則是實部(x軸)和實部相加,虛部(y軸)和虛部相加。 複數乘法的規則是模長相乘,幅角相加。下面略作證明:c++裡面提供了複數的模板,可以直接進行加減乘除(相當於一個pair),當然我們也可以自己寫。
  • OpenCV-Python 傅立葉變換|三十
    (一些連結已添加到「其他資源」,其中通過示例直觀地說明了頻率變換)。現在,我們將看到如何找到傅立葉變換。Numpy中的傅立葉變換首先,我們將看到如何使用Numpy查找傅立葉變換。Numpy具有FFT軟體包來執行此操作。
  • MATLAB實驗——FFT變換
    實驗基本原理與設計1 應用傅立葉變換進行圖像處理傅立葉變換是線性系統分析的一個有力工具,它能夠定量地分析諸如數位化系統、採樣點、電子放大器、卷積濾波器、噪音和顯示點等的作用。通過實驗培養這項技能,將有助於解決大多數圖像處理問題。對任何想在工作中有效應用數字圖像處理技術的人來說,把時間用在學習和掌握博裡葉變換上是很有必要的。
  • STM32四種庫對比:寄存器、標準外設庫、HAL、LL
    每個STM32系列的100多個片段演示了如何以最小的內存佔用有效地使用STM32外圍設備。(因為現在ST官方主推STM32CubeMX,所以停止了對SPL的更新) 標準外設庫是在寄存器的基礎上進行了一次簡單封裝,主要是面向過程的嵌入式系統開發人員。
  • 快速傅立葉變換FFT在MATLAB中的實現
    首先,為什麼要進行傅立葉變換?將時域的信號變換到頻域的正弦信號,正弦比原信號更簡單,且正弦函數很早就被充分地研究,處理正弦信號比處理原信號更簡單。正弦信號的頻率保持性:輸入為正弦信號,輸出仍是正弦信號,幅度和相位可能發生變化,但頻率與原信號保持一致,只有正弦信號才擁有這樣的性質。
  • 通俗易懂的講解FFT的讓你快速了解FFT
    在此之前,先列出離散傅立葉變換對(DFT): ,k=0,1,…N-1 n=0,1…N-1 其中:  但是FFT之所以稱之為快速傅立葉變換,就利用了以下的幾個性質(重中之重!) 對於運算效率就不用多提了 以上就是FFT算法的理論內容了,接下來就是用C語言對這個算法的實現了,對於FFT算法C語言的實現,網上的方法層出不窮,介於本人比較懶(懶得看別人的程序),再加上自給自足豐衣足食的原則,我自己也寫了一個個人認為比較通俗易懂的程序,並且為了幫助讀者理解,我特意儘量減少了庫函數的使用,一些基本的函數都是自己寫的(難免有很多BUG),但是作為FFT算法已經夠用了
  • 每日函數——fft
    fft快速傅立葉變換語法Y  = fft(X)Y  = fft(X
  • 用matlab對信號進行傅立葉變換
    傅氏變換分析是信號分析中很重要的方法,藉助matlab可以很方便的對各類信號進行傅氏頻域分析。
  • 用FPGA實現FFT算法(圖)
    當n較大時,因計算量太大,直接用dft算法進行譜分析和信號的實時處理是不切實際的。快速傅立葉變換(fast fourier transformation,簡稱fft)使dft運算效率提高1~2個數量級。其原因是當n較大時,對dft進行了基4和基2分解運算。fft算法除了必需的數據存儲器ram和旋轉因子rom外,仍需較複雜的運算和控制電路單元,即使現在,實現長點數的fft仍然是很困難。
  • 用matlab對信號進行傅立葉變換的入門實例
    來源:博客園-走豈來的博客傅氏變換分析是信號分析中很重要的方法,藉助matlab可以很方便的對各類信號進行傅氏頻域分析
  • 使用Matlab對信號進行頻域分析的方法
    本文引用地址:http://www.eepw.com.cn/article/201808/391336.htm  本文討論使用Matlab對信號進行頻域分析的方法。  說到頻域,不可避免的會提到傅立葉變換,傅立葉變換提供了一個將信號從時域轉變到頻域的方法。之所以要有信號的頻域分析,是因為很多信號在時域不明顯的特徵可以在頻域下得到很好的展現,可以更加容易的進行分析和處理。
  • STM32學習筆記——使用函數庫編程控制GPIO口輸出
    看了網上許多人的代碼以及各類開發板所帶的例程,大多數使用的都是官方發布的函數庫來編程,通過查詢後發現,使用函數庫來編程可以簡化開發過程,並不需要追溯到各個寄存器,通過查看庫手冊,新手也可以快速應用STM32,因此
  • 基於DSP的FFT算法實現
    虛、實等特性,對離散傅立葉變換的算法進行改進獲得的。它對傅氏變換的理論並沒有新的發現,但是對於在計算機系統或者說數字系統中應用離散傅立葉變換,可以說是進了一大步。而如果我們將這種「一分為二」的思想不斷進行下去,直到分成兩兩一組的DFT運算單元,那麼N點的DFT變換就只需要Nlog2N次的運算,N在1024點時,運算量僅有10240次,是先前的直接算法的1%,點數越多,運算量的節約就越大,這就是FFT的優越性。
  • matlab下實現FFT信號分析
    利用matlab做頻譜分析前我們需要了解分析過程中的一些基礎知識,matlab中的 fft 函數用法、fftshift 函數的用法函數 1  fft :作用:快速傅立葉變換。語法:Y = fft(X)Y = fft(X,n)Y = fft(X,n,dim)語法:Y = fft(X) 用快速傅立葉變換 (FFT) 算法計算 X 的離散傅立葉變換 (DFT)。
  • 基於DSP和FPGA的機器人聲控系統設計與實現
    3.3.4 語音信號的模式匹配和訓練 模型訓練即將特徵向量進行訓練建立模板,模式匹配即將當前特徵向量與語音庫中的模板進行匹配得出結果。語音庫的模式匹配和訓練採用隱馬爾可夫模型hmm(hidden markov models),他是一種統計隨機過程統計特性的概率模型一個雙重隨機過程,因為隱馬爾可夫模型能夠很好地描述語音信號的非平穩性和可變性,因此得到廣泛的使用[4]。
  • 【基礎教程】Matlab實現傅立葉變換
    周期性離散信號 對應於DFT(離散時間傅立葉變換),頻域離散周期傅立葉級數首先從傅立葉級數開始分析,傅立葉級數是將一個信號在一組正交基上進行分解的體現。連續時間傅立葉變換傅立葉變換實現只有離散傅立葉變換才可以實現,在MATLAB中實現有fft,fft2進行傅立葉變換,同樣可以手動進行變換。
  • Matlab傅立葉變換、餘弦變換和小波變換
    離散傅立葉變換的 Matlab實現Matlab 函數 fft、fft2 和 fftn 分別可以實現一維、二維和 N 維 DFT 算法;而函數 ifft、ifft2 和 ifftn 則用來計算反 DFT 。