Skip to content

Contributed by WangChong, curated by Ai-Thinker

For the detailed PWM tutorial, please refer to Ze Ge's article. This article supplements Ze Ge's article.

Operation Steps

1
Zero-based Xiao An Pai-Eyes_DU development: PWM breathing LED

Zero-based Xiao An Pai-Eyes_DU development: PWM breathing LED http://ai-thinker.com/forum.php?mod=viewthread&tid=279 (Source: IoT Developer Community - Ai-Thinker Forum)

2
Forum thread reference on PWM

http://ai-thinker.com/forum.php?mod=viewthread&tid=622&highlight=pwm&_dsign=d510fc0b

Here’s the code directly; my code is also based on Ze Ge’s.

c
#include "bflb_mtimer.h"
#include "bflb_pwm_v2.h"
#include "bflb_clock.h"
#include "bflb_gpio.h"
#include "board.h"
struct bflb_device_s *pwm;
struct bflb_device_s *gpio;
#define PWM_PERIOD_MAX 255
int main(void)
{
    int i;
    board_init();
    pwm = bflb_device_get_by_name("pwm_v2_0");
    gpio = bflb_device_get_by_name("gpio");
    // white LED
    bflb_gpio_init(gpio, 29, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
    /* period = .XCLK / .clk_div / .period = 40MHz / 40 / 1000 = 1KHz */
    struct bflb_pwm_v2_config_s cfg = {
        .clk_source = BFLB_SYSTEM_XCLK,
        .clk_div = 40,
        .period = PWM_PERIOD_MAX,
    };
    /*initialize the PWM output*/
    bflb_pwm_v2_init(pwm, &cfg);
    bflb_pwm_v2_start(pwm);
    while (1) {
        // white LED breathing on and off
        bflb_pwm_v2_channel_positive_start(pwm, PWM_CH1); // enable the white LED channel
        for (i = 0; i < PWM_PERIOD_MAX; i++) {
            bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 0, i);
            bflb_mtimer_delay_ms(5);
        }
        for (i = PWM_PERIOD_MAX; i > 0; i--) {
            bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH1, 0, i);
            bflb_mtimer_delay_ms(5);
        }
        bflb_pwm_v2_channel_positive_stop(pwm, PWM_CH1); // disable the white LED channel
    }
}

The main thing to explain here is the information in this document. I need to add some extra notes.

  • First, the Ai-M61-32S-Kit datasheet only states which ports can use PWM0, but does not state which channels those ports use.
  • To see the specific channels, you need to check the BL616/618 documentation. The document is as follows:

Attachments:

bl616_bl618_ds_zh_cn_1.4.pdf(1023.13 KB, downloads: 4)

Explanation: For the channels, please see the pin definitions section. Take GPIO21 (a pin on the dev board) as an example: as shown below, this IO can support two PWM channels — positive PWM channel 1 and negative PWM channel 2. Others are similar.

The figure below shows the data captured by a Raspberry Pi PICO logic analyzer:

Have questions?

For other questions, please visit the unified discussion area: Ai-Thinker Discussions

Released under the MIT License. Build Time 2026-09-11 14:52:23