STM32 HAL WS2812B PWM+DMA控制

在这里插入图片描述
由上图可知 T0H+T0LT1H+T1L 的时间周期为 800ns ~ 1380ns
取一个中间值 1.25us
那么0码/1码的周期就是 1s / 1.25us = 800kHz
所以PWM的周期就是800KHz

1.配置PWM+DMA

在这里插入图片描述
我这里使用的是TIM2_CH1 总线上的时钟频率为 52M
52M / 800KHz = 65
分频系数为0
那么向上计数值为65-1
在这里插入图片描述
在这里插入图片描述

2.占空比设置

在这里插入图片描述
0码的高电平大概占1/3的时间,那么PWM的计数值为 65 * 1/3 = 22

1码的高电平大概占2/3的时间,那么PWM的计数值为65 * 2/3 = 43


上面理论的东西弄好了,接下来是怎么使用
如果你以前只是使用PWM来调节呼吸灯,那你可能很难理解
例如我想输出 8个码 0 0 1 0 1 0 1 1
这里需要解决两个问题,怎么控制
1.输出一个0后,如何快速输出一个1?
2.怎么精准控制输出8个脉冲后就停止了?

运用你以前的PWM的使用方法是无法做到上面这两点的,但是和DMA组合使用,就可以很方便地实现(一行代码就搞定)

#define NUM 9
uint16_t send_Buf[NUM] = {22, 22, 43, 22, 43, 22, 43, 43, 0};

void led_on(void)
{
    send_Buf[NUM - 1] = 0; // 这个很重要,最后一个需要设为0,要不然DMA不会停下来
    HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_1, (uint32_t *)send_Buf, NUM);
}

一个函数,简简单单就实现了上面的功能,示波器采集到的数据也对应得上
在这里插入图片描述


/**
 * @brief        :输入hsv 返回rgb值 转换函数
 * @param         {uint32_t} h:色调(0~360°)
 * @param         {uint32_t} s:饱和度(0~100%)
 * @param         {uint32_t} v:亮度(0~100%)
 * @param         {uint32_t} *r:
 * @param         {uint32_t} *g:
 * @param         {uint32_t} *b:
 * @return        {*}
 **/
void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r, uint32_t *g, uint32_t *b)
{
    h %= 360; // h -> [0,360]
    uint32_t rgb_max = v * 2.55f;
    uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;

    uint32_t i = h / 60;
    uint32_t diff = h % 60;

    // RGB adjustment amount by hue
    uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;

    switch (i)
    {
    case 0:
        *r = rgb_max;
        *g = rgb_min + rgb_adj;
        *b = rgb_min;
        break;
    case 1:
        *r = rgb_max - rgb_adj;
        *g = rgb_max;
        *b = rgb_min;
        break;
    case 2:
        *r = rgb_min;
        *g = rgb_max;
        *b = rgb_min + rgb_adj;
        break;
    case 3:
        *r = rgb_min;
        *g = rgb_max - rgb_adj;
        *b = rgb_max;
        break;
    case 4:
        *r = rgb_min + rgb_adj;
        *g = rgb_min;
        *b = rgb_max;
        break;
    default:
        *r = rgb_max;
        *g = rgb_min;
        *b = rgb_max - rgb_adj;
        break;
    }
}

后续把WS2812B的驱动代码补上(如果我还记得的话。。。)

  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
ws2812b是一种智能彩灯,在STM32上使用HAL库进行编程时,可以利用PWMDMA控制控制彩灯的颜色和亮度。 PWM(脉宽调制)是一种常用的控制电子设备亮度的方法,通过改变PWM信号的占空比即高电平时间和低电平时间的比例,可以控制灯光的亮度。对于ws2812b彩灯,它需要接收到一串特定的脉冲信号来控制灯光的颜色和亮度,因此我们可以利用PWM信号来模拟这个特定的脉冲信号。 在使用HAL库进行编程时,可以利用定时器和PWM功能来生成脉冲信号。首先,我们需要初始化定时器和PWM通道,然后设置定时器的计数周期和预分频值,以确定脉冲信号的频率。接下来,我们可以通过改变PWM通道的CCR寄存器的值来改变脉冲信号的占空比,从而控制灯光的亮度。通过反复改变CCR寄存器的值,即可实现灯光的渐变效果。 为了实现更高效的控制,可以结合使用DMA(直接存储器访问)功能。DMA可以在处理器和外设之间直接传输数据,减轻CPU的负担。对于控制彩灯来说,我们可以把存储颜色和亮度信息的数组存放在内存中,然后通过DMA传输到PWM寄存器中,从而控制彩灯。通过配置DMA通道和中断,可以实现定时更新彩灯的效果。 总之,通过利用STM32HAL库,结合PWMDMA控制,我们可以方便地对ws2812b彩灯进行编程,实现灯光的颜色和亮度控制,使其呈现出丰富多彩的效果。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值