現在、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に並列にショットキーダイオードを入れる事で改善する事が判り、早速入れてみた、完全には無くならないが、確かに改善してる。
全体的にリップルも減った。

