QSPICEでADC

えー特段何もありませんが、自身の備忘録です。 ひとつ前のクソ記事で、回路シミュレータを触るだけ触っていましたが、 どうやら、QSPICEはC++で素子の挙動を記述してシミュレーションできるらしく、 それでADCをやってみました。 参考はYoutubeに転がっていた外国人の方の動画をみたり、公式のやつを見たりしてやった感じです。

そういえば全然話それるけど、 総合機械工学科では回路をあんまりやらなかったが、こういうシミュレーション授業がもっとあっても良かったなぁと思う。

ADC

手順は、公式のドキュメントの通りですので、下記画像の通りに実行できれば終了です。僕の存在意義とは....

さっそく、ファイルメニューの「New」から「schematic」を作成し、まず最初に何もない状態で保存しておきます

その後下記画像の通りに操作することで、素子のパッケージの枠を作成します。

こんな感じ↓

そうしたら、灰色の枠の中で、右クリックすることで下記のメニューが出てくるので、「Add port」を選択し、枠の淵の部分に端子を作成します。

端子を作成すると、名前を付けられるので、

  • 入力 :「Input」

  • 出力:「Output」

  • 基準電圧:「Vref」

  • 動作のクロック:「clock」

として名前を付けておきます。

そうしたら、この素子のシンボルタイプをΦ(.dll)にしておきます。編集するにあたっては、ショートカットキー「F3」で「Symbol Property」を開くと便利です。

そうしたら、また枠内で右クリックし、「Port Type」からポートのIOピンアサインを行います。

次に「Data Type」から、入出力するデータの型を決めておきます。

最後に、また右クリックからの「C++ Interface/Create C++ Template」で素子のピンアサインに関するC++のコードを自動生成します。(CubeMXやんけ)

下記のようなコードが生成されれば成功です

// Automatically generated C++ file on Thu Sep  7 00:29:45 2023
// To build with Digital Mars C++ Compiler:
//    dmc -mn -WD adc_test_x1.cpp kernel32.lib
union uData{
   bool b;
   char c;
   unsigned char uc;
   short s;
   unsigned short us;
   int i;
   unsigned int ui;
   float f;
   double d;
   long long int i64;
   unsigned long long int ui64;
   char str;
   unsigned char bytes;
};

// int DllMain() must exist and return 1 for a process to load the .DLL // See https://docs.microsoft.com/en-us/windows/win32/dlls/dllmain for more information. int __stdcall DllMain(void module, unsigned int reason, void reserved) { return 1; }

// #undef pin names lest they collide with names in any header file(s) you might include. //#undef Input //#undef Vref //#undef clock //#undef Output

//ここらへんに変数宣言

extern "C" __declspec(dllexport) void adc_test_x1(void *opaque, double t, union uData data){ double Input = data[0].d; // input double Vref = data[1].d; // input bool clock = data[2].b; // input double &Output = data[3].d; // output // Implement module evaluation code here: //ここに処理内容をかく }

ここまでできたら、あとは処理内容を書いて、回路を完成させるだけです。

まず、変数宣言部分に、下記のコードを追記します。

//ADC resolution (Arduino:10 STM32:12)
int Arduino_resolution=10;
int STM_resolution=12;
int resolution=2;//今回はこれをつかう
//past Val for time discrete
int pre_clock = 0;
int pre_Output = 0;

そして、処理内容のところに下記コードを追記します

   if(clock == 1 && pre_clock == 0){ //クロックが0→1に変化した時=立ち上がり時のみ
      pre_Output=(int) (Input/Vref * (2<<resolution-1));
   }
   Output = pre_Output;
   pre_clock=clock;

最後に回路です。

pulseの引数は、左から、「最小値」「最大値」「遅延時間」「立ち上がり時間」「立下り時間」「ピークを維持する時間」「1周期の時間」「何回」です。

したがって、Inputでは、pulseと書いてありますが、引数によってランプ入力になってます

この状態で、3msの過渡応答をシミュレートすると、下記のような波形が出てきます。

クロックの立ち上がり時にのみ、分解能に応じた出力の階段が確認できました。わーい

次回:PWM出力

お楽しみに