STM32F103+HAL+PWM+DMA+WS2812

来源:互联网 发布:mac炉石记牌器 编辑:程序博客网 时间:2024/06/05 18:50

如题:用HAL库,通过stm32f103r8的PWM的DMA模式控制WS2812

           硬件使用的是TIM3的CHANNEL1硬件配置如下:


时钟为常规时钟配置


   定时器3产生1.25us周期需要的arr为89(计算略)


 DMA配置如下:


 

几个需要注意的地方,

1.DMA

  1.1DMA方向    Memory To Peripheral (默认为Peripheral  To Memory)

  1.2DMA传输位宽 Half Word

2.定义数组

2.1一定要定位为16bit,

3.定义高低位

#define BIT_1                   61u //1比较值为61 850us
#define BIT_0                   28u //0比较值为28 400us 

4. //发送函数

void TM7812_show(void)
{
    uint8_t i, j;


    for(i = 0; i < PIXEL_MAX; i++)
    {
        for(j = 0; j < 8; j++)
        {
            frame.data[24 * i + j]     = (rBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;//将高低位扩展到16bit
            frame.data[24 * i + j + 8]   = (gBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;
            frame.data[24 * i + j + 16]  = (bBuffer[i] & (0x80 >> j)) ? BIT_1 : BIT_0;


        }
    }
    HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_1, (uint32_t *)&frame, 3 + 24 * PIXEL_MAX + 1);  //虽然传的是16bit但是要先转为32bit指针,

//貌似是函数要求为32位无符号指针,但实际传输时,因为之前定义的为half word,所以还是16bit传输;

//不对还请指正

}

5.PWM的DMA完成中断回调函数

 因为HAL库自身清楚DMA标志的时候并没有停止PWM所以需要手动停止

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    HAL_TIM_PWM_Stop(&htim3,TIM_CHANNEL_1);
}