社区导航

 

搜索
12
返回列表 发新帖
楼主: 通宵敲代码

[原创] WS2812灯珠的STM32驱动方式(二)——DMA+PWM

  [复制链接]

3

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-12-26 14:45 | 显示全部楼层
谢谢大神,代码没有问题,我在主函数里面修改了一下WS2812_send(rgb0,16),发现自己的问题挺傻的


回复

使用道具 举报

126

TA的帖子

1

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-12-26 16:14 | 显示全部楼层
谢谢分享,回去试一下。


回复

使用道具 举报

126

TA的帖子

1

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2018-12-30 09:52 | 显示全部楼层
灯欢快的亮了起来


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-4-24 16:31 | 显示全部楼层
请问为什么我一个灯条60颗灯,只能点亮48颗灯,如果设置为大于48,就全都不亮


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-4-28 17:41 | 显示全部楼层


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-6-21 16:11 | 显示全部楼层

请问,TIMING1和TIMING0的大小怎么确定的呢

 



回复

使用道具 举报

2

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-6-25 02:15 来自手机 | 显示全部楼层
感谢,分享


回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-7-2 17:57 | 显示全部楼层

驱动WS2812还是SPI好一点,占用内存比PWM少一倍。PWM用uint16去模拟WS2812B的一个Bit,SPI用uint8就可以模拟1Bit。既然有代码,来学习下PWM的DMA方式也是极好的,给DMA发送的数组换成正选表就是SPWM发生器



回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-7-2 18:02 | 显示全部楼层

另外我用SPI驱动,SPI1,SPI2同时驱动2条1200灯带,DMA一次刷新的时间不到27ms。不过灯一多就要换MCU了,2条1200灯占用了56.25K-RAM,只能选用64K RAM的片子。程序改天整理好注释开出来



回复

使用道具 举报

8

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-7-6 19:10 | 显示全部楼层
不错,支持下


回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-7-25 16:07 | 显示全部楼层
码客_Mark 发表于 2019-7-2 18:02 另外我用SPI驱动,SPI1,SPI2同时驱动2条1200灯带,DMA一次刷新的时间不到27ms。不过灯一多就要换MCU了,2 ...

请问一下整理好了吗?能不能分享呢?谢谢



回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-8-14 16:36 | 显示全部楼层

感谢LZ提供的代码。在测试的时候,出现每次循环一次的时候,都会在第一个led灯出现瞬间混乱色彩,然后正常。什么原因?同时,在“用TIM2_CH123实现三路LED控制” 案例中,CH1(PA0)正常红色渐变。CH2(PA1)并不是正常的绿色渐变,CH3(PA2)并不是正常的蓝色渐变,而是混乱的多彩变化。是什么原因?

点评

优先考虑下供电及干扰问题, 这种LED等的驱动电流不低,确保供电电流是否充足, 再就是信号干扰问题,也算是高频驱动了,必要的保护措施一定要到位  详情 回复 发表于 2019-8-15 16:29
天之苍狼


回复

使用道具 举报

1252

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2019-8-15 16:29 | 显示全部楼层
tzcl 发表于 2019-8-14 16:36 感谢LZ提供的代码。在测试的时候,出现每次循环一次的时候,都会在第一个led灯出现瞬间混乱色彩,然后正常 ...

优先考虑下供电及干扰问题,

这种LED等的驱动电流不低,确保供电电流是否充足,

再就是信号干扰问题,也算是高频驱动了,必要的保护措施一定要到位



回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-9-10 15:47 | 显示全部楼层

请问下为啥联级灯数大于50个灯  就全部不会亮?

点评

排查一下程序,再就是保证供电电流足够, 理论上这种灯珠可以级联1000多颗。  详情 回复 发表于 2019-9-11 08:30


回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-9-10 16:35 | 显示全部楼层
qw845253793 发表于 2019-4-24 16:31 请问为什么我一个灯条60颗灯,只能点亮48颗灯,如果设置为大于48,就全都不亮

加到数组容量就行了  60*24=1440  差不多设1500大小的数组



回复

使用道具 举报

1252

TA的帖子

2

TA的资源

版主

Rank: 6Rank: 6

 楼主| 发表于 2019-9-11 08:30 | 显示全部楼层
sjh13140 发表于 2019-9-10 15:47 请问下为啥联级灯数大于50个灯  就全部不会亮?

排查一下程序,再就是保证供电电流足够,

理论上这种灯珠可以级联1000多颗。



回复

使用道具 举报

3

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-9-11 15:27 | 显示全部楼层

请问下这个怎么实现多彩效果啊,突然发现发送函数是集体控制,一排灯珠一个色的控制而已,怎么实现流水效果呢



回复

使用道具 举报

1

TA的帖子

0

TA的资源

一粒金砂(初级)

Rank: 1

