デジタル・スイッチング・レギュレーター

現在、SW レギュレーターを組もうと思ったら、専用の IC を買えば済む、しかし、微妙に違う仕様のICが数限りなくあり、ベストな選択をする事が難しいし、数個購入するとなると、割高でもある。

とりあえずのゴールは、リチウムイオン電池の充電や、ブラシレスモーターの制御なのだが、専用 IC で組むとそれなりの値段になってしまうし、より細かい制御をしようと思うと、マイコンの助けも必要なので、1個のマイコンだけで、全ての制御を行う予定。

まず、「昇圧」は、電流の管理が必須で、誤るとドライバーを破壊するので、無難な「降圧」方式で実験してみた。

12 ビットの A/D コンバーターを使って、フィードバックを行い、指令電圧に追従させてみた。
まず、一番単純な制御で行ってみた。

IMG_0534ss

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 した時、かなりハンチングしているようで、原因が良く判らない・・・
IMG_0535ss
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 のセラミックコンデンサを入れたら、リップルはかなり小さくなり、これなら実用的と思える。
※電圧が低い場合にはゲインを抑えるように改修

IMG_0537ss
※三角波を出力したところ
これなら、まぁ許容できるかも・・

追記(2014/1/7):
トップのオン時、出力が振動するのは、リニアテクノロジーの資料を読んでたら、トップ側FETに並列にショットキーダイオードを入れる事で改善する事が判り、早速入れてみた、完全には無くならないが、確かに改善してる。
全体的にリップルも減った。