CQ出版社セミナ,2021/12/07開催「実習・C++言語によるArmマイコンのプログラミング」で使うプログラム.

Dependencies:   Array_Matrix mbed SerialTxRxIntr UIT_FFT_Real

Committer:
MikamiUitOpen
Date:
Thu Apr 02 01:12:34 2020 +0000
Revision:
5:5e55a5f440c0
Parent:
4:741883d4a075
6

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:a80f730d32a8 1 //---------------------------------------------------------------------
MikamiUitOpen 0:a80f730d32a8 2 // FFT によるスペクルアナライザ (Nucleo-F446RE 用)
MikamiUitOpen 0:a80f730d32a8 3 //
MikamiUitOpen 0:a80f730d32a8 4 // ● ST-Link Firmware の V2.J28.M16 で動作確認
MikamiUitOpen 0:a80f730d32a8 5 //
MikamiUitOpen 0:a80f730d32a8 6 // ● ST-Link Firmware のアップグレードには stsw-link07.zip
MikamiUitOpen 0:a80f730d32a8 7 // に含まれている "ST-LinkUpgrade.exe" を使う
MikamiUitOpen 0:a80f730d32a8 8 //
MikamiUitOpen 0:a80f730d32a8 9 // ● PC 側のプログラム: "F446_FFT_Analyzer"
MikamiUitOpen 0:a80f730d32a8 10 // ● ボーレート: 460800 baud
MikamiUitOpen 0:a80f730d32a8 11 // ● 受信データの文字列の終了マーク: "\r"
MikamiUitOpen 0:a80f730d32a8 12 //
MikamiUitOpen 0:a80f730d32a8 13 // ● 入力: A1
MikamiUitOpen 0:a80f730d32a8 14 // ● モニタ用出力:A2
MikamiUitOpen 0:a80f730d32a8 15 //
MikamiUitOpen 0:a80f730d32a8 16 // PC 側のプログラムのフォルダ:プログラム\PC\F446_FFT_Analyzer
MikamiUitOpen 0:a80f730d32a8 17 //
MikamiUitOpen 4:741883d4a075 18 // 2020/02/05, Copyright (c) 2020 MIKAMI, Naoki
MikamiUitOpen 0:a80f730d32a8 19 //---------------------------------------------------------------------
MikamiUitOpen 0:a80f730d32a8 20
MikamiUitOpen 0:a80f730d32a8 21 #include "mbed.h"
MikamiUitOpen 0:a80f730d32a8 22 #include <string>
MikamiUitOpen 0:a80f730d32a8 23 #include "Array.hpp"
MikamiUitOpen 2:d28a3f741217 24 #include "F446_AdcIntr.hpp"
MikamiUitOpen 2:d28a3f741217 25 #include "F446_Dac.hpp"
MikamiUitOpen 0:a80f730d32a8 26 #include "FFT_Analyzer.hpp"
MikamiUitOpen 0:a80f730d32a8 27 #include "DoubleBuffer.hpp"
MikamiUitOpen 5:5e55a5f440c0 28 #include "Coefs_IIR8_LP_8k_Biquad.hpp" // 縦続形 IIR フィルタの係数
MikamiUitOpen 0:a80f730d32a8 29 #include "IIR_Cascade.hpp" // 縦続形 IIR フィルタ
MikamiUitOpen 0:a80f730d32a8 30 #include "Xfer.hpp"
MikamiUitOpen 0:a80f730d32a8 31 using namespace Mikami;
MikamiUitOpen 0:a80f730d32a8 32
MikamiUitOpen 0:a80f730d32a8 33 const int N_FFT_ = 512; // FFT の点数
MikamiUitOpen 0:a80f730d32a8 34 const int N_FRAME_ = N_FFT_/2; // 1フレーム当たり標本化するデータ数
MikamiUitOpen 0:a80f730d32a8 35 const int N_FFT_2_ = N_FFT_/2; // FFT の点数の半分
MikamiUitOpen 0:a80f730d32a8 36 const int RATIO_ = 10; // オーバーサンプリングの倍率
MikamiUitOpen 0:a80f730d32a8 37
MikamiUitOpen 0:a80f730d32a8 38 DoubleBuffer<float, N_FRAME_> buf_(0); // AD の結果を保存するバッファ
MikamiUitOpen 0:a80f730d32a8 39 AdcF446_Intr myAdc_(16*RATIO_, A1); // 標本化周波数: 160 kHz
MikamiUitOpen 0:a80f730d32a8 40 DacF446 myDac;
MikamiUitOpen 0:a80f730d32a8 41 IirCascade df_(ORDER_, CK_, G0_); // ダウンサンプリング用 Anti-alias フィルタ
MikamiUitOpen 0:a80f730d32a8 42
MikamiUitOpen 0:a80f730d32a8 43 // ADC 変換終了割り込みに対する割り込みサービス・ルーチン
MikamiUitOpen 0:a80f730d32a8 44 void AdcIsr()
MikamiUitOpen 0:a80f730d32a8 45 {
MikamiUitOpen 0:a80f730d32a8 46 static int count = 0;
MikamiUitOpen 0:a80f730d32a8 47
MikamiUitOpen 0:a80f730d32a8 48 float xn = myAdc_.Read();
MikamiUitOpen 0:a80f730d32a8 49 myDac.Write(xn); // モニタ用
MikamiUitOpen 0:a80f730d32a8 50 float yn = df_.Execute(xn); // ダウンサンプリング用 Anti-alias フィルタの実行
MikamiUitOpen 0:a80f730d32a8 51
MikamiUitOpen 0:a80f730d32a8 52 if (++count >= RATIO_)
MikamiUitOpen 0:a80f730d32a8 53 {
MikamiUitOpen 0:a80f730d32a8 54 buf_.Store(yn); // ダウンサンプリングされたデータをバッファへ格納
MikamiUitOpen 0:a80f730d32a8 55 count = 0;
MikamiUitOpen 0:a80f730d32a8 56 buf_.IfFullSwitch(); // バッファが満杯であればバッファを切り替える
MikamiUitOpen 0:a80f730d32a8 57 }
MikamiUitOpen 0:a80f730d32a8 58 }
MikamiUitOpen 0:a80f730d32a8 59
MikamiUitOpen 0:a80f730d32a8 60 int main()
MikamiUitOpen 0:a80f730d32a8 61 {
MikamiUitOpen 0:a80f730d32a8 62 SerialRxTxIntr rxTx(32, 460800); // PC との通信用
MikamiUitOpen 0:a80f730d32a8 63 Xfer tx(rxTx, N_FFT_/2+1); // PC に転送するためのオブジェクトの生成
MikamiUitOpen 0:a80f730d32a8 64 FftAnalyzer analyzer(N_FFT_); // FFT によるスペクトル解析オブジェクトの生成
MikamiUitOpen 0:a80f730d32a8 65
MikamiUitOpen 0:a80f730d32a8 66 Array<float> sn(N_FFT_, 0.0f); // スペクトル解析の対象となるデータ
MikamiUitOpen 0:a80f730d32a8 67 Array<float> db(N_FRAME_); // 解析結果:対数スペクトル [dB]
MikamiUitOpen 0:a80f730d32a8 68
MikamiUitOpen 0:a80f730d32a8 69 NVIC_SetPriority(ADC_IRQn, 0); // AD変換終了割り込みの優先度が最高
MikamiUitOpen 0:a80f730d32a8 70 NVIC_SetPriority(USART2_IRQn, 1);
MikamiUitOpen 0:a80f730d32a8 71
MikamiUitOpen 0:a80f730d32a8 72 bool ready = false; // スペクトルの計算終了で true
MikamiUitOpen 0:a80f730d32a8 73 bool okGo = false; // "GO" を受信したら true
MikamiUitOpen 0:a80f730d32a8 74
MikamiUitOpen 0:a80f730d32a8 75 myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て
MikamiUitOpen 0:a80f730d32a8 76 while (true)
MikamiUitOpen 0:a80f730d32a8 77 {
MikamiUitOpen 0:a80f730d32a8 78 // PC からのコマンドの解析
MikamiUitOpen 0:a80f730d32a8 79 if (rxTx.IsEol()) // 受信バッファのデータが有効になった場合の処理
MikamiUitOpen 0:a80f730d32a8 80 {
MikamiUitOpen 0:a80f730d32a8 81 string str = rxTx.GetBuffer();
MikamiUitOpen 0:a80f730d32a8 82 if (str == "FFTAnalyzer")
MikamiUitOpen 4:741883d4a075 83 //// rxTx.Tx("ACK\n"); // PC からの "FFTAnalyzer" に対して "ACK" を送信
MikamiUitOpen 4:741883d4a075 84 rxTx.TxString("ACK\n"); // PC からの "FFTAnalyzer" に対して "ACK" を送信
MikamiUitOpen 0:a80f730d32a8 85 else if (str == "GO") okGo = true; // データの転送要求あり
MikamiUitOpen 0:a80f730d32a8 86 }
MikamiUitOpen 0:a80f730d32a8 87
MikamiUitOpen 0:a80f730d32a8 88 if (buf_.IsFull()) // 入力データが満杯の場合,以下の処理を行う
MikamiUitOpen 0:a80f730d32a8 89 {
MikamiUitOpen 0:a80f730d32a8 90 for (int n=0; n<N_FFT_2_; n++) // フレームの後半のデータを前半に移動する
MikamiUitOpen 0:a80f730d32a8 91 sn[n] = sn[n+N_FRAME_];
MikamiUitOpen 0:a80f730d32a8 92 for (int n=0; n<N_FRAME_; n++) // フレームの後半には新しいデータを格納する
MikamiUitOpen 0:a80f730d32a8 93 sn[n+N_FFT_2_] = buf_.Get(n);
MikamiUitOpen 0:a80f730d32a8 94
MikamiUitOpen 0:a80f730d32a8 95 analyzer.Execute(sn, db); // スペクトル解析の実行
MikamiUitOpen 0:a80f730d32a8 96 tx.Convert(db); // スペクトル解析の結果を転送する形式に変換
MikamiUitOpen 0:a80f730d32a8 97 ready = true; // スペクトル解析終了
MikamiUitOpen 0:a80f730d32a8 98 }
MikamiUitOpen 0:a80f730d32a8 99
MikamiUitOpen 0:a80f730d32a8 100 // 転送要求がありスペクトル解析が終了している場合にデータを PC へ転送する
MikamiUitOpen 0:a80f730d32a8 101 if (okGo && ready)
MikamiUitOpen 0:a80f730d32a8 102 {
MikamiUitOpen 0:a80f730d32a8 103 tx.ToPC(); // データを PC へ転送
MikamiUitOpen 0:a80f730d32a8 104 ready = false;
MikamiUitOpen 0:a80f730d32a8 105 okGo = false;
MikamiUitOpen 0:a80f730d32a8 106 }
MikamiUitOpen 0:a80f730d32a8 107 }
MikamiUitOpen 4:741883d4a075 108 }