Nucleo-F446 によるグラフィック・イコライザ.DA変換器にデータを送る際は 4 倍にアップ・サンプリング.
Dependencies: mbed SerialTxRxIntr F446_AD_DA_Multirate
Diff: main.cpp
- Revision:
- 0:0312aa1893cf
- Child:
- 1:4c6a67b336d1
diff -r 000000000000 -r 0312aa1893cf main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Jun 05 11:14:21 2018 +0000 @@ -0,0 +1,80 @@ +//---------------------------------------------------------------------- +// 遮断周波数可変 IIR フィルタ(LPF, HPF) +// +// PC 側のプログラム: F446_LPF_HPF_Variable: +// 周波数特性が PC の画面に表示され,その上のカーソルをマウスでドラッグすることで, +// 遮断周波数を変えられる +// +// 2018/06/04, Copyright (c) 2018 MIKAMI, Naoki +//---------------------------------------------------------------------- + +#include "main.hpp" +using namespace Mikami; + +// 出力標本化周波数を4倍にするオブジェクト +F446_Multirate myAdDa_(ORDER_SM_, HK_SM_, G0_SM_); +// Serial クラスの受信割込み用オブジェクト +SerialRxIntr rx_; + +int main() +{ + myAdDa_.Start(FS_); // ADC 変換終了割り込みを使えるようにする + + // 以下の割り込み優先順位の設定を忘れないこと + NVIC_SetPriority(ADC_IRQn, 0); // ADC 終了割り込み:最優先 + NVIC_SetPriority(USART2_IRQn, 1); // USART2 割り込み:次に優先 + + // グラフィック・イコライザ用パラメータ等の定義 + const int BANDS = 9; + const float Q_VAL = 1.0f/sqrtf(2.0f); // フィルタの Q 値 + GrEqParams params(BANDS, FS_); // グラフィック・イコライザで使うフィルタの + // 係数を計算するオブジェクト + BiquadGrEq biquad[BANDS]; // グラフィック・イコライザで使うフィルタ + float f0[BANDS]; // 中心周波数(ピーキング・フィルタの場合) + for (int n=0; n<BANDS; n++) f0[n] = 62.5f*powf(2, n); + for (int n=0; n<BANDS; n++) + biquad[n].SetCoefficients(params.Get(n, f0[n], 0, Q_VAL)); + + bool on = true; // フィルタ処理の有効/無効を決める変数 + + while (true) + { + //------------------------------------------------------------ + // ここにディジタルフィルタ等の処理を記述する + float xn = myAdDa_.Input()*0.25f; // 入力 + float yn = xn; + for (int n=0; n<BANDS; n++) yn =biquad[n].Execute(yn); + // 実行時間:約 7 μs + myAdDa_.Output(on ? yn : xn); // 出力 + //------------------------------------------------------------ + + //------------------------------------------------------------ + // PC からの指令に対応する処理 + if (rx_.IsEol()) // 受信バッファのデータが有効になった場合の処理 + { + string str = rx_.GetBuffer(); + if (str.find("ENQ") != string::npos) + rx_.Tx("ACK"); // "ACK" を送り返す + else if (str.find("ON") != string::npos) + on = true; // フィルタ処理を有効にする + else if (str.find("OFF") != string::npos) + on = false; // フィルタ処理を無効にする + else if (str.find("FLAT") != string::npos) + for (int n=0; n<BANDS; n++) // フィルタの特性を平坦にする + biquad[n].SetCoefficients(params.Get(n, f0[n], 0, Q_VAL)); + // "ENQ", "ON", "OFF", "FLAT" 以外は float 型の数値に対応する文字列とし + // て処理を行う + else + { + // 最初の文字はフィルタの番号 + int k = atoi(str.substr(0, 1).c_str()); // フィルタの番号 + // 次の文字からは dB 値 + str.erase(0, 1); + float db = atof(str.c_str()); + biquad[k].SetCoefficients(params.Get(k, f0[k], db, Q_VAL)); + } + } + // PC からの指令に対応する処理はここまで + //------------------------------------------------------------ + } +}