初めてのRaspberry Pi Pico ⑰ C言語 PWM その2


 前回はPWM信号を作りましたが、とても高い周波数でした。ここでは、LEDのほんわか点灯などに適した500Hzから1kHzの周波数にします。

前回のプログラムに追加

GPIO2,3に出力するのは変わっていません。

/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

// Output PWM signals on pins 2 and 3

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

int main() {
    stdio_init_all();  // need when UART 

    printf("\nstart GPIO 2,3\n");

    // Get some sensible defaults for the slice configuration. By default, the
    // counter is allowed to wrap over its maximum range (0 to 2**16-1)
    pwm_config config = pwm_get_default_config();
    // Set divider, reduces counter clock to sysclock/this value
    float div = 3;
    pwm_config_set_clkdiv(&config, div);

    /// \tag::setup_pwm[]
    // Tell GPIO 0 and 1 they are allocated to the PWM
    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(3, GPIO_FUNC_PWM);

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

    // Set period of 4 cycles (0 to 5 inclusive)
    pwm_set_wrap(slice_num, 5);
    // Set channel A output high for one cycle before dropping
    // pwm_set_chan_level(slice_num, PWM_CHAN_A, 1);
    // Set initial B output high for three cycles before dropping
    // pwm_set_chan_level(slice_num, PWM_CHAN_B, 5);
    // Set the PWM running
    //    pwm_set_enabled(slice_num, true);
    /// \end::setup_pwm[]

    // Load the configuration into our PWM slice, and set it running.
    pwm_init(slice_num, &config, true);

    pwm_set_both_levels(slice_num, pow(2,16)*0.5, pow(2,16)*0.9);
}

 分周するdiv変数に3を代入して、configにセットします。

    pwm_config config = pwm_get_default_config();
    // Set divider, reduces counter clock to sysclock/this value
    float div = 3;
    pwm_config_set_clkdiv(&config, div);

 その変更を有効にし、PWMを動かします。

    // Load the configuration into our PWM slice, and set it running.
    pwm_init(slice_num, &config, true);

へんな分周

 divが変です。いろいろ数字を変化させて、オシロスコープでその周波数を読みました。

 Arduino UNOのようなPWM周波数の500Hzや1kHzに近い設定できるのですが、設定値divと周波数はまったく比例していません。

ディーティ比

 最後の記述はデューティ比を設定しています。1周期が0から0xffffなので、highになる区間を比率で設定しています。引数はスライス番号、Aチャネル、Bチャネルです。
 GPIO2はスライス0のAチャネル、GPIO3はスライス0のBチャネルに割り当てられています。

    pwm_set_both_levels(slice_num, pow(2,16)*0.5, pow(2,16)*0.9);

 ぴったりの値が測定できました。