TOPに戻る

Raspberry Pi PicoとMOSFET ④ PWM 分周

 前回、wrapを使って、システム・クロック125MHzを1MHzに落としました。もう一つの分周器を使って、もっと周波数を下げます。

固定小数点形式

uint8_t div = 2;
uint8_t fract = 8;
pwm_set_clkdiv_int_frac(slice_num, div, fract);

 整数部分をdiv、小数点部分をfractとします。divは8ビットなので最大256、fractは4ビットなので、1が最小単位になり、0b0001は、

  0 * 1/2^1 + 0 * 1/2^2 + 0 * 1/2^3 + 1 * 1/2^4 = 1/16 = 0.0625

が最大分解能になります。

 fract =8は0b1000なので、

  1 * 1/2^1 + 0 * 1/2^2 + 0 * 1/2^3 + 0 * 1/2^4 = 1/2 = 0.5

 div=2なので合成すると2.5になります。したがって、1MHz/2.5=400kHzです。


#include "pico/stdlib.h"
#include <stdio.h>
#include "hardware/pwm.h"

int main() {
    stdio_init_all();
    printf("\nHello, PWM GP2/3\n");

    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(3, GPIO_FUNC_PWM);

    // Find out which PWM slice is connected to GPIO 0 (it's slice 0)
    uint slice_num = pwm_gpio_to_slice_num(2);

    // Set period of 10 cycles (0 to 3 inclusive)
    pwm_set_wrap(slice_num, 124);
    // Set channel A output high for one cycle before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 12);
    // Set initial B output high for three cycles before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 63);

    uint8_t div = 2;
    uint8_t fract = 8;
    pwm_set_clkdiv_int_frac(slice_num, div, fract);

    // Set the PWM running
    pwm_set_enabled(slice_num, true);

    return 0;
}

もう1セットPWMを起動

 GP2/3をスライス2で動作させています。GP4/5をスライス4で動かして波形を見ます。デューティ比はすべて20%にしました。

  スライス2とスライス4がそれぞれ同期しています。つまり、チャネルAとBは同じタイミングで起動されるということです。

 このずれはどこで生じるのでしょうか。最後のPWMをスタートさせる部分を入れ替えました。

// Set the PWM running
pwm_set_enabled(slice_num2, true);
pwm_set_enabled(slice_num, true);

 変わりませんでした。

pwm_set_mask_enabled

 この関数は、 複数のPWMスライスを同時に有効/無効にできます。

  static void pwm_set_mask_enabled (uint32_t mask)

 マスクはGP2、GP4をONにするため、0b00000110にしました。希望通り、波形の位置関係が同じになりました。

 マスクの使いかたは、下記のページを参照してください。

  Raspberry Pi Picoでプログラミング ⑰ gpioファンクション MASK

 プログラムです。


#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);

    // Find out which PWM slice is connected to GPIO 0 (it's slice 0)
    uint slice_num = pwm_gpio_to_slice_num(2);
    uint slice_num2 = pwm_gpio_to_slice_num(4);

    // Set period of 10 cycles (0 to 3 inclusive)
    pwm_set_wrap(slice_num, 1249);
    // Set channel A output high for one cycle before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 256);
    // Set initial B output high for three cycles before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 256);

    pwm_set_wrap(slice_num2, 1249);
    pwm_set_chan_level(slice_num2, PWM_CHAN_A, 256);
    pwm_set_chan_level(slice_num2, PWM_CHAN_B, 256);

    // Set the PWM running
    //pwm_set_enabled(slice_num, true);
    //pwm_set_enabled(slice_num2, true);
    pwm_set_mask_enabled(0b00000110);

    return 0;
}

連載 Raspberry Pi PicoとMOSFET

(1) MOSFETの特徴

(2) MOSFETを発振器でドライブ

(3) PWMのAPI

(4) PWM 分周

(5) NチャネルMOSFETをPicoからドライブ

(6) PチャネルMOSFETをPicoからドライブ


連載 Raspberry Pi Picoでプログラミング

(1) ラズパイ4の準備(1) USBブートの設定

(2) ラズパイ4の準備(2) 標準入出力の用意

(3) ラズパイ4の準備(3) LチカとHello, world!の実行

(4) ラズパイ4の準備(4) リモート環境の設定

(5) プログラミングの環境整備とLチカ

(6) Hello, World!

(7) 使用するピンと機能

(8) クロックの値の表示

(9) i2cscanner

(10) i2c APIと気圧センサLPS25

(11) i2c 温度センサTMP117

(12) i2c 湿度センサAHT20

(13) spi APIとA-DコンバータMCP3008

(14) spi A-DコンバータMCP3208

(15) gpioファンクション

(16) gpio スイッチを押すとLEDが点灯する STEP2

(17) gpioファンクション MASK