Raspberry Pi PicoでPWM出力

ピン機能の設定

  • gpio_set_function()でピン機能をGPIO_FUNC_PWMに設定する。
  • RP2040には8つのPWMスライスがあり、各スライスにA/Bの2つのPWMチャンネルがある。
  • つまり最大8×2=16チャンネルのPWM出力が可能。
  • PWM周波数や分解能はスライスごとに設定できる。
  • 偶数番(2n)のGPIOはAチャンネル、奇数番(2n+1)のGPIOはBチャンネルで、スライス番号は n % 8
  • スライス番号はpwm_gpio_to_slice_num()でも取得できる。

PWM周波数の設定

  • Raspberry Pi Picoのメインクロックは125MHz。
  • pwm_set_clkdiv()で分周比を設定する。(0~256未満の実数値で設定)
  • pwm_set_wrap()でPWMの分解能を設定する。

メインクロックをsysclock、PWM分解能の設定値をwrap、分周比をclkdiv とすると、
PWM周波数 f = sysclock / ((wrap+1) ⋅ clkdiv) より
clkdiv = sysclock / ((wrap+1) ⋅ f )

例えばPWM周波数を250Hzに、PWMの分解能を11ビット(0~2047)に設定したい場合、
sysclock = 125,000,000Hz、wrap = 2047、f=250Hz より
分周比 clkdiv = 244.140625 となる。ただし、clkdiv は実際には1/16単位に丸められる。

デューティーの設定

  • デューティー(High期間)の設定にはpwm_set_chan_level()を用いる。
  • PWM出力の有効/無効はpwm_set_enabled()で設定する。

サンプルコード (Arduino環境用)

#include <hardware/pwm.h>

void setup()
{
    // GP2とGP3のピン機能をPWMに設定
    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(3, GPIO_FUNC_PWM);

    // GP2(とGP3)のPWMスライスを取得
    uint slice_num = pwm_gpio_to_slice_num(2);

    // PWM周期を設定
    pwm_set_clkdiv(slice_num, 244.140625);
    pwm_set_wrap(slice_num, 2047);
    
    // チャンネルA(GP2)とチャンネルB(GP3)のPWMのHigh期間を設定
    pwm_set_chan_level(slice_num, PWM_CHAN_A, 1024);
    pwm_set_chan_level(slice_num, PWM_CHAN_B, 512);
    
    // PWM出力イネーブル
    pwm_set_enabled(slice_num, true);
}

void loop()
{
  
}

参考