【Ai-M61-32SU入门】学习PWM的使用

[复制链接]
查看1869 | 回复12 | 2023-12-16 15:43:41 | 显示全部楼层 |阅读模式
这次来学习一下PWM的用法,从手册中可以看到BL616/BL618有一个PWM生成器支持4组通道
QQ截图20231216153735.png

下面用RGB灯珠通过PWM实现红绿蓝的呼吸效果,在手册上找到IO对应的IO通道
QQ截图20231216144039.png QQ截图20231216144116.png QQ截图20231216144340.png

代码实现
  1. #include "bflb_gpio.h"
  2. #include "bflb_mtimer.h"
  3. #include "bflb_pwm_v2.h"
  4. #include "bflb_clock.h"
  5. #include "board.h"
  6. #include "bl616_glb.h"

  7. struct bflb_device_s *gpio;
  8. struct bflb_device_s *pwm;
  9. uint8_t rgb_pwmchs[3] = {0};
  10. uint8_t rgb_index = 0;
  11. uint16_t rgb_pwm = 0;

  12. int main(void)
  13. {
  14.     board_init();
  15.     gpio = bflb_device_get_by_name("gpio");
  16.     pwm = bflb_device_get_by_name("pwm_v2_0");
  17.     bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1); //R CH0P CH2P
  18.     bflb_gpio_init(gpio, GPIO_PIN_14, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1); //G CH2P CH3P
  19.     bflb_gpio_init(gpio, GPIO_PIN_15, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1); //B CH3P CH3N
  20.     struct bflb_pwm_v2_config_s cfg = {
  21.         .clk_source = BFLB_SYSTEM_XCLK,
  22.         .clk_div = 40,
  23.         .period = 1000,
  24.     };
  25.     bflb_pwm_v2_init(pwm, &cfg);
  26.     bflb_pwm_v2_channel_positive_start(pwm, PWM_CH0);
  27.     bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2);
  28.     bflb_pwm_v2_channel_positive_start(pwm, PWM_CH3);
  29.     bflb_pwm_v2_start(pwm);
  30.     rgb_pwmchs[0] = PWM_CH0;
  31.     rgb_pwmchs[1] = PWM_CH2;
  32.     rgb_pwmchs[2] = PWM_CH3;
  33.     while (1) {
  34.         if(rgb_pwm > 1999)
  35.         {
  36.             rgb_index += 1;
  37.             rgb_pwm = 0;
  38.             if(rgb_index > 2)
  39.                 rgb_index = 0;
  40.         }
  41.         rgb_pwm += 1;
  42.         if(rgb_pwm>1000)
  43.         {
  44.             bflb_pwm_v2_channel_set_threshold(pwm, rgb_pwmchs[rgb_index], 0, 2000 - rgb_pwm);
  45.         }
  46.         else
  47.         {
  48.             bflb_pwm_v2_channel_set_threshold(pwm, rgb_pwmchs[rgb_index], 0, rgb_pwm);
  49.         }
  50.         bflb_mtimer_delay_ms(1);
  51.     }
  52. }
复制代码
代码解析:
bflb_device_get_by_name("pwm_v2_0") BL616/BL618只支持PWM_V2,外设支持情况可以看这张图
QQ截图20231216150830.png

clk_source = BFLB_SYSTEM_XCLK 设置PWM的时钟源,可以选择bclk、 xclk、 f32k
clk_div = 40 时钟分频,最大65535,0和1都是不分频
period = 1000 PWM 周期 = PWM 源时钟 / pwm_clk_div / pwm_period
bflb_pwm_v2_init(pwm, &cfg) 以指定的参数初始化PWM
bflb_pwm_v2_channel_positive_start 开启正向通道(CHxP)输出,与之相对的是bflb_pwm_v2_channel_negative_start开启负向通道(CHxN)
bflb_pwm_v2_start 开启PWM
bflb_pwm_v2_channel_set_threshold 设置占空比,默认情况下当计数值在第3个参数和第4个参数间时正向通道输出高电平,反之输出低电平
运行效果
WeChat_20231216153424 00_00_00-00_00_30.gif

上面的示例只用到了正向输出通道,每一路通道还有互补输出,例如G和B就是通道3的互补输出,R和C是通道2的互补输出,为了拍摄看得明显些这里选择R和C,要使用负向通道的话需要用GLB_Set_PWM1_IO_Sel改变PWM的外设选择,代码示例
  1. #include "bflb_gpio.h"
  2. #include "bflb_mtimer.h"
  3. #include "bflb_pwm_v2.h"
  4. #include "bflb_clock.h"
  5. #include "board.h"
  6. #include "bl616_glb.h"

  7. struct bflb_device_s *gpio;
  8. struct bflb_device_s *pwm;
  9. uint16_t rgb_pwm = 0;

  10. int main(void)
  11. {
  12.     board_init();
  13.     GLB_Set_PWM1_IO_Sel(GLB_PWM1_IO_DIFF_END);
  14.     gpio = bflb_device_get_by_name("gpio");
  15.     pwm = bflb_device_get_by_name("pwm_v2_0");
  16.     bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1); //R CH0P CH2P
  17.     bflb_gpio_init(gpio, GPIO_PIN_29, GPIO_FUNC_PWM0 | GPIO_ALTERNATE | GPIO_FLOAT | GPIO_SMT_EN | GPIO_DRV_1); //R CH1P CH2N
  18.     struct bflb_pwm_v2_config_s cfg = {
  19.         .clk_source = BFLB_SYSTEM_XCLK,
  20.         .clk_div = 40,
  21.         .period = 1000,
  22.     };
  23.     bflb_pwm_v2_init(pwm, &cfg);
  24.     bflb_pwm_v2_channel_positive_start(pwm, PWM_CH2);
  25.     bflb_pwm_v2_channel_negative_start(pwm, PWM_CH2);
  26.     bflb_pwm_v2_start(pwm);
  27.     while (1) {
  28.         if(rgb_pwm > 1999)
  29.         {
  30.             rgb_pwm = 0;
  31.         }
  32.         rgb_pwm += 1;
  33.         if(rgb_pwm>1000)
  34.         {
  35.             bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 0, 2000 - rgb_pwm);
  36.         }
  37.         else
  38.         {
  39.             bflb_pwm_v2_channel_set_threshold(pwm, PWM_CH2, 0, rgb_pwm);
  40.         }
  41.         bflb_mtimer_delay_ms(1);
  42.     }
  43. }
复制代码
运行效果,只控制1个通道的占空比就能让2个LED交替呼吸

WeChat_20231216153446 00_00_00-00_00_30.gif


本帖被以下淘专辑推荐:

回复

使用道具 举报

1084504793 | 2023-12-16 16:48:35 | 显示全部楼层
学到了
回复

使用道具 举报

干簧管 | 2023-12-16 19:00:12 | 显示全部楼层
点赞
回复

使用道具 举报

bzhou830 | 2023-12-16 20:19:40 | 显示全部楼层
点赞
选择去发光,而不是被照亮
回复

使用道具 举报

san | 2023-12-16 22:50:44 | 显示全部楼层
回复

使用道具 举报

AXK123456 | 2023-12-17 11:52:17 | 显示全部楼层
学习了
回复

使用道具 举报

qwe2079282957 | 2023-12-17 11:58:42 | 显示全部楼层
泰裤辣
回复

使用道具 举报

WT_0213 | 2023-12-17 14:04:25 | 显示全部楼层
回复

使用道具 举报

1084504793 | 2023-12-17 17:30:10 | 显示全部楼层
学到了
回复

使用道具 举报

lazy | 2023-12-17 23:54:24 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则