FFT アナライザ このプログラムの説明は,CQ出版社「トランジスタ技術」の2021年10月号から開始された連載記事「STM32マイコンではじめるPC計測」の中にあります.このプログラムといっしょに使うPC側のプログラムについても同誌を参照してください.

Dependencies:   Array_Matrix mbed SerialTxRxIntr DSP_ADDA UIT_FFT_Real Window

Committer:
MikamiUitOpen
Date:
Thu Sep 09 08:52:33 2021 +0000
Revision:
0:e5fc70976c00
Child:
1:d9dbfbe95c8d
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:e5fc70976c00 1 //---------------------------------------------------------------------
MikamiUitOpen 0:e5fc70976c00 2 // FFT によるスペクトルアナライザ,白色雑音発生器付き (Nucleo-F446RE 用)
MikamiUitOpen 0:e5fc70976c00 3 // ● PC 側のプログラム: "CQ_FFT_Analyzer"
MikamiUitOpen 0:e5fc70976c00 4 // ● ボーレート
MikamiUitOpen 0:e5fc70976c00 5 // ポートの検索時: 9,600 baud
MikamiUitOpen 0:e5fc70976c00 6 // ポートの検索後: 460,800 baud
MikamiUitOpen 0:e5fc70976c00 7 //
MikamiUitOpen 0:e5fc70976c00 8 // ● 入力: A1
MikamiUitOpen 0:e5fc70976c00 9 // ● 白色雑音の出力:A2
MikamiUitOpen 0:e5fc70976c00 10 //
MikamiUitOpen 0:e5fc70976c00 11 // 2021/07/11, Copyright (c) 2021 MIKAMI, Naoki
MikamiUitOpen 0:e5fc70976c00 12 //---------------------------------------------------------------------
MikamiUitOpen 0:e5fc70976c00 13
MikamiUitOpen 0:e5fc70976c00 14 #include <string>
MikamiUitOpen 0:e5fc70976c00 15 #include "Array.hpp"
MikamiUitOpen 0:e5fc70976c00 16 #include "DSP_AdcIntr.hpp"
MikamiUitOpen 0:e5fc70976c00 17 #include "DSP_Dac.hpp"
MikamiUitOpen 0:e5fc70976c00 18 #include "FFT_Analyzer.hpp"
MikamiUitOpen 0:e5fc70976c00 19 #include "DoubleBuffer.hpp"
MikamiUitOpen 0:e5fc70976c00 20 #include "Coefs_IIR_LP.hpp" // 縦続形 IIR フィルタの係数
MikamiUitOpen 0:e5fc70976c00 21 #include "IirCascade.hpp" // 縦続形 IIR フィルタ
MikamiUitOpen 0:e5fc70976c00 22 #include "MSeq16.hpp" // M 系列発生器
MikamiUitOpen 0:e5fc70976c00 23 #include "XferSpectrum.hpp"
MikamiUitOpen 0:e5fc70976c00 24 using namespace Mikami;
MikamiUitOpen 0:e5fc70976c00 25
MikamiUitOpen 0:e5fc70976c00 26 #ifndef __STM32F446xx_H
MikamiUitOpen 0:e5fc70976c00 27 #error "Use Nucleo-F446RE"
MikamiUitOpen 0:e5fc70976c00 28 #endif
MikamiUitOpen 0:e5fc70976c00 29
MikamiUitOpen 0:e5fc70976c00 30 const int N_FFT_ = 1024; // FFT の点数
MikamiUitOpen 0:e5fc70976c00 31 const int N_FRAME_ = N_FFT_; // 1フレーム当たり標本化するデータ数
MikamiUitOpen 0:e5fc70976c00 32 const int N_SPC_ = N_FFT_/2 + 1; // 有効なスペクトルの点数
MikamiUitOpen 0:e5fc70976c00 33 const int RATIO_ = 10; // オーバーサンプリングの倍率
MikamiUitOpen 0:e5fc70976c00 34 const int N_TX_ = 501; // PC に転送するデータ数
MikamiUitOpen 0:e5fc70976c00 35
MikamiUitOpen 0:e5fc70976c00 36 DoubleBuffer<float> buf_(N_FRAME_); // AD の結果を保存するバッファ
MikamiUitOpen 0:e5fc70976c00 37 DspAdcIntr myAdc_(10.24f*RATIO_, A1); // 標本化周波数: 102.4 kHz
MikamiUitOpen 0:e5fc70976c00 38 DspDac myDac;
MikamiUitOpen 0:e5fc70976c00 39 IirCascade df1_(ORDER1_, CK1_, G01_); // ダウンサンプリング用 Anti-alias フィルタ
MikamiUitOpen 0:e5fc70976c00 40 IirCascade df2_(ORDER2_, CK2_, G02_); // 白色雑音発生用低域通貨フィルタ
MikamiUitOpen 0:e5fc70976c00 41 MSeq16 mSeq_; // M 系列信号発生器(N = 16)
MikamiUitOpen 0:e5fc70976c00 42
MikamiUitOpen 0:e5fc70976c00 43 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン
MikamiUitOpen 0:e5fc70976c00 44 void AdcIsr()
MikamiUitOpen 0:e5fc70976c00 45 {
MikamiUitOpen 0:e5fc70976c00 46 static int count = 0;
MikamiUitOpen 0:e5fc70976c00 47
MikamiUitOpen 0:e5fc70976c00 48 float xn = myAdc_.Read(); // AD 変換された値を取得
MikamiUitOpen 0:e5fc70976c00 49
MikamiUitOpen 0:e5fc70976c00 50 float noise = df2_.Execute(mSeq_.Execute());
MikamiUitOpen 0:e5fc70976c00 51 myDac.Write(0.8f*noise); // 白色雑音出力
MikamiUitOpen 0:e5fc70976c00 52
MikamiUitOpen 0:e5fc70976c00 53 float yn = df1_.Execute(xn); // ダウンサンプリング用 Anti-alias フィルタの実行
MikamiUitOpen 0:e5fc70976c00 54
MikamiUitOpen 0:e5fc70976c00 55 if (++count >= RATIO_)
MikamiUitOpen 0:e5fc70976c00 56 {
MikamiUitOpen 0:e5fc70976c00 57 buf_.Store(yn); // ダウンサンプリングされたデータをバッファへ格納
MikamiUitOpen 0:e5fc70976c00 58 count = 0;
MikamiUitOpen 0:e5fc70976c00 59 buf_.IsFullSwitch(); // バッファが満杯であればバッファを切り替える
MikamiUitOpen 0:e5fc70976c00 60 }
MikamiUitOpen 0:e5fc70976c00 61 }
MikamiUitOpen 0:e5fc70976c00 62
MikamiUitOpen 0:e5fc70976c00 63 int main()
MikamiUitOpen 0:e5fc70976c00 64 {
MikamiUitOpen 0:e5fc70976c00 65 SerialRxTxIntr rxTx; // PC との通信用,最初は 9600 baud
MikamiUitOpen 0:e5fc70976c00 66 XferSpectrum tx(rxTx, N_TX_); // PC に転送するためのオブジェクトの生成
MikamiUitOpen 0:e5fc70976c00 67 FftAnalyzer analyzer(N_FFT_); // FFT によるスペクトル解析オブジェクトの生成
MikamiUitOpen 0:e5fc70976c00 68
MikamiUitOpen 0:e5fc70976c00 69 Array<float> sn(N_FFT_, 0.0f); // スペクトル解析の対象となるデータ
MikamiUitOpen 0:e5fc70976c00 70 Array<float> absFt(N_SPC_); // 解析結果:スペクトルの絶対値
MikamiUitOpen 0:e5fc70976c00 71
MikamiUitOpen 0:e5fc70976c00 72 NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高
MikamiUitOpen 0:e5fc70976c00 73 NVIC_SetPriority(USART2_IRQn, 1);
MikamiUitOpen 0:e5fc70976c00 74
MikamiUitOpen 0:e5fc70976c00 75 bool ready = false; // スペクトルの計算終了で true
MikamiUitOpen 0:e5fc70976c00 76 bool okGo = false; // "GO" を受信したら true
MikamiUitOpen 0:e5fc70976c00 77
MikamiUitOpen 0:e5fc70976c00 78 myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て
MikamiUitOpen 0:e5fc70976c00 79 while (true)
MikamiUitOpen 0:e5fc70976c00 80 {
MikamiUitOpen 0:e5fc70976c00 81 // PC からのコマンドの解析
MikamiUitOpen 0:e5fc70976c00 82 if (rxTx.IsEol()) // 受信バッファのデータが有効になった場合の処理
MikamiUitOpen 0:e5fc70976c00 83 {
MikamiUitOpen 0:e5fc70976c00 84 string str = rxTx.GetBuffer();
MikamiUitOpen 0:e5fc70976c00 85 if (str == "FFTAnalyzer")
MikamiUitOpen 0:e5fc70976c00 86 {
MikamiUitOpen 0:e5fc70976c00 87 rxTx.TxString("ACK\n"); // PC からの "FFTAnalyzer" に対して "ACK" を送信
MikamiUitOpen 0:e5fc70976c00 88 wait_ms(10);
MikamiUitOpen 0:e5fc70976c00 89 rxTx.Baud(460800); // 以降は 460,800 baud
MikamiUitOpen 0:e5fc70976c00 90 }
MikamiUitOpen 0:e5fc70976c00 91 if (str.substr(0, 2) == "GO")
MikamiUitOpen 0:e5fc70976c00 92 okGo = true; // データの転送要求あり
MikamiUitOpen 0:e5fc70976c00 93 }
MikamiUitOpen 0:e5fc70976c00 94
MikamiUitOpen 0:e5fc70976c00 95 if (buf_.IsFull()) // 入力データが満杯の場合,以下の処理を行う
MikamiUitOpen 0:e5fc70976c00 96 {
MikamiUitOpen 0:e5fc70976c00 97 for (int n=0; n<N_FRAME_; n++) sn[n] = buf_.Get(n);
MikamiUitOpen 0:e5fc70976c00 98 analyzer.Execute(sn, absFt); // スペクトル解析の実行
MikamiUitOpen 0:e5fc70976c00 99 ready = true; // スペクトル解析終了
MikamiUitOpen 0:e5fc70976c00 100 }
MikamiUitOpen 0:e5fc70976c00 101
MikamiUitOpen 0:e5fc70976c00 102 // 転送要求がありスペクトル解析が終了している場合にデータを PC へ転送する
MikamiUitOpen 0:e5fc70976c00 103 if (okGo && ready)
MikamiUitOpen 0:e5fc70976c00 104 {
MikamiUitOpen 0:e5fc70976c00 105 tx.ToPC(absFt); // データを PC へ転送
MikamiUitOpen 0:e5fc70976c00 106 ready = false;
MikamiUitOpen 0:e5fc70976c00 107 okGo = false;
MikamiUitOpen 0:e5fc70976c00 108 }
MikamiUitOpen 0:e5fc70976c00 109 }
MikamiUitOpen 0:e5fc70976c00 110 }