FFT によるスペクトル解析器
Dependencies: Array_Matrix mbed SerialTxRxIntr UIT_FFT_Real DSP_ADDA
main.cpp
00001 //--------------------------------------------------------------------- 00002 // FFT によるスペクトルアナライザ,白色雑音発生器付き (Nucleo-F446RE 用) 00003 // 00004 // ● ST-Link Firmware の V2.J37.M26 で動作確認 00005 // 00006 // ● ST-Link Firmware のアップグレードには stsw-link007_V2-37-26.zip 00007 // に含まれている "ST-LinkUpgrade.exe" を使う 00008 // 00009 // ● PC 側のプログラム: "F446_FFT_Analyzer" 00010 // ● ボーレート: 460800 baud 00011 // ● 受信データの文字列の終了マーク: "\r" 00012 // 00013 // ● 入力: A1 00014 // ● 白色雑音の出力:A2 00015 // 00016 // 2021/01/08, Copyright (c) 2021 MIKAMI, Naoki 00017 //--------------------------------------------------------------------- 00018 00019 #include "mbed.h" 00020 #include <string> 00021 #include "Array.hpp" 00022 #include "DSP_AdcIntr.hpp" 00023 #include "DSP_Dac.hpp" 00024 #include "FFT_Analyzer.hpp" 00025 #include "DoubleBuffer.hpp" 00026 #include "Coefs_IIR_LP.hpp" // 縦続形 IIR フィルタの係数 00027 #include "IirCascade.hpp" // 縦続形 IIR フィルタ 00028 #include "MSeq16.hpp" // M 系列発生器 00029 #include "Xfer.hpp" 00030 using namespace Mikami; 00031 00032 const int N_FFT_ = 1024; // FFT の点数 00033 const int N_FRAME_ = N_FFT_; // 1フレーム当たり標本化するデータ数 00034 const int N_SPC_ = N_FFT_/2 + 1; // 有効なスペクトルの点数 00035 const int RATIO_ = 10; // オーバーサンプリングの倍率 00036 00037 DoubleBuffer<float, N_FRAME_> buf_(0); // AD の結果を保存するバッファ 00038 DspAdcIntr myAdc_(10*RATIO_, A1); // 標本化周波数: 100 kHz 00039 DspDac myDac; 00040 IirCascade df1_(ORDER1_, CK1_, G01_); // ダウンサンプリング用 Anti-alias フィルタ 00041 IirCascade df2_(ORDER2_, CK2_, G02_); // 白色雑音発生用 00042 MSeq16 mSeq_; 00043 00044 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン 00045 void AdcIsr() 00046 { 00047 static int count = 0; 00048 00049 float xn = myAdc_.Read(); 00050 00051 float noise = df2_.Execute(mSeq_.Execute()); 00052 myDac.Write(0.8f*noise); // 白色雑音出力 00053 00054 float yn = df1_.Execute(xn); // ダウンサンプリング用 Anti-alias フィルタの実行 00055 00056 if (++count >= RATIO_) 00057 { 00058 buf_.Store(yn); // ダウンサンプリングされたデータをバッファへ格納 00059 count = 0; 00060 buf_.IfFullSwitch(); // バッファが満杯であればバッファを切り替える 00061 } 00062 } 00063 00064 int main() 00065 { 00066 SerialRxTxIntr rxTx(32, 460800); // PC との通信用 00067 Xfer tx(rxTx, N_SPC_); // PC に転送するためのオブジェクトの生成 00068 FftAnalyzer analyzer(N_FFT_); // FFT によるスペクトル解析オブジェクトの生成 00069 00070 Array<float> sn(N_FFT_, 0.0f); // スペクトル解析の対象となるデータ 00071 Array<float> absFt(N_SPC_); // 解析結果:スペクトルの絶対値 00072 00073 NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高 00074 NVIC_SetPriority(USART2_IRQn, 1); 00075 00076 bool ready = false; // スペクトルの計算終了で true 00077 bool okGo = false; // "GO" を受信したら true 00078 float magn = 1; // 転送する際の倍率 00079 00080 myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て 00081 while (true) 00082 { 00083 // PC からのコマンドの解析 00084 if (rxTx.IsEol()) // 受信バッファのデータが有効になった場合の処理 00085 { 00086 string str = rxTx.GetBuffer(); 00087 if (str == "FFTAnalyzer") 00088 rxTx.TxString("ACK\n"); // PC からの "FFTAnalyzer" に対して "ACK" を送信 00089 if (str.substr(0, 2) == "GO") 00090 { 00091 okGo = true; // データの転送要求あり 00092 float x = (float)atoi(str.erase(0, 2).c_str()); 00093 magn = powf(10, x/20.0f); 00094 } 00095 } 00096 00097 if (buf_.IsFull()) // 入力データが満杯の場合,以下の処理を行う 00098 { 00099 for (int n=0; n<N_FRAME_; n++) sn[n] = buf_.Get(n); 00100 analyzer.Execute(sn, absFt); // スペクトル解析の実行 00101 tx.Convert(absFt, magn); // スペクトル解析の結果を転送する形式に変換 00102 ready = true; // スペクトル解析終了 00103 } 00104 00105 // 転送要求がありスペクトル解析が終了している場合にデータを PC へ転送する 00106 if (okGo && ready) 00107 { 00108 tx.ToPC(); // データを PC へ転送 00109 ready = false; 00110 okGo = false; 00111 } 00112 } 00113 }
Generated on Fri Jul 15 2022 00:11:09 by 1.7.2