打印
[STM32F1]

STM32驱动WS2812

[复制链接]
302|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sesefadou|  楼主 | 2023-12-30 22:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式


PWM+DMA+TIME3处理脉冲数据
#include "ws281x.h"
#include "delay.h"
#include "timer.h"


u16 pixelBuffer[PIXEL_NUM + RESET_NUM][24] = {0};

void ws281x_show(void)
{               
     DMA_SetCurrDataCounter(DMA1_Channel5,(PIXEL_NUM + RESET_NUM)* 24 );
                                       
            DMA_Cmd(DMA1_Channel5, ENABLE);
     TIM_Cmd(TIM4, ENABLE);
                                

            while(DMA_GetFlagStatus(DMA1_FLAG_TC5) !=SET);
     DMA_Cmd(DMA1_Channel5, DISABLE );
     DMA_ClearFlag(DMA1_FLAG_TC5);
     TIM_Cmd(TIM4, DISABLE);                                                        
}

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;
          }
     }               
}



/**********************************************************************************************************/
// level
//  8               08   09
//  7            07         10
//  6          06             11
//  5         05               12
//  4         04               13
//  3          03             14
//  2            02         15
//  1               01  16
//  0 off            
void ws281x_setPixelColor_ringleds(uint16_t n ,uint32_t GRBcolor)            //PIXEL_NUM:12/16/2*n Ring leds
{
       uint8_t i,k,p;
                                                        
                                                        for(i = 0; i < 24; i++)
                                                 {                        
                                                                                                        for(k = 0;(k < n) && (n <= (PIXEL_NUM / 2));k++)
                                                                                                        {
                                                                                                             pixelBuffer[k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
                                                                                                             pixelBuffer[(PIXEL_NUM - 1) - k][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;                                                                                                
                                                                                                        }
                                                                                                        for(p = n;(p < ( PIXEL_NUM - n)) && (n <= (PIXEL_NUM / 2)) ;p++)
                                                                                                        {
                                                                                                             pixelBuffer[p][i]  =   WS_LOW;                                                                                                                                                                                                                                 
                                                                                                        }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                        }
}


//  fill the dots one by one with a color on left and right sides at the same time
void ws281x_colorWipe_lr( uint32_t c, uint8_t num)
{
    uint16_t i;
                                if(num > PIXEL_NUM / 2)
                                {
                                     num = PIXEL_NUM / 2;
                                }
    for(i = 0; i < (num + 1); i++)         //
                  {                                                
                                                                ws281x_setPixelColor_ringleds(i ,c);
                      ws281x_show();
        //delay_ms(wait);          //>        0.05ms                                will should be using timer               
    }
}


//Freq rising or falling lights
void ws281x_colorWipe_freq(uint8_t type)
{        
                                                                                                               
                 switch(type)
                                                                                {
                                                                                       case 1:
                        ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
                                                                                                                                                                                                break;
                                                                                              case 2:
                        ws281x_colorWipe_lr(ws281x_color(0, 50, 0), ws281x_freq_num); // green
                                                                                                                                                                                                break;                                                                                                                                                               
                                                                                                                                        case 3:
                        ws281x_colorWipe_lr(ws281x_color(0, 0, 50), ws281x_freq_num); // Blue
                                                                                                                                                                                                break;               
                                                                                                                                        case 4:
                        ws281x_colorWipe_lr(ws281x_color(50, 50, 50), ws281x_freq_num); // white
                                                                                                                                                                                                break;               
                                                                                                                                                                                       
                                                                                                                                default:
                        ws281x_colorWipe_lr(ws281x_color(50, 0, 0), ws281x_freq_num); // red
                                                                                                                                                                                                break;                                       
                                                                                }                                                                                   
}




/***************************************************************************************************/
uint32_t ws281x_colorTran(uint8_t tran,uint8_t color_mode)  //The colour is a transition r/g/b back to r/g/b(color_mode:Red1,Green2,Blue3). space 3
{
     tran = 255 - tran;
     if(tran < 85)
                                        {
                                             switch(color_mode)
                                                                                {
                                                                                       case 1:
                        return ws281x_color(tran * 3, 0, 0);
                                                                                              case 2:
                        return ws281x_color(0, tran * 3, 0);                                                                                                                                                                                
                                                                                                                                        case 3:
                        return ws281x_color(0, 0, tran * 3);                                                               
                                                                                                                                default:
                                                                                                                                        return ws281x_color(tran * 3, 0, 0);                                                
                                                                                }
     }
                                       
     if(tran < 170)
                                        {
          tran -= 85;
                                                                                switch(color_mode)
                                                                                {
                                                                                       case 1:
                        return ws281x_color(255, 0, 0);
                                                                                              case 2:
                        return ws281x_color(0,255, 0);                                                                                                                                                                                
                                                                                                                                        case 3:
                        return ws281x_color(0, 0, 255);                                                               
                                                                                                                                default:
                                                                                                                                        return ws281x_color(255, 0, 0);                                                
                                                                                }
     }
     tran -= 170;
                                        switch(color_mode)
                                        {
                                                                                                case 1:
                                                                                                                                                        return ws281x_color(255 - tran * 3, 0, 0);
                                                                                                case 2:
                                                                                                                                                        return ws281x_color(0, 255 - tran * 3, 0);                                                                                                                                                                                
                                                                                                case 3:
                                                                                                                                                        return ws281x_color(0, 0, 255 - tran * 3);                                                               
                                                                                        default:
                                                                                                                                                        return ws281x_color(255 - tran * 3, 0, 0);                                                                                                                                                
                                        }
}


void ws281x_colorblnCtrl(uint8_t color_mode)   // ws281x_bln_num use timer,mode:red1/green2/blue3
{
     uint16_t i;

                                                                                        if( !(ws281x_bln_num == ws281x_bln_oldnum))
                                                                                        {
                                                                                                                        for(i = 0; i < PIXEL_NUM; i++)
                                                                                                                        {
                                                                                                                                                        ws281x_setPixelColor(i ,ws281x_colorTran(ws281x_bln_num,color_mode));
                                                                                                                        }
                                                                                                                        ws281x_show();
                                                                                                                        ws281x_bln_oldnum = ws281x_bln_num;
                                                                                        }
                                
}
/***************************************************************************************************/

void ws281x_setPixelColor_wheel_leds(uint16_t n ,uint32_t GRBcolor)            //n:0~15 whirling leds
{
       uint8_t i,k;
                                                        
                                                        for(i = 0; i < 24; i++)
                                                 {        
                  for(k = 0;k < PIXEL_NUM;k++)
                                                                                                                                                {                                                                                                                                                                                                        
                                                                                                                                                                                                        pixelBuffer[k][i]  =   WS_LOW;                                                                                                                                                                                         
                                                                                                                                                }                                                            

                                                                                                             pixelBuffer[n][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;
                                                                                                                                                if( n < PIXEL_NUM/2)
                                                                                                                                                {
                                                                                                                                                     pixelBuffer[n + (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;        
                                                                                                                                                }
                                                                                                                                                else
                                                                                                                                                {
                                                                                                                                                     pixelBuffer[n - (PIXEL_NUM/2)][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;        
                                                                                                                                                }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                        }
                                                        ws281x_show();        
}

void ws281x_display(void)
{
                                     if(ws281x_led_display_mode == 1)
                                                                        {
                                                                        ws281x_colorblnCtrl(ws281x_bln_mode);
                                                                        }
                                                                        
                                                                        if(ws281x_led_display_mode == 2)
                                                                        {
                                                                        ws281x_colorWipe_freq(ws281x_freq_color_type);
                                                                        }
                                                                        if(ws281x_led_display_mode == 3)
                                                                        {
                                                                                                        ws281x_setPixelColor_wheel_leds(ws281x_whirl_index,
                                                                                                                                                                                                                                                                                                                                                                        ws281x_color(color_R[ws281x_whirl_colortran_index],
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                color_G[ws281x_whirl_colortran_index],
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                color_B[ws281x_whirl_colortran_index])) ;        
                                                                        }     
}







/*
void ws281x_setPixelColor_11x44leds(uint16_t n ,uint32_t GRBcolor)            //PIXEL_NUM:11x44 leds  n:0~10
{
       uint8_t i,k,p,q;
                                                        
                                                        for(i = 0; i < 24; i++)
                                                 {                        
                                                                                                        for(k = 0;k < 44;k++)
                                                                                                        {
                                                                                                              for(q = 0 ;q < (n +1);q++)
                                                                                                                                                        {
                                                                                                                                                      pixelBuffer[q + k*11][i] = ((GRBcolor << i) & 0X800000) ? WS_HIGH : WS_LOW;                                                                                                                                                                                
                                                                                                                                                 }
                                                                                                                                                        for(p = 1;p < (10-n);p++)
                                                                                                                                                 {
                                                                                                                                                                                         pixelBuffer[(n + p) + k*11][i]  =   WS_LOW;                                                                                                                                                                                                                                 
                                                                                                                                                 }                                                                                                                                                                                                        
                                                                                                        }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                                                        }
}
*/


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

1520

帖子

0

粉丝