发表于 2019-9-11 22:09 | 显示全部楼层
通宵敲代码 发表于 2019-9-11 08:30 排查一下程序,再就是保证供电电流足够, 理论上这种灯珠可以级联1000多颗。

我的PWM第一个脉冲有问题,周期不对,剩下的都正确,仿真的波形到是正确的。能否帮忙看看?

void timer2_pwm_ch2_init (void)
{
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
  TIM_OCInitTypeDef TIM_OCInitStructure;
  DMA_InitTypeDef DMA_InitStructure;

  RCC_APB1PeriphClockCmd (RCC_APB1Periph_TIM2, ENABLE);
  TIM_DeInit(TIM2);
  /* Compute the prescaler value */
  //PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
  /* Time base configuration */
  TIM_TimeBaseStructure.TIM_Period = 90 - 1; // 800kHz
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit (TIM2, &TIM_TimeBaseStructure);

  /* PWM2 Mode configuration: Channel1 */
  TIM_OCStructInit(&TIM_OCInitStructure);
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 0;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;
  TIM_ARRPreloadConfig(TIM2, ENABLE);
  TIM_OC2Init (TIM2, &TIM_OCInitStructure);

  /* configure DMA */
  /* DMA clock enable */
  RCC_AHBPeriphClockCmd (RCC_AHBPeriph_DMA1, ENABLE);

  /* DMA1 Channel7 Config for PWM2 by TIM2_CH2*/
  DMA_DeInit (DMA1_Channel2);
  DMA_StructInit(&DMA_InitStructure);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(TIM2->CCR2);    // physical address of Timer 2 CCR2
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) WS2812B_OUTPUT_LED_PWM2_BUFFER;        // this is the buffer memory
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;            // data shifted from memory to peripheral
  DMA_InitStructure.DMA_BufferSize = 42;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;            // automatically increase buffer index
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                // stop DMA feed after buffer size is reached
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init (DMA1_Channel2, &DMA_InitStructure);
  DMA_ClearFlag(DMA1_FLAG_TC2);

  /* TIM2 DMA Request enable */
  //TIM_DMACmd (TIM2, TIM_DMA_CC2, ENABLE);
  TIM_DMACmd (TIM2, TIM_DMA_Update, ENABLE);
#if 1

WS2812B_send_led_pwm2(test_array, 1);

#endif
}

 

void WS2812B_send_led_pwm2 (uint8_t (*color)[3], uint16_t len)
{
    uint8_t i;
    uint16_t memaddr;
    uint16_t buffersize;
    buffersize = (len * 24)+1 ; // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
    memaddr = 0;              // reset buffer memory index
    uint8_t total=len; 
    
    while (len)
    {
        for (i = 0; i < 8; i++) // GREEN data
        {
            WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][1] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
            memaddr++;
        }
        for (i = 0; i < 8; i++) // RED
        {
            WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][0] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
            memaddr++;
        }
        for (i = 0; i < 8; i++) // BLUE
        {
            WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][2] << i) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
            memaddr++;
        }
        len--;
    }
//===================================================================//
//bug:最后一个周期波形不知道为什么全是高电平,故增加一个波形
    WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = ((color[0][2] << 8) & 0x0080) ? TIMING_ONE : TIMING_ZERO;
//===================================================================//
    memaddr++;
    while (memaddr < buffersize)
    {
        WS2812B_OUTPUT_LED_PWM2_BUFFER[memaddr] = 0;
        memaddr++;
    }
    TIM_ClearFlag(TIM2,TIM_FLAG_Update );
    TIM_SetCounter(TIM2, 0);
    DMA_SetCurrDataCounter (DMA1_Channel2, buffersize);   // load number of bytes to be transferred
    TIM_Cmd (TIM2, ENABLE); 
    DMA_Cmd (DMA1_Channel2, ENABLE);          // enable DMA channel 6    
    // enable Timer 3
    while (!DMA_GetFlagStatus (DMA1_FLAG_TC2))
        ;   // wait until transfer complete
    TIM_Cmd (TIM2, DISABLE);  // disable Timer 3
    DMA_Cmd (DMA1_Channel2, DISABLE);             // disable DMA channel 6
    DMA_ClearFlag (DMA1_FLAG_TC2);                // clear DMA1 Channel 6 transfer complete flag

}



回复

使用道具 举报

11

TA的帖子

0

TA的资源

一粒金砂(中级)

Rank: 2

发表于 2019-11-6 18:00 | 显示全部楼层

楼主必须定你一个



回复

使用道具 举报

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

关闭

站长推荐上一条 /9 下一条

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

Archiver|手机版|小黑屋|电子工程世界 ( 京ICP证 060456 )

GMT+8, 2019-11-22 10:19 , Processed in 0.529662 second(s), 16 queries , Gzip On, MemCache On.

快速回复 返回顶部 返回列表