![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
オシロスコープ. このプログラムの説明は,CQ出版社「トランジスタ技術」の2021年10月号から開始された連載記事「STM32マイコンではじめるPC計測」の中にあります.このプログラムといっしょに使うPC側のプログラムについても同誌を参照してください.
Dependencies: Array_Matrix mbed SerialTxRxIntr DSP_ADDA_Dual
Revision 0:4440ad009afe, committed 2021-09-09
- Comitter:
- MikamiUitOpen
- Date:
- Thu Sep 09 08:47:03 2021 +0000
- Commit message:
- 1
Changed in this revision
diff -r 000000000000 -r 4440ad009afe Array_Matrix.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Array_Matrix.lib Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/MikamiUitOpen/code/Array_Matrix/#d3aa1ddb57e1
diff -r 000000000000 -r 4440ad009afe DSP_ADDA_Dual.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DSP_ADDA_Dual.lib Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/MikamiUitOpen/code/DSP_ADDA_Dual/#a3148d75c1ea
diff -r 000000000000 -r 4440ad009afe InputBuffer.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/InputBuffer.hpp Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,58 @@ +//-------------------------------------------------------- +// バッファの template クラス +// +// 2021/07/19, Copyright (c) 2021 MIKAMI, Naoki +//------------------------------------------------------- + +#ifndef INPUT_BUFFER_HPP +#define INPUT_BUFFER_HPP + +#include "Array.hpp" +using namespace Mikami; + +class InputBuffer +{ +public: + // コンストラクタ + explicit InputBuffer(int size, float initValue = 0) + : N_(size), buf_(2*size, initValue), index_(0), full_(false) {} + + // データを格納 + void Store(float data1, float data2) + { + buf_[index_] = data1; + buf_[N_+index_++] = data2; + } + + // バッファからデータの取り出し + Array<float> Get() const { return buf_; } + + // バッファが満杯で次の準備を行う + bool IsFullNext() + { + if (index_ < N_) return false; + + index_ = 0; + full_ = true; + return true; + } + + // バッファが満杯で,true を返す + bool IsFull() + { + bool temp = full_; + if (full_) full_ = false; + return temp; + } + +private: + const int N_; // バッファのサイズに対応する値 + Array<float> buf_; // バッファ + int index_; // 入力データのカウンタ + bool full_; // 満杯の場合 true + + // コピー・コンストラクタおよび代入演算子の禁止のため + InputBuffer(const InputBuffer&); + InputBuffer& operator=(const InputBuffer&); +}; +#endif // INPUT_BUFFER_HPP \ No newline at end of file
diff -r 000000000000 -r 4440ad009afe SerialTxRxIntr.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SerialTxRxIntr.lib Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/MikamiUitOpen/code/SerialTxRxIntr/#268977533f95
diff -r 000000000000 -r 4440ad009afe XferBase.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/XferBase.hpp Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,49 @@ +//--------------------------------------------------------------------- +// データを PC へ転送するための抽象基底クラス +// +// 2021/07/11, Copyright (c) 2021 MIKAMI, Naoki +//--------------------------------------------------------------------- + +#include <string> +#include "SerialRxTxIntr.hpp" +using namespace Mikami; + +#ifndef XFER_ABSTRACT_BASE_HPP +#define XFER_ABSTRACT_BASE_HPP + +class XferBase +{ +public: + // コンストラクタ + XferBase(SerialRxTxIntr& rxTx, int size) + : SIZE_(size), xn_(size), rxTx_(rxTx) {} + + // データを PC へ転送(0 ~ 10,000 の範囲の値を 2 文字で表すコード化を利用) + void ToPC(const float data[]) + { + Convert(data); + string str = ""; + for (int n=0; n<SIZE_; n++) + { + str += ((xn_[n] >> 7) & 0x7F) + 0x10; + str += (xn_[n] & 0x7F) + 0x10; + } + rxTx_.TxString(str+"\n"); + } + +protected: + const int SIZE_; // PC に送るデータの数 + Array<uint16_t> xn_; // PC に送るデータ + +private: + SerialRxTxIntr& rxTx_; + + // データを転送する際の形式に変換 + // data 元のデータ + virtual void Convert(const float data[]) = 0; + + // コピー・コンストラクタおよび代入演算子の禁止のため + XferBase(const XferBase&); + XferBase& operator=(const XferBase&); +}; +#endif // XFER_ABSTRACT_BASE_HPP \ No newline at end of file
diff -r 000000000000 -r 4440ad009afe XferWaveform.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/XferWaveform.hpp Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,39 @@ +//--------------------------------------------------------------------- +// 波形データを PC へ転送するための XferBase の派生クラス +// +// 2021/07/11, Copyright (c) 2021 MIKAMI, Naoki +//--------------------------------------------------------------------- + +#include "XferBase.hpp" + +#ifndef XFER_WAVEFORM_DERIVED_HPP +#define XFER_WAVEFORM_DERIVED_HPP + +class XferWaveform : public XferBase +{ +public: + // コンストラクタ + XferWaveform(SerialRxTxIntr& rxTx, int size) + : XferBase(rxTx, size) {} + +private: + // 転送すべきデータを転送する形式に変換 + // -1 <= xIn[] <= 1 + // 対応関係:1 => 10000, -1 => 0 + virtual void Convert(const float xIn[]) + { + static const float FACTOR = 5000.0f; + for (int n=0; n<SIZE_; n++) + { + float x = FACTOR*(xIn[n] + 1.0f); + if (x > 10000) x = 10000; + if (x < 0) x = 0; + xn_[n] = (uint16_t)x; + } + } + + // コピー・コンストラクタおよび代入演算子の禁止のため + XferWaveform(const XferWaveform&); + XferWaveform& operator=(const XferWaveform&); +}; +#endif // XFER_WAVEFORM_DERIVED_HPP \ No newline at end of file
diff -r 000000000000 -r 4440ad009afe main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,64 @@ +//--------------------------------------------------------------------- +// オシロスコープ (Nucleo-F446RE 用) +// ● 入力 A0: チャンネル1,A1 チャンネル2 +// +// 2021/07/19, Copyright (c) 2021 MIKAMI, Naoki +//--------------------------------------------------------------------- + +#include <string> +#include "DSP_AdcDualIntr.hpp" +#include "InputBuffer.hpp" +#include "XferWaveform.hpp" +using namespace Mikami; + +#ifndef __STM32F446xx_H +#error "Use Nucleo-F446RE" +#endif + +const int N_FRAME_ = 1000; // 1フレーム当たり標本化するデータ数 + +DspAdcDualIntr myAdc_(100, A0, A1); +InputBuffer buf_(N_FRAME_); // AD の結果を保存するバッファ + +// ADC 変換終了割り込みに対する割り込みサービス・ルーチン +void AdcIsr() +{ + float sn1, sn2; + myAdc_.Read(sn1, sn2); + buf_.Store(sn1, sn2); // バッファへ格納 + if (buf_.IsFullNext()) // バッファが満杯になったら ADC 割り込みを禁止する + myAdc_.DisableIntr(); +} + +int main() +{ + SerialRxTxIntr rxTx; // PC との通信用,最初は 9600 baud + XferWaveform tx(rxTx, 2*N_FRAME_); // PC に転送するためのオブジェクトの生成 + + myAdc_.SetIntrVec(&AdcIsr); // AD変換終了割り込みの割り当て + myAdc_.DisableIntr(); + while (true) + { + // PC からのコマンドの解析 + if (rxTx.IsEol()) // 受信バッファのデータが有効になった場合の処理 + { + string str = rxTx.GetBuffer(); + if (str == "Oscilloscope") + { + rxTx.TxString("ACK\n"); // PC からの "Oscilloscope" 受信に対して"ACK" を送信 + wait_ms(10); + rxTx.Baud(460800); // 以降は 460,800 baud + } + else if (str.substr(0, 2) == "GO") + { + // str の [2..5] の内容:標本化周波数 + int fs = atoi(str.substr(2, 4).c_str()); // 標本化周波数 + myAdc_.SetFs(fs); // 標本化周波数再設定 + myAdc_.EnableIntr(); // ADC 割り込みを有効にする + } + } + + if (buf_.IsFull()) + tx.ToPC(buf_.Get()); // データを PC へ転送 + } +} \ No newline at end of file
diff -r 000000000000 -r 4440ad009afe mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Thu Sep 09 08:47:03 2021 +0000 @@ -0,0 +1,1 @@ +https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400 \ No newline at end of file