LoginSignup
0
0

More than 3 years have passed since last update.

初めてのRaspberry Pi Pico ㉘ C言語 PWM その4

Posted at

PWMを4本(GP2、GP3、GP4、GP5)立ち上げます。

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

// Output PWM signals on pins 2 and 3, 4

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

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

    printf("\nstart GPIO 2,3,4,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 2 (it's slice 0)
    uint8_t slice_num = pwm_gpio_to_slice_num(2);
    uint8_t slice_num2 = pwm_gpio_to_slice_num(4);

    uint16_t divCounter = 1250; // max 2^16 = 65536
    pwm_set_wrap(slice_num, divCounter-1); // 
    pwm_set_wrap(slice_num2, divCounter-1); // 

    uint8_t div = 127;
    uint8_t fract = 8;
    //pwm_set_clkdiv_int_frac(slice_num, div, fract);

    // duty 50%
    pwm_set_chan_level(slice_num, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num, PWM_CHAN_B, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num2, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num2, PWM_CHAN_B, (int)divCounter*0.5);
    // Set the PWM running
    pwm_set_enabled(slice_num, true);
    pwm_set_enabled(slice_num2, true);
}

IMGP0262a.png

 GP2とGP3がスライス0、GP4とGP5がスライス1です。GPIOは次のようにチャネルがマッピングされています。

GPIO 0 1 2 3 4 5 ... 14 15
PWMチャネル 0A 0B 1A 1B 2A 2B ... 7A 7B
GPIO 16 17 18 19 20 21 ... - -
PWMチャネル 0A 0B 1A 1B 2A 2B ... - -

スライスを独立して4本のPWMを作る

 GP2、GP3、GP4、GP5の出力に対してひとつずつスライスを定義します。

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

// Output PWM signals on pins 2 and 3,4,5

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

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

    printf("\nstart GPIO 2,3,4,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 2 (it's slice 0)
    uint8_t slice_num  = pwm_gpio_to_slice_num(2);
    uint8_t slice_num2 = pwm_gpio_to_slice_num(3);
    uint8_t slice_num3 = pwm_gpio_to_slice_num(4);
    uint8_t slice_num4 = pwm_gpio_to_slice_num(5);

    uint16_t divCounter = 1250; // max 2^16 = 65536
    pwm_set_wrap(slice_num,  divCounter-1); // 
    pwm_set_wrap(slice_num2, divCounter-1); // 
    pwm_set_wrap(slice_num3, divCounter-1); // 
    pwm_set_wrap(slice_num4, divCounter-1); // 

    uint8_t div = 127;
    uint8_t fract = 8;
    //pwm_set_clkdiv_int_frac(slice_num, div, fract);

    // duty 50%
    pwm_set_chan_level(slice_num, PWM_CHAN_A,  (int)divCounter*0.5);
    pwm_set_chan_level(slice_num2, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num3, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num4, PWM_CHAN_A, (int)divCounter*0.5);

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

IMGP0264.png

 GP3とGP5の出力が出ていません。

飛び飛びのGPxを指定

 Aの出力だけを指定します。出力は、GP2、GP4、GP6、GP8です。

    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(4, GPIO_FUNC_PWM);
    gpio_set_function(6, GPIO_FUNC_PWM);
    gpio_set_function(8, GPIO_FUNC_PWM);

    // Find out which PWM slice is connected to GPIO 2 (it's slice 0)
    uint8_t slice_num  = pwm_gpio_to_slice_num(2);
    uint8_t slice_num2 = pwm_gpio_to_slice_num(4);
    uint8_t slice_num3 = pwm_gpio_to_slice_num(6);
    uint8_t slice_num4 = pwm_gpio_to_slice_num(8);

 四つの独立したPWM信号がずれながら発生しています。
IMGP0265.png

 これを分周して1MHzから980.39Hzへ落とします(前回参照)。1usのずれは、目視では見えなくなってしまいました。
IMGP0268.png

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

// Output PWM signals on pins 2 and 4, 6, 8

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

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

    printf("\nstart GPIO 2,4,6,8\n");

    gpio_set_function(2, GPIO_FUNC_PWM);
    gpio_set_function(4, GPIO_FUNC_PWM);
    gpio_set_function(6, GPIO_FUNC_PWM);
    gpio_set_function(8, GPIO_FUNC_PWM);

    // Find out which PWM slice is connected to GPIO 2 (it's slice 0)
    uint8_t slice_num  = pwm_gpio_to_slice_num(2);
    uint8_t slice_num2 = pwm_gpio_to_slice_num(4);
    uint8_t slice_num3 = pwm_gpio_to_slice_num(6);
    uint8_t slice_num4 = pwm_gpio_to_slice_num(8);

    uint16_t divCounter = 1250; // max 2^16 = 65536
    pwm_set_wrap(slice_num,  divCounter-1); // 
    pwm_set_wrap(slice_num2, divCounter-1); // 
    pwm_set_wrap(slice_num3, divCounter-1); // 
    pwm_set_wrap(slice_num4, divCounter-1); // 

    uint8_t div_int = 127;
    uint8_t div_fract = 8;
    pwm_set_clkdiv_int_frac(slice_num,  div_int, div_fract);
    pwm_set_clkdiv_int_frac(slice_num2, div_int, div_fract);
    pwm_set_clkdiv_int_frac(slice_num3, div_int, div_fract);
    pwm_set_clkdiv_int_frac(slice_num4, div_int, div_fract);

    // duty 50%
    pwm_set_chan_level(slice_num,  PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num2, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num3, PWM_CHAN_A, (int)divCounter*0.5);
    pwm_set_chan_level(slice_num4, PWM_CHAN_A, (int)divCounter*0.5);

    // Set the PWM running
    pwm_set_enabled(slice_num,  true);
    pwm_set_enabled(slice_num2, true);
    pwm_set_enabled(slice_num3, true);
    pwm_set_enabled(slice_num4, true);
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0