FFT によるスペクトル解析器
Dependencies: Array_Matrix mbed SerialTxRxIntr UIT_FFT_Real DSP_ADDA
main.cpp@0:91cc5a03f0ca, 2021-01-08 (annotated)
- Committer:
- MikamiUitOpen
- Date:
- Fri Jan 08 02:27:46 2021 +0000
- Revision:
- 0:91cc5a03f0ca
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MikamiUitOpen | 0:91cc5a03f0ca | 1 | //--------------------------------------------------------------------- |
MikamiUitOpen | 0:91cc5a03f0ca | 2 | // FFT によるスペクトルアナライザ,白色雑音発生器付き (Nucleo-F446RE 用) |
MikamiUitOpen | 0:91cc5a03f0ca | 3 | // |
MikamiUitOpen | 0:91cc5a03f0ca | 4 | // ● ST-Link Firmware の V2.J37.M26 で動作確認 |
MikamiUitOpen | 0:91cc5a03f0ca | 5 | // |
MikamiUitOpen | 0:91cc5a03f0ca | 6 | // ● ST-Link Firmware のアップグレードには stsw-link007_V2-37-26.zip |
MikamiUitOpen | 0:91cc5a03f0ca | 7 | // に含まれている "ST-LinkUpgrade.exe" を使う |
MikamiUitOpen | 0:91cc5a03f0ca | 8 | // |
MikamiUitOpen | 0:91cc5a03f0ca | 9 | // ● PC 側のプログラム: "F446_FFT_Analyzer" |
MikamiUitOpen | 0:91cc5a03f0ca | 10 | // ● ボーレート: 460800 baud |
MikamiUitOpen | 0:91cc5a03f0ca | 11 | // ● 受信データの文字列の終了マーク: "\r" |
MikamiUitOpen | 0:91cc5a03f0ca | 12 | // |
MikamiUitOpen | 0:91cc5a03f0ca | 13 | // ● 入力: A1 |
MikamiUitOpen | 0:91cc5a03f0ca | 14 | // ● 白色雑音の出力:A2 |
MikamiUitOpen | 0:91cc5a03f0ca | 15 | // |
MikamiUitOpen | 0:91cc5a03f0ca | 16 | // 2021/01/08, Copyright (c) 2021 MIKAMI, Naoki |
MikamiUitOpen | 0:91cc5a03f0ca | 17 | //--------------------------------------------------------------------- |
MikamiUitOpen | 0:91cc5a03f0ca | 18 | |
MikamiUitOpen | 0:91cc5a03f0ca | 19 | #include "mbed.h" |
MikamiUitOpen | 0:91cc5a03f0ca | 20 | #include <string> |
MikamiUitOpen | 0:91cc5a03f0ca | 21 | #include "Array.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 22 | #include "DSP_AdcIntr.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 23 | #include "DSP_Dac.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 24 | #include "FFT_Analyzer.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 25 | #include "DoubleBuffer.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 26 | #include "Coefs_IIR_LP.hpp" // 縦続形 IIR フィルタの係数 |
MikamiUitOpen | 0:91cc5a03f0ca | 27 | #include "IirCascade.hpp" // 縦続形 IIR フィルタ |
MikamiUitOpen | 0:91cc5a03f0ca | 28 | #include "MSeq16.hpp" // M 系列発生器 |
MikamiUitOpen | 0:91cc5a03f0ca | 29 | #include "Xfer.hpp" |
MikamiUitOpen | 0:91cc5a03f0ca | 30 | using namespace Mikami; |
MikamiUitOpen | 0:91cc5a03f0ca | 31 | |
MikamiUitOpen | 0:91cc5a03f0ca | 32 | const int N_FFT_ = 1024; // FFT の点数 |
MikamiUitOpen | 0:91cc5a03f0ca | 33 | const int N_FRAME_ = N_FFT_; // 1フレーム当たり標本化するデータ数 |
MikamiUitOpen | 0:91cc5a03f0ca | 34 | const int N_SPC_ = N_FFT_/2 + 1; // 有効なスペクトルの点数 |
MikamiUitOpen | 0:91cc5a03f0ca | 35 | const int RATIO_ = 10; // オーバーサンプリングの倍率 |
MikamiUitOpen | 0:91cc5a03f0ca | 36 | |
MikamiUitOpen | 0:91cc5a03f0ca | 37 | DoubleBuffer<float, N_FRAME_> buf_(0); // AD の結果を保存するバッファ |
MikamiUitOpen | 0:91cc5a03f0ca | 38 | DspAdcIntr myAdc_(10*RATIO_, A1); // 標本化周波数: 100 kHz |
MikamiUitOpen | 0:91cc5a03f0ca | 39 | DspDac myDac; |
MikamiUitOpen | 0:91cc5a03f0ca | 40 | IirCascade df1_(ORDER1_, CK1_, G01_); // ダウンサンプリング用 Anti-alias フィルタ |
MikamiUitOpen | 0:91cc5a03f0ca | 41 | IirCascade df2_(ORDER2_, CK2_, G02_); // 白色雑音発生用 |
MikamiUitOpen | 0:91cc5a03f0ca | 42 | MSeq16 mSeq_; |
MikamiUitOpen | 0:91cc5a03f0ca | 43 | |
MikamiUitOpen | 0:91cc5a03f0ca | 44 | // ADC 変換終了割り込みに対する割り込みサービス・ルーチン |
MikamiUitOpen | 0:91cc5a03f0ca | 45 | void AdcIsr() |
MikamiUitOpen | 0:91cc5a03f0ca | 46 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 47 | static int count = 0; |
MikamiUitOpen | 0:91cc5a03f0ca | 48 | |
MikamiUitOpen | 0:91cc5a03f0ca | 49 | float xn = myAdc_.Read(); |
MikamiUitOpen | 0:91cc5a03f0ca | 50 | |
MikamiUitOpen | 0:91cc5a03f0ca | 51 | float noise = df2_.Execute(mSeq_.Execute()); |
MikamiUitOpen | 0:91cc5a03f0ca | 52 | myDac.Write(0.8f*noise); // 白色雑音出力 |
MikamiUitOpen | 0:91cc5a03f0ca | 53 | |
MikamiUitOpen | 0:91cc5a03f0ca | 54 | float yn = df1_.Execute(xn); // ダウンサンプリング用 Anti-alias フィルタの実行 |
MikamiUitOpen | 0:91cc5a03f0ca | 55 | |
MikamiUitOpen | 0:91cc5a03f0ca | 56 | if (++count >= RATIO_) |
MikamiUitOpen | 0:91cc5a03f0ca | 57 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 58 | buf_.Store(yn); // ダウンサンプリングされたデータをバッファへ格納 |
MikamiUitOpen | 0:91cc5a03f0ca | 59 | count = 0; |
MikamiUitOpen | 0:91cc5a03f0ca | 60 | buf_.IfFullSwitch(); // バッファが満杯であればバッファを切り替える |
MikamiUitOpen | 0:91cc5a03f0ca | 61 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 62 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 63 | |
MikamiUitOpen | 0:91cc5a03f0ca | 64 | int main() |
MikamiUitOpen | 0:91cc5a03f0ca | 65 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 66 | SerialRxTxIntr rxTx(32, 460800); // PC との通信用 |
MikamiUitOpen | 0:91cc5a03f0ca | 67 | Xfer tx(rxTx, N_SPC_); // PC に転送するためのオブジェクトの生成 |
MikamiUitOpen | 0:91cc5a03f0ca | 68 | FftAnalyzer analyzer(N_FFT_); // FFT によるスペクトル解析オブジェクトの生成 |
MikamiUitOpen | 0:91cc5a03f0ca | 69 | |
MikamiUitOpen | 0:91cc5a03f0ca | 70 | Array<float> sn(N_FFT_, 0.0f); // スペクトル解析の対象となるデータ |
MikamiUitOpen | 0:91cc5a03f0ca | 71 | Array<float> absFt(N_SPC_); // 解析結果:スペクトルの絶対値 |
MikamiUitOpen | 0:91cc5a03f0ca | 72 | |
MikamiUitOpen | 0:91cc5a03f0ca | 73 | NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高 |
MikamiUitOpen | 0:91cc5a03f0ca | 74 | NVIC_SetPriority(USART2_IRQn, 1); |
MikamiUitOpen | 0:91cc5a03f0ca | 75 | |
MikamiUitOpen | 0:91cc5a03f0ca | 76 | bool ready = false; // スペクトルの計算終了で true |
MikamiUitOpen | 0:91cc5a03f0ca | 77 | bool okGo = false; // "GO" を受信したら true |
MikamiUitOpen | 0:91cc5a03f0ca | 78 | float magn = 1; // 転送する際の倍率 |
MikamiUitOpen | 0:91cc5a03f0ca | 79 | |
MikamiUitOpen | 0:91cc5a03f0ca | 80 | myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て |
MikamiUitOpen | 0:91cc5a03f0ca | 81 | while (true) |
MikamiUitOpen | 0:91cc5a03f0ca | 82 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 83 | // PC からのコマンドの解析 |
MikamiUitOpen | 0:91cc5a03f0ca | 84 | if (rxTx.IsEol()) // 受信バッファのデータが有効になった場合の処理 |
MikamiUitOpen | 0:91cc5a03f0ca | 85 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 86 | string str = rxTx.GetBuffer(); |
MikamiUitOpen | 0:91cc5a03f0ca | 87 | if (str == "FFTAnalyzer") |
MikamiUitOpen | 0:91cc5a03f0ca | 88 | rxTx.TxString("ACK\n"); // PC からの "FFTAnalyzer" に対して "ACK" を送信 |
MikamiUitOpen | 0:91cc5a03f0ca | 89 | if (str.substr(0, 2) == "GO") |
MikamiUitOpen | 0:91cc5a03f0ca | 90 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 91 | okGo = true; // データの転送要求あり |
MikamiUitOpen | 0:91cc5a03f0ca | 92 | float x = (float)atoi(str.erase(0, 2).c_str()); |
MikamiUitOpen | 0:91cc5a03f0ca | 93 | magn = powf(10, x/20.0f); |
MikamiUitOpen | 0:91cc5a03f0ca | 94 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 95 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 96 | |
MikamiUitOpen | 0:91cc5a03f0ca | 97 | if (buf_.IsFull()) // 入力データが満杯の場合,以下の処理を行う |
MikamiUitOpen | 0:91cc5a03f0ca | 98 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 99 | for (int n=0; n<N_FRAME_; n++) sn[n] = buf_.Get(n); |
MikamiUitOpen | 0:91cc5a03f0ca | 100 | analyzer.Execute(sn, absFt); // スペクトル解析の実行 |
MikamiUitOpen | 0:91cc5a03f0ca | 101 | tx.Convert(absFt, magn); // スペクトル解析の結果を転送する形式に変換 |
MikamiUitOpen | 0:91cc5a03f0ca | 102 | ready = true; // スペクトル解析終了 |
MikamiUitOpen | 0:91cc5a03f0ca | 103 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 104 | |
MikamiUitOpen | 0:91cc5a03f0ca | 105 | // 転送要求がありスペクトル解析が終了している場合にデータを PC へ転送する |
MikamiUitOpen | 0:91cc5a03f0ca | 106 | if (okGo && ready) |
MikamiUitOpen | 0:91cc5a03f0ca | 107 | { |
MikamiUitOpen | 0:91cc5a03f0ca | 108 | tx.ToPC(); // データを PC へ転送 |
MikamiUitOpen | 0:91cc5a03f0ca | 109 | ready = false; |
MikamiUitOpen | 0:91cc5a03f0ca | 110 | okGo = false; |
MikamiUitOpen | 0:91cc5a03f0ca | 111 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 112 | } |
MikamiUitOpen | 0:91cc5a03f0ca | 113 | } |