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

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

```cpp
/**
 * 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/de9ff722-7a8f-c0d7-dc58-bf3f15b93b58.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の出力に対してひとつずつスライスを定義します。

```cpp
/**
 * 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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/b0ea860e-9b5f-e50f-e272-b3ac6d6c7d62.png)

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

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

```cpp
    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](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/a11e2535-35f1-02a2-a42d-3daa3faf7bab.png)

　これを分周して1MHzから980.39Hzへ落とします（前回参照）。1usのずれは、目視では見えなくなってしまいました。
![IMGP0268.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/23826475-3b7e-a9f0-aea5-e6e1ec8226b6.png)

```cpp
/**
 * 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);
}
```