ファンクション・ジェネレータ

Dependencies:   mbed SerialTxRxIntr MyTicker7 Array_Matrix

Committer:
MikamiUitOpen
Date:
Sat Oct 17 10:05:58 2020 +0000
Revision:
0:17c762b41fc7
Child:
1:ea5aa7f3d68c
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:17c762b41fc7 1 //----------------------------------------------------------------------
MikamiUitOpen 0:17c762b41fc7 2 // ファンクション・ジェネレータ (Nucleo-F446RE 用)
MikamiUitOpen 0:17c762b41fc7 3 //
MikamiUitOpen 0:17c762b41fc7 4 // 設定できる項目
MikamiUitOpen 0:17c762b41fc7 5 // 波形の種類: 正弦波,矩形波,合成矩形波(フーリエ級数の5倍波までの和)
MikamiUitOpen 0:17c762b41fc7 6 // 振幅: 0.00 ~ 1.00 倍
MikamiUitOpen 0:17c762b41fc7 7 // 周波数: 10 Hz ~ 10 kHz
MikamiUitOpen 0:17c762b41fc7 8 // ノイズ付加の有無
MikamiUitOpen 0:17c762b41fc7 9 // 標本化間隔:2.5 μs
MikamiUitOpen 0:17c762b41fc7 10 // 使用タイマ:TIM7
MikamiUitOpen 0:17c762b41fc7 11 // 信号出力のピン: A2
MikamiUitOpen 0:17c762b41fc7 12 // 同期信号出力のピン: A5
MikamiUitOpen 0:17c762b41fc7 13 //
MikamiUitOpen 0:17c762b41fc7 14 // このプログラムの前のバージョン:F446_FunctionGenerator_7
MikamiUitOpen 0:17c762b41fc7 15 //
MikamiUitOpen 0:17c762b41fc7 16 // PC 側のプログラム
MikamiUitOpen 0:17c762b41fc7 17 // F446_FunctionGenerator
MikamiUitOpen 0:17c762b41fc7 18 //
MikamiUitOpen 0:17c762b41fc7 19 // 注意
MikamiUitOpen 0:17c762b41fc7 20 // PC から送信されるコマンド等が不正かどうかはチェックしていない
MikamiUitOpen 0:17c762b41fc7 21 //
MikamiUitOpen 0:17c762b41fc7 22 // 2020/10/17, Copyright (c) 2020 MIKAMI, Naoki
MikamiUitOpen 0:17c762b41fc7 23 //----------------------------------------------------------------------
MikamiUitOpen 0:17c762b41fc7 24
MikamiUitOpen 0:17c762b41fc7 25 #include "F446_DAC.hpp"
MikamiUitOpen 0:17c762b41fc7 26 #include "SerialRxTxIntr.hpp"
MikamiUitOpen 0:17c762b41fc7 27 #include "MyTicker7.hpp"
MikamiUitOpen 0:17c762b41fc7 28 #include "FastSin.hpp"
MikamiUitOpen 0:17c762b41fc7 29 #include "MSeq16.hpp"
MikamiUitOpen 0:17c762b41fc7 30 #include "IIR_Cascade.hpp"
MikamiUitOpen 0:17c762b41fc7 31 #include "CoefficientsIIR_Cascade.hpp"
MikamiUitOpen 0:17c762b41fc7 32 #include <cctype> // isalpha() で使用
MikamiUitOpen 0:17c762b41fc7 33 #pragma diag_suppress 870 // マルチバイト文字使用の警告抑制のため
MikamiUitOpen 0:17c762b41fc7 34
MikamiUitOpen 0:17c762b41fc7 35 using namespace Mikami;
MikamiUitOpen 0:17c762b41fc7 36
MikamiUitOpen 0:17c762b41fc7 37 const float T0_ = 2.5f; // 出力の標本化間隔: 2.5 μs
MikamiUitOpen 0:17c762b41fc7 38 const float TS_ = T0_*1.0e-6f;
MikamiUitOpen 0:17c762b41fc7 39 const float C0_ = 4.0f;
MikamiUitOpen 0:17c762b41fc7 40 const float C0_2_ = C0_/2.0f;
MikamiUitOpen 0:17c762b41fc7 41
MikamiUitOpen 0:17c762b41fc7 42 DacF446 dac_; // DA 変換器オブジェクト
MikamiUitOpen 0:17c762b41fc7 43 MyTicker7 timer_(T0_); // タイマ割り込み用クラスのオブジェクト,TIM7 を利用
MikamiUitOpen 0:17c762b41fc7 44 SerialRxTxIntr rxTx_; // Serial クラスの受送信割込み用オブジェクト
MikamiUitOpen 0:17c762b41fc7 45 DigitalOut syncOut_(A5); // 同期信号出力用
MikamiUitOpen 0:17c762b41fc7 46
MikamiUitOpen 0:17c762b41fc7 47 float phi_ = 0;
MikamiUitOpen 0:17c762b41fc7 48 float dPhi_ = C0_*1000*TS_; // 周波数決める変数,開始時は 1 kHz;
MikamiUitOpen 0:17c762b41fc7 49 float volume_ = 0.5f; // 出力の振幅を決める変数,開始時は 0.5
MikamiUitOpen 0:17c762b41fc7 50 bool sw_ = false; // 出力 ON/OFF のスイッチ,開始時は off
MikamiUitOpen 0:17c762b41fc7 51 float volNoize_ = 0.5f; // ノイズの大きさを決める変数
MikamiUitOpen 0:17c762b41fc7 52
MikamiUitOpen 0:17c762b41fc7 53 // ノイズ付加に関する関数等
MikamiUitOpen 0:17c762b41fc7 54 MSeq16 mSeq_;
MikamiUitOpen 0:17c762b41fc7 55 IirCascade filter_(ORDER_, hk_, G0_);
MikamiUitOpen 0:17c762b41fc7 56 float Noise() { return volNoize_*filter_.Execute(0.5f*mSeq_.Execute()); }
MikamiUitOpen 0:17c762b41fc7 57 float NoiseFree() { return 0; }
MikamiUitOpen 0:17c762b41fc7 58 float (*fpNoize[])() = { Noise, NoiseFree };
MikamiUitOpen 0:17c762b41fc7 59 float (*fpN)() = fpNoize[1]; // 起動時はノイズなし
MikamiUitOpen 0:17c762b41fc7 60
MikamiUitOpen 0:17c762b41fc7 61 // 発生する信号を定義する関数
MikamiUitOpen 0:17c762b41fc7 62 // 正弦波
MikamiUitOpen 0:17c762b41fc7 63 float Sin(float sinx) { return volume_*sinx + fpN(); }
MikamiUitOpen 0:17c762b41fc7 64 // 矩形波
MikamiUitOpen 0:17c762b41fc7 65 float Rect(float sinx)
MikamiUitOpen 0:17c762b41fc7 66 {
MikamiUitOpen 0:17c762b41fc7 67 float x = (sinx >= 0) ? volume_ : -volume_;
MikamiUitOpen 0:17c762b41fc7 68 return x + volNoize_*fpN();
MikamiUitOpen 0:17c762b41fc7 69 }
MikamiUitOpen 0:17c762b41fc7 70 // 矩形波(5倍波まで)
MikamiUitOpen 0:17c762b41fc7 71 float Compo(float sinx)
MikamiUitOpen 0:17c762b41fc7 72 {
MikamiUitOpen 0:17c762b41fc7 73 static const float ONE_3 = 1.0f/3.0f; // フーリエ合成で使用
MikamiUitOpen 0:17c762b41fc7 74 static const float ONE_5 = 0.2f; // フーリエ合成で使用
MikamiUitOpen 0:17c762b41fc7 75
MikamiUitOpen 0:17c762b41fc7 76 float sinx2 = sinx*sinx;
MikamiUitOpen 0:17c762b41fc7 77 float sin3x = (-4.0f*sinx2 + 3.0f)*sinx;
MikamiUitOpen 0:17c762b41fc7 78 float sin5x = ((16.0f*sinx2 - 20.0f)*sinx2 + 5.0f)*sinx;
MikamiUitOpen 0:17c762b41fc7 79
MikamiUitOpen 0:17c762b41fc7 80 return volume_*(sinx + ONE_3*sin3x + ONE_5*sin5x) + fpN();
MikamiUitOpen 0:17c762b41fc7 81 }
MikamiUitOpen 0:17c762b41fc7 82
MikamiUitOpen 0:17c762b41fc7 83 float (*fp[])(float x) = { Sin, Rect, Compo };
MikamiUitOpen 0:17c762b41fc7 84 float (*fpS)(float x) = fp[0]; // 起動時は正弦波
MikamiUitOpen 0:17c762b41fc7 85
MikamiUitOpen 0:17c762b41fc7 86 // タイマ割り込みに対する割込みサービス・ルーチン
MikamiUitOpen 0:17c762b41fc7 87 void TimerIsr()
MikamiUitOpen 0:17c762b41fc7 88 {
MikamiUitOpen 0:17c762b41fc7 89 float sinx = FastSin(phi_); // 基本波発生
MikamiUitOpen 0:17c762b41fc7 90 float yn = fpS(sinx); // 指定した信号を発生
MikamiUitOpen 0:17c762b41fc7 91
MikamiUitOpen 0:17c762b41fc7 92 // 同期信号出力
MikamiUitOpen 0:17c762b41fc7 93 syncOut_ = (sinx >= 0) ? 1 : 0;
MikamiUitOpen 0:17c762b41fc7 94
MikamiUitOpen 0:17c762b41fc7 95 if (sw_) dac_.Write(yn); // 出力:ON
MikamiUitOpen 0:17c762b41fc7 96 else dac_.Write(0.0f); // 出力:OFF
MikamiUitOpen 0:17c762b41fc7 97
MikamiUitOpen 0:17c762b41fc7 98 phi_ += dPhi_;
MikamiUitOpen 0:17c762b41fc7 99 if (phi_ >= C0_2_) phi_ = phi_ - C0_; // オーバーフロー防止
MikamiUitOpen 0:17c762b41fc7 100 }
MikamiUitOpen 0:17c762b41fc7 101
MikamiUitOpen 0:17c762b41fc7 102 int main()
MikamiUitOpen 0:17c762b41fc7 103 {
MikamiUitOpen 0:17c762b41fc7 104 // 以下の割り込み優先順位の設定を忘れないこと
MikamiUitOpen 0:17c762b41fc7 105 NVIC_SetPriority(TIM7_IRQn, 0);
MikamiUitOpen 0:17c762b41fc7 106 NVIC_SetPriority(USART2_IRQn, 1); // USART2 割り込み:次に優先
MikamiUitOpen 0:17c762b41fc7 107
MikamiUitOpen 0:17c762b41fc7 108 timer_.Attach(&TimerIsr); // タイマ割り込み設定
MikamiUitOpen 0:17c762b41fc7 109
MikamiUitOpen 0:17c762b41fc7 110 while (true) // PC からの指令に対応する処理
MikamiUitOpen 0:17c762b41fc7 111 {
MikamiUitOpen 0:17c762b41fc7 112 if (rxTx_.IsEol()) // 受信バッファのデータが有効になった場合の処理
MikamiUitOpen 0:17c762b41fc7 113 {
MikamiUitOpen 0:17c762b41fc7 114 string str = rxTx_.GetBuffer();
MikamiUitOpen 0:17c762b41fc7 115 for (int n=0; n<str.size(); n++) str[n] = toupper(str[n]);
MikamiUitOpen 0:17c762b41fc7 116 if (isalpha(str[0])) // 先頭が A ~ Z, a ~ z の場合
MikamiUitOpen 0:17c762b41fc7 117 {
MikamiUitOpen 0:17c762b41fc7 118 if (str == "FG")
MikamiUitOpen 0:17c762b41fc7 119 rxTx_.TxString("ACK\n"); // PC からの "FG" に対して "ACK" を送信する
MikamiUitOpen 0:17c762b41fc7 120
MikamiUitOpen 0:17c762b41fc7 121 if (str == "ON") sw_ = true;
MikamiUitOpen 0:17c762b41fc7 122 if (str == "OFF") sw_ = false;
MikamiUitOpen 0:17c762b41fc7 123
MikamiUitOpen 0:17c762b41fc7 124 if (str == "SIN") fpS = fp[0];
MikamiUitOpen 0:17c762b41fc7 125 if (str == "RECT") fpS = fp[1];
MikamiUitOpen 0:17c762b41fc7 126 if (str == "COMPO") fpS = fp[2];
MikamiUitOpen 0:17c762b41fc7 127
MikamiUitOpen 0:17c762b41fc7 128 if (str == "NSON") fpN = fpNoize[0];
MikamiUitOpen 0:17c762b41fc7 129 if (str == "NSOFF") fpN = fpNoize[1];
MikamiUitOpen 0:17c762b41fc7 130 }
MikamiUitOpen 0:17c762b41fc7 131 else // 先頭が A ~ Z, a ~ z 以外の場合
MikamiUitOpen 0:17c762b41fc7 132 {
MikamiUitOpen 0:17c762b41fc7 133 char c1 = str[0]; // 先頭の文字を取得
MikamiUitOpen 0:17c762b41fc7 134 float x = atof(str.substr(1, str.size()-1).c_str());
MikamiUitOpen 0:17c762b41fc7 135 if (x >= 0.0f)
MikamiUitOpen 0:17c762b41fc7 136 {
MikamiUitOpen 0:17c762b41fc7 137 if (c1 == '#') // 出力振幅の変更
MikamiUitOpen 0:17c762b41fc7 138 volume_ = x*0.9f;
MikamiUitOpen 0:17c762b41fc7 139 if (c1 == '$') // 周波数の変更
MikamiUitOpen 0:17c762b41fc7 140 {
MikamiUitOpen 0:17c762b41fc7 141 x = (x < 10) ? 10 : x;
MikamiUitOpen 0:17c762b41fc7 142 x = (x > 10000) ? 10000 : x;
MikamiUitOpen 0:17c762b41fc7 143 dPhi_ = C0_*x*TS_;
MikamiUitOpen 0:17c762b41fc7 144 }
MikamiUitOpen 0:17c762b41fc7 145 if (c1 == '%') // ノイズの大きさの変更
MikamiUitOpen 0:17c762b41fc7 146 volNoize_ = (x < 1.0f) ? x : 1.0f;
MikamiUitOpen 0:17c762b41fc7 147 }
MikamiUitOpen 0:17c762b41fc7 148 }
MikamiUitOpen 0:17c762b41fc7 149 }
MikamiUitOpen 0:17c762b41fc7 150 }
MikamiUitOpen 0:17c762b41fc7 151 }