为什么我的 wsb2812 led 没有像我预期的那样工作,最后一个 led 不工作

why doesn't my wsb2812 led work as i expected, the last led doesn't work

我试图同时顺时针和逆时针点亮我的 LED 灯。 我用 mpu6050 作为 LED 的方向控制。我检查了我的 mpu6050 驱动代码,它们没问题。 顺时针方向工作时效果很好,所有 LED 都亮起红色。像这样 enter image description here 当它逆时针工作时,发生了一个问题 enter image description here

我尝试了很多方法来解决,但 none 其中的方法有效。 这是我的 led 驱动程序代码

#include "../BOARD/ws2812/ws2812.h"
#include "bsp_usart1.h"
#include "delay.h"

uint8_t pixelBuffer[PIXEL_NUM][24] ;


void ws281x_init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  SPI_InitTypeDef  SPI_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); 
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);    


  /* PA7  SPI1_MOSI */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //SPI-PA-7
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;  
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master; 
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;     
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;    
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;     
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;    
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;  
  SPI_Init(SPI1, &SPI_InitStructure);  

  SPI_Cmd(SPI1, ENABLE); 
  SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);

  DMA_DeInit(DMA1_Channel3);   
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1 -> DR); 
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)pixelBuffer; //cmar
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;  
  DMA_InitStructure.DMA_BufferSize = PIXEL_NUM * 24; //cndtr;  
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;  
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;  
  DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; 
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
  DMA_Init(DMA1_Channel3, &DMA_InitStructure); 

   ws281x_closeAll();  //SHUT DOWN ALL LEDS
   delay_ms(100); //SHUT DOWN DELAY
}

void ws281x_closeAll(void)
{
  uint16_t i;
  uint8_t j;

  for(i = 0; i < PIXEL_NUM; ++i)
  {

    for(j = 0; j < 24; ++j)
    {
      pixelBuffer[i][j] = WS_LOW;
    }
  }
  ws281x_show(); 
}

uint32_t ws281x_color(uint8_t red, uint8_t green, uint8_t blue)
{
  return green << 16 | red << 8 | blue;
}

void ws281x_setPixelColor(uint16_t n ,uint32_t GRBcolor)
{
  uint8_t i;
  if(n < PIXEL_NUM)
  {
    for(i = 0; i < 24; ++i)
    {
      pixelBuffer[n][i] = (((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW);
    }
  }
}

void ws281x_setPixelRGB(uint16_t n ,uint8_t red, uint8_t green, uint8_t blue)
{
  uint8_t i;

  if(n < PIXEL_NUM)
  {
    for(i = 0; i < 24; ++i)
    {
      pixelBuffer[n][i] = (((ws281x_color(red,green,blue) << i) & 0X800000) ? WS_HIGH : WS_LOW);
     }
   }
}

void ws281x_show(void)
{
  DMA_Cmd(DMA1_Channel3, DISABLE );  //shut down USART1 TX DMA1 
  DMA_ClearFlag(DMA1_FLAG_TC3);    
  DMA_SetCurrDataCounter(DMA1_Channel3,24 * PIXEL_NUM );
  DMA_Cmd(DMA1_Channel3, ENABLE);  //enable USART1 TX DMA1 
}
// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t ws281x_wheel(uint8_t wheelPos) {
    wheelPos = 255 - wheelPos;
    if(wheelPos < 85) {
         return ws281x_color(255 - wheelPos * 3, 0, wheelPos * 3);
    }
    if(wheelPos < 170) {
        wheelPos -= 85;
        return ws281x_color(0, wheelPos * 3, 255 - wheelPos * 3);
     }
     wheelPos -= 170;
     return ws281x_color(wheelPos * 3, 255 - wheelPos * 3, 0);
     }

     // Fill the dots one after the other with a color
     void ws281x_colorWipe(uint32_t c, uint8_t wait) {
         for(uint16_t i=0; i<PIXEL_NUM; i++) {
             ws281x_setPixelColor(i, c);
             ws281x_show();
             delay_ms(wait);
         }
     }


         //roll the opposite way 
         //doesnt enable the last led
   void ws281x_colorWipe_rollback(uint32_t c, uint8_t wait){
       uint16_t n;
       for(uint16_t i = PIXEL_NUM ; i > 0; i --) {
           ws281x_setPixelColor(i, c);
           ws281x_show();
           delay_ms(wait);
       }
   }

void ws281x_rainbow(uint8_t wait) {
uint16_t i, j;

for(j=0; j<256; j++) {
    for(i=0; i<PIXEL_NUM; i++) {
        ws281x_setPixelColor(i, ws281x_wheel((i+j) & 255));
        }
    ws281x_show();
    delay_ms(wait);
    }
}

// Slightly different, this makes the rainbow equally distributed throughout
void ws281x_rainbowCycle(uint8_t wait) {
    uint16_t i, j;

    for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< PIXEL_NUM; i++) {
        ws281x_setPixelColor(i,ws281x_wheel(((i * 256 / PIXEL_NUM) + j) & 
 255));
        }
       ws281x_show();
       delay_ms(wait);
     }
}

//Theatre-style crawling lights.
void ws281x_theaterChase(uint32_t c, uint8_t wait) {
      for (int j=0; j<10; j++) {  //do 10 cycles of chasing
            for (int q=0; q < 3; q++) {
                  for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
                        ws281x_setPixelColor(i+q, c);    //turn every third             pixel on
                   }
                  ws281x_show();
                  delay_ms(wait);

                  for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
                        ws281x_setPixelColor(i+q, 0);        //turn every third pixel off
                  }
            }
      }
}

//Theatre-style crawling lights with rainbow effect
void ws281x_theaterChaseRainbow(uint8_t wait) {
      for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
           for (int q=0; q < 3; q++) {
                for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
                    ws281x_setPixelColor(i+q, ws281x_wheel( (i+j) % 255));            
                    //turn every third pixel on
                  }
                ws281x_show();
                delay_ms(wait);
                for (uint16_t i=0; i < PIXEL_NUM; i=i+3) {
                    ws281x_setPixelColor(i+q, 0);        //turn every third pixel off
                 }
          }
    }
}

让我心烦的两个函数是这些

         // Fill the dots one after the other with a color
     void ws281x_colorWipe(uint32_t c, uint8_t wait) {
         for(uint16_t i=0; i<PIXEL_NUM; i++) {
         ws281x_setPixelColor(i, c);
         ws281x_show();
         delay_ms(wait);
         }
     }


         //roll the opposite way 
         //doesnt enable the last led
   void ws281x_colorWipe_rollback(uint32_t c, uint8_t wait){
       uint16_t n;
       for(uint16_t i = PIXEL_NUM ; i > 0; i --) {
       ws281x_setPixelColor(i, c);
       ws281x_show();
       delay_ms(wait);
       }
   }

单片机:stm32f103c8 led:wsb2812 带 24 个 LED

您在 ws281x_colorWipe_rollback 函数中从 24 循环到 1,但您希望它从 23 循环到 0:

for(int16_t i = PIXEL_NUM-1 ; i >= 0; i --)
void ws281x_colorWipe_rollback(uint32_t c, uint8_t wait){
    for(int i = PIXEL_NUM ; i > (-1); --i) {

    ws281x_setPixelColor(i, c);

    ws281x_show();
    delay_ms(wait);
   }
}

问题已解决