えー特段何もありませんが、自身の備忘録です。 ひとつ前のクソ記事で、回路シミュレータを触るだけ触っていましたが、 どうやら、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出力
お楽しみに