STM32 マイコンを使っていわゆるデジタル電源を作ってみました。 何がデジタルかというと,スイッチング電源の出力電圧をフィードバックして スイッチングのデューティ比を決める部分,がデジタル化(ソフトウェア化)されています。
回路図を下図に示します。
まず,P-ch の FET とファストリカバリダイオード,コイル,コンデンサで降圧コンバータ(Buck コンバータ)を構成しています。
残りの 3 つのトランジスタは,FET を駆動するためのゲート駆動回路(プッシュプル型)になっています。
NUCLEO-F446RE は STMicroelectronics 社の MCU,STM32F446RE(ARM Cortex-M4 core with DSP and FPU,180 MHz)を搭載したマイコンボードです。
電源の出力電圧をフィードバックするために,抵抗分圧して,マイコンの AD 変換器に入力しています(ADC1_IN0)。 また,FET のスイッチングを制御するために,マイコンのタイマ出力(TIM1_CH1)をゲート駆動回路に接続しています。
実際に作った回路の写真です。
プログラム全体の動きとしては以下のようになっています。
AD 変換完了割り込み部分のプログラムを以下に示します。 AD 変換の結果(出力電圧の現在値)に基づいて,PI 制御で操作量(デューティ比)を決定しています。
PWM のキャリア周波数は 100 kHz で,タイマのクロックソースは 180 MHz なので,PWM の 1 周期は 1800 カウントになっています。
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
const float ref = 9.0f * 10.0f / (10.0f + 33.0f) / 3.3f * 4095.0f; // 目標値(9 V)
const float kp = 1.0f; // 比例ゲイン
const float ki = 0.1f; // 積分ゲイン
static float s = 0.0f; // 偏差の積分
float u; // 操作量
float x; // 現在値
float e; // 偏差
// 現在値(出力電圧)の取得
x = HAL_ADC_GetValue(&hadc1);
// 偏差の計算
e = ref - x;
// 積分項の計算
s += e;
// 操作量の計算(PI 制御)
u = kp * e + ki * s;
// リミット演算
if (u < 0.0f)
{
u = 0.0f;
}
if (u > 1800.0f)
{
u = 1800.0f;
}
// 操作量の反映
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (int)u);
}
無負荷時から負荷をスイッチオンしたときの出力電圧波形を下図に示します。 一瞬電圧が下がっていますが,すぐに回復していることがわかります。 プログラム中の制御パラメータを変えて,応答特性がどう変化するか,簡単に試すことができます。