Raspberry Pi PicoとMOSFET ⑦ P/NチャネルMOSFETをPicoからドライブ<その1>
●PWM信号の反転
PWM出力の極性を設定する関数があります。一つのスライスにはAとBがあるので、両方を同時に設定できます。
static void pwm_set_output_polarity (uint slice_num, bool a, bool b)
trueで反転します。
Aはパルスは正、Bは反転させました。デューティ比はduty_factor、デッド・タイムはdead_timeで設定します。
#include "pico/stdlib.h"
#include <stdio.h>
#include "hardware/pwm.h"
int main() {
stdio_init_all();
printf("\nHello, PWM GP2/3,GP4/5\n");
gpio_set_function(2, GPIO_FUNC_PWM);
gpio_set_function(3, GPIO_FUNC_PWM);
gpio_set_function(4, GPIO_FUNC_PWM);
gpio_set_function(5, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(2);
uint slice_num2 = pwm_gpio_to_slice_num(4);
uint16_t divCounter = 12500; // max 2^16 = 65536
pwm_set_wrap(slice_num, divCounter-1); // 10kHz
uint8_t div = 10;
uint8_t fract = 0;
pwm_set_clkdiv_int_frac(slice_num, div, fract); // 1kHz
// duty
float duty_factor = 0.5;
float dead_time = 0.95;
pwm_set_chan_level(slice_num, PWM_CHAN_A, (int)divCounter * duty_factor * dead_time);
pwm_set_chan_level(slice_num, PWM_CHAN_B, (int)divCounter * duty_factor);
pwm_set_output_polarity(slice_num, false, true); // A B
// Set the PWM running
pwm_set_mask_enabled(0b00000010);
return 0;
}
A(波形上の黄色)の立ち上がりとB(波形下の緑色)の立ち下がりは一致しています。
Aの立ち下がりは、Bの立ち下がりより2.5%早くなっています。
●実際にスイッチングする
電圧は、Vs=8.88V、Vdd=9.74Vです。
float dead_time = 0.9; にしてデッド・タイムを広げました。
●ゲートの波形
画面中央の位置がトリガしている場所です。黄色はA(GP2)で立ち上がりをNチャネルMOSFETのONとして利用、下の緑色はB(GP)は立ち下がりをPチャネルMOSFETのONとして利用しています。
ONのタイミングはまったく同じです。OFFのタイミングは、NチャネルMOSFETが早めです。
●ドレインの波形
上の黄色がNチャネルMOSFETのドレイン、下の緑がPチャネルMOSFETのドレインです。
NチャネルMOSFETのONとはLowの状態で、PチャネルMOSFETのONとはHighの状態です。
信号の終わり部分のデッド・タイムは作れましたが、最初の部分は同時です。この部分をずらす方法を考えます。
●起動部分を変更する
設定が終わって、最後の起動部分では、MASK機能を使ってGP2/GP3を同時に起動しています。というかスライスが同じなので、同時に起動されます。
// Set the PWM running
pwm_set_mask_enabled(0b00000010);
これは、
pwm_set_enabled(slice_num, true);
でも同じです。
GP2/GP3のスライスとGP4/GP5のスライスを同時に立ち上げるには、
pwm_set_mask_enabled(0b00000110);
のようにMASKの機能を利用します。
pwm_set_enabled(slice_num, true);
pwm_set_enabled(slice_num2, true);
のように個別にスライスを起動すると、nsオーダでは、ずれます。
pwm_set_enabled(slice_num, true);
<Wait>
pwm_set_enabled(slice_num2, true);
のように、わずかに時間をずらして起動することを考えます。
●出力ピンはGP2とGP5
GP2/GP3とGP4/GP5の二つのスライスを利用します。実際はGP2とGP5のピンから波形を得ます。
周波数は1kHzです。
#include "pico/stdlib.h"
#include <stdio.h>
#include "hardware/pwm.h"
int main() {
stdio_init_all();
printf("\nHello, PWM GP2/3,GP4/5\n");
gpio_set_function(2, GPIO_FUNC_PWM);
gpio_set_function(3, GPIO_FUNC_PWM);
gpio_set_function(4, GPIO_FUNC_PWM);
gpio_set_function(5, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(2);
uint slice_num2 = pwm_gpio_to_slice_num(4);
uint16_t divCounter = 12500; // max 2^16 = 65536
pwm_set_wrap(slice_num, divCounter-1); // 10kHz
pwm_set_wrap(slice_num2, divCounter-1); // 10kHz
uint8_t div = 10;
uint8_t fract = 0;
pwm_set_clkdiv_int_frac(slice_num, div, fract); // 1kHz
pwm_set_clkdiv_int_frac(slice_num2, div, fract); // 1kHz
// duty
float duty_factor = 0.2;
float dead_time = 0.6;
// GP2
pwm_set_chan_level(slice_num, PWM_CHAN_A, (int)divCounter * duty_factor);
pwm_set_chan_level(slice_num2, PWM_CHAN_B, (int)divCounter * duty_factor * dead_time);
// GP5
pwm_set_output_polarity(slice_num2, false, true); // A B
// Set the PWM running
pwm_set_enabled(slice_num, true);
sleep_us(0.1);
pwm_set_enabled(slice_num2, true);
return 0;
}
回路図です。Picoの出力GP2はINaへ、GP5はINbにつなぎました。
●ゲート信号
黄色がINa、緑がINbです。デューティ比20%で波形を作っています。
sleep_us(0.1);
は、引数の数値通りうまく働いていませんが、デッド・タイムは十分に確保できました。
時間軸を拡大します。
●ドレインの波形
負荷のつながったドレインの電圧です。Vd=9.75V、Vs=8.9Vの条件です。
時間軸を短くします。デッド・タイムが有効に効いていることが確認できました。
●INxのおなじ信号で駆動
INaをIR4427の2ピンと4ピンにつなぎます。
黄色はNチャネルMOSFET、緑色はPチャネルMOSFETです。デッド・タイムが確保できていません。
INbをIR4427の2ピンと4ピンにつなぎます。
黄色はNチャネルMOSFET、緑色はPチャネルMOSFETです。デッド・タイムが確保できていません。
今回の信号発生方法では、デッド・タイムを確保できないことがわかりました。
ハーフブリッジ回路の場合、デッド・タイムがないと、PチャネルMOSFET(ハイサイド)がONしたとき、NチャネルMOSFET(ローサイド)を通して貫通電流が流れ、MOSFETが破壊されます。