現在、SW レギュレーターを組もうと思ったら、専用の IC を買えば済む、しかし、微妙に違う仕様のICが数限りなくあり、ベストな選択をする事が難しいし、数個購入するとなると、割高でもある。
とりあえずのゴールは、リチウムイオン電池の充電や、ブラシレスモーターの制御なのだが、専用 IC で組むとそれなりの値段になってしまうし、より細かい制御をしようと思うと、マイコンの助けも必要なので、1個のマイコンだけで、全ての制御を行う予定。
まず、「昇圧」は、電流の管理が必須で、誤るとドライバーを破壊するので、無難な「降圧」方式で実験してみた。
12 ビットの A/D コンバーターを使って、フィードバックを行い、指令電圧に追従させてみた。
まず、一番単純な制御で行ってみた。
A/D チャネル0: 10K のボリューム(指令電圧)
A/D チャネル1: 出力電圧(1/6)
A/D チャネル2: 入力電圧(1/6)
A/D の入力には、AD8656 をバッファアンプに使い、1/6 に分圧して、基準電圧には 2.5V のリファレンスを使った、電源は 12V 。
※写真のボードでは、保護抵抗やリミッターを省いているが、付けた方が無難だろう。
パワー MOS-FET は、IR 社の IRLR3114 、ドライバーはリニアテクノロジーの LTC4442
LTC4442 の制御電圧は FET のゲート電圧を考えて 10V 程度を供給している。
※バイパスコンデンサをしっかり配置しないと、正常に動作しない、使うのにコツがいるようだ、ハイサイド側が ON した時、かなりハンチングしているようで、原因が良く判らない・・・
LTC4442 は、上下の FET が貫通しないような工夫がしてあるので、デッドタイムの制御はしなくていいのでコンビニエンスだ・・(それが正しく働いてなくて、ハンチングしているのかも・・)
RX63T は、PWM タイマーの周波数として 100MHz を扱えるので、9 ビットの分解能として、187.5KHz (96MHz / 512) を実現している。
インダクターは TDK の 22uH 電圧にもよるけど、このサイズ(容量)なら 500mA 程度なら取り出せるだろうか・・
メインループは、1000Hz なので、応答は、そんなに高速では無いが、サンプリング方式では、どのみち限界がある。
ソースコード一式を、github にプッシュしてある。
-----
今後の課題として、もっと違った制御法を試して、ステップ応答などの特性を評価してみないといけない。
追記 (2014/1/1)(2014/1/2):
・比例制御から、もう少し違う制御にしてみた・・
・A/D の変換タイミングを、PWM に同期させてみた。
・ハイサイドの FET をチャージポンプで駆動している為、パルスが無くならないように、最低値と最大値を制限。
・サンプリングは 10KHz にした。
bool up = true; int32_t base_gain = 651; int32_t high_gain = 1500; int32_t low_limit = 10; int32_t high_limit = 500; int32_t cpv = low_limit; while(1) { adc_.start(0b00000111); cmt_.sync(); // A/D 変換開始 adc_.sync(); // int32_t ref = static_cast<int32_t>(adc_.get(0)); // 指令電圧 int32_t out = static_cast<int32_t>(adc_.get(1)); // 出力電圧 int32_t inp = static_cast<int32_t>(adc_.get(2)); // 入力電圧 // 三角波 if(up) { ref += 20; } else { ref -= 20; } if(ref > 1700) { up = false; ref = 1700; } else if(ref < 200) { up = true; ref = 200; } int32_t dif = ref - out; // 誤差 // PWM の制御量に対するスレッショルド if(std::abs(dif) < 40) { if(dif < 0) --cpv; else ++cpv; } else { // 基本的な制御量の計算 int32_t d = dif * 512 / inp; // 指令電圧、入力電圧の比に応じて、ゲインを制御 // ・指令電圧が低い場合はゲインを小さくする int32_t g = (high_gain - base_gain) * ref / inp; g += base_gain; if(d < 0) g -= g / 4; cpv += d * g / 4096; } // 出力リミッター if(cpv < low_limit) cpv = low_limit; else if(cpv > high_limit) cpv = high_limit; gpt_.set_a(cpv); uint16_t ofs = (512 - cpv) / 2; gpt_.set_ad_a(cpv + ofs); // A/D 変換開始タイミング
↑はメインループ(サンプリング)部分
※実用的には過電流保護なども必要。
出力に 1000uF のコンデンサと 10uF のセラミックコンデンサを入れたら、リップルはかなり小さくなり、これなら実用的と思える。
※電圧が低い場合にはゲインを抑えるように改修
追記(2014/1/7):
トップのオン時、出力が振動するのは、リニアテクノロジーの資料を読んでたら、トップ側FETに並列にショットキーダイオードを入れる事で改善する事が判り、早速入れてみた、完全には無くならないが、確かに改善してる。
全体的にリップルも減った。