野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 9471|回复: 2

关于WS2812灯环。

[复制链接]
发表于 2018-9-19 12:56:32 | 显示全部楼层 |阅读模式
最近在学习WS2812灯环,遇到一个奇怪的现象,就是有一个灯的颜色始终与其它灯的颜色不同【其它的灯的颜色是可以同步的】,不知道这个问题是由什么引起的?
代码如下(来源网络):
[mw_shl_code=c,true]#include "WS2812B.h"
/* Buffer that holds one complete DMA transmission
*
* Ensure that this buffer is big enough to hold
* all data bytes that need to be sent
*
* The buffer size can be calculated as follows:
* number of LEDs * 24 bytes + 42 bytes
*
* This leaves us with a maximum string length of
* (2^16 bytes per DMA stream - 42 bytes)/24 bytes per LED = 2728 LEDs
*/
//#define TIM3_CCR3_Address 0x4000043c         // physical memory address of Timer 3 CCR1 register
//#define TIM3_CCR1_Address 0x40000434        // physical memory address of Timer 3 CCR1 register
#define TIM2_CCR1_Address 0x40000034
       
#define TIMING_ONE  50
#define TIMING_ZERO 25
uint16_t LED_BYTE_Buffer[300];
//---------------------------------------------------------------//

void Timer2_init(void)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
        /* GPIOA Configuration: TIM2 Channel 1 as alternate function push-pull */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        /* 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);

        /* PWM1 Mode configuration: Channel1 */
        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_OC1Init(TIM2, &TIM_OCInitStructure);
               
        /* configure DMA */
        /* DMA clock enable */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
       
        /* DMA1 Channel6 Config */
        DMA_DeInit(DMA1_Channel2);

        DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)TIM2_CCR1_Address;        // physical address of Timer 3 CCR1
        DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)LED_BYTE_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);

                /* TIM3 CC1 DMA Request enable */
        TIM_DMACmd(TIM2, TIM_DMA_Update, ENABLE);
}

/* This function sends data bytes out to a string of WS2812s
* The first argument is a pointer to the first RGB triplet to be sent
* The seconds argument is the number of LEDs in the chain
*
* This will result in the RGB triplet passed by argument 1 being sent to
* the LED that is the furthest away from the controller (the point where
* data is injected into the chain)
*/
void WS2812_send(uint8_t (*color)[3], uint16_t len)
{
        uint8_t i;
        uint16_t memaddr;
        uint16_t buffersize;
        buffersize = (len*24)+43+48;        // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes
        memaddr = 0;                                // reset buffer memory index

        for(i=0; i<48; i++) // GREEN data
                        {
                                        LED_BYTE_Buffer[memaddr] = ((0<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
                                        memaddr++;
                        }
        while (len)
        {       

                                for(i=0; i<8; i++) // GREEN data
                        {
                                        LED_BYTE_Buffer[memaddr] = ((color[0][1]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
                                        memaddr++;
                        }
                        for(i=0; i<8; i++) // RED
                        {
                                        LED_BYTE_Buffer[memaddr] = ((color[0][0]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
                                        memaddr++;
                        }
                        for(i=0; i<8; i++) // BLUE
                        {
                                        LED_BYTE_Buffer[memaddr] = ((color[0][2]<<i) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
                                        memaddr++;
                        }
                       
                  len--;
        }
//===================================================================//       
//bug£o×&#238;oóò&#187;&#184;&#246;&#214;ü&#198;ú2¨D&#206;2&#187;&#214;aμà&#206;aê2&#195;′è&#171;ê&#199;&#184;&#223;μ&#231;&#198;&#189;£&#172;1ê&#212;&#246;&#188;óò&#187;&#184;&#246;2¨D&#206;
          LED_BYTE_Buffer[memaddr] = ((color[0][2]<<8) & 0x0080) ? TIMING_ONE:TIMING_ZERO;
//===================================================================//       
          memaddr++;       
                while(memaddr < buffersize)
                {
                        LED_BYTE_Buffer[memaddr] = 0;
                        memaddr++;
                }

                DMA_SetCurrDataCounter(DMA1_Channel2, buffersize);         // load number of bytes to be transferred
                DMA_Cmd(DMA1_Channel2, ENABLE);                         // enable DMA channel 6
                TIM_Cmd(TIM2, ENABLE);                                                 // 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
}

[/mw_shl_code]
以上为WS2812驱动部分
[mw_shl_code=c,true]#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "ws2812b.h"
/************************************************
ALIENTEK&#190;&#171;ó¢STM32&#191;a·¢°&#229;êμ&#209;é1
&#197;ü&#194;íμ&#198;êμ&#209;é
&#188;&#188;ê&#245;&#214;§3&#214;£owww.openedv.com
ì&#212;±|μê&#198;ì£ohttp://eboard.taobao.com
1&#216;×¢&#206;¢D&#197;1&#171;&#214;ú&#198;&#189;ì¨&#206;¢D&#197;o&#197;£o"&#213;yμ&#227;&#212;-×ó"£&#172;&#195;a·&#209;&#187;&#241;è&#161;STM32×êá&#207;&#161;£
1&#227;&#214;YêDD&#199;òíμ&#231;×ó&#191;&#198;&#188;&#188;óD&#207;T1&#171;&#203;&#190;  
×÷&#213;&#223;£o&#213;yμ&#227;&#212;-×ó @ALIENTEK
************************************************/
uint8_t r[][3] = {255,0,0};
uint8_t g[][3] = {0,255,0};
uint8_t b[][3] = {0,0,255};
uint8_t w[][3]={0,0,0};
int main(void)
{       
        int xx=0,yy=0,zz=0;
        delay_init();            //&#209;óê±oˉêy3&#245;ê&#188;&#187;ˉ          
        LED_Init();                          //3&#245;ê&#188;&#187;ˉó&#235;LEDá&#172;&#189;óμ&#196;ó2&#188;t&#189;ó&#191;ú
  Timer2_init();
         
        while(1)
        {
                for(xx=0;xx<255;xx++)
                {
                                r[0][0]=xx;
                        for(yy=0;yy<255;yy++)
                        {
                                r[0][1]=yy;
                                for(zz=0;zz<255;zz++)
                                {
                                        r[0][2]=zz;
                                        delay_ms(50);
                                        WS2812_send(r,8);
                                }
                        }
                }
               
               
               
               
                //while(1);
//                WS2812_send(g,8);
//                delay_ms(1000);
//                WS2812_send(b,8);
//                delay_ms(1000);
        }
}



[/mw_shl_code]
以上为主程序
信号引脚为PA0

回复

使用道具 举报

发表于 2018-9-19 17:50:30 | 显示全部楼层
这个灯不了解
回复 支持 反对

使用道具 举报

发表于 2018-9-20 11:46:08 | 显示全部楼层
可能是驱动没有写好,时序的问题,传数据的时候被打断了,还有就是灯带折了,也会有这个现象
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-5-19 07:11 , Processed in 0.057333 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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