久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 24788|回復: 39
收起左側

WS2812B漸變色流水算法+PWM DMA驅動STM32源程序

  [復制鏈接]
ID:300212 發表于 2019-7-18 11:55 | 顯示全部樓層 |閱讀模式
最近在學習STM32,到定時器與DMA章節,正巧手頭有先前買的WS2812B模塊,查找相關資料,于是成功點亮了,
又按照自己想法和思路寫了一個漸變色算法,和漸變色流水功能,

可自定義燈的數量和漸變色的深度

漸變色原理:
假如紅藍兩色變換
紅(亮度):10   8   6   4   2   0
藍(亮度):0     2   4   6   8   10


這樣就形成兩種顏色的過度
加大其分辨率,兩顏色之間顏色差越小,生成顏色數據越多


在流水過程中,顏色取到數組末尾時,要將數組首端的數據加在末尾,使其顏色無差別連接

控制代碼:

生成三種顏色數據數組
  1. /**
  2. * color_length 每種顏色漸變最大長度,總顏色長度:color_length * 3
  3. * return 顏色數據總長度
  4. */
  5. uint32_t set_Color_Loop(uint8_t color_length)
  6. {
  7.     RGB = (uint32_t*)malloc(color_length*3*sizeof(uint32_t));//分配數組大小,(所有漸變色顏色長度)
  8.     color_length -= 1;
  9.     for(uint8_t i=0;i<=color_length;i++)
  10.     {
  11.         RGB[i] = (((0xff/color_length)*i)<<8)|((0xff/color_length)*(color_length-i));                                       //藍到綠
  12.         RGB[color_length + 1 +i] = (((0xff/color_length)*i)<<16)|((0xff/color_length)*(color_length-i))<<8; //綠到紅
  13.         RGB[((color_length+1)*2) +i] = ((0xff/color_length)*i)|((0xff/color_length)*(color_length-i))<<16;   //紅到藍
  14.     }
  15.     return color_length*3;
  16. }


  17. 無間斷位移獲取8位顏色數據
  18. /**
  19. * colorwidth 每次獲取多少位
  20. */

  21. void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth)
  22. {
  23.     static uint32_t rgb_position = 0;
  24.     for(uint32_t i = 0;i < colorwidth; i++){
  25.         uint16_t c = (rgb_position + i) % data_Max_Length;//末尾顏色數據結束時將首位的收據填充到數組
  26.         send_Data(RGB[c]);
  27.     }
  28.     rgb_position ++;
  29.     rgb_position %= data_Max_Length;
  30. }
復制代碼


兩種圖片效果
TIM圖片20190718114706.jpg TIM圖片20190718114715.jpg


手機拍不出燈光效果,實際肉眼看還是非常漂亮的
視頻效果:
游客,本帖隱藏的內容需要積分高于 1 才可瀏覽,您當前積分為 0


  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "WS2812B.h"
  5. #include <stdlib.h>

  6. uint32_t *RGB;//顏色列表數組

  7. void LED_Init(void);
  8. void PWM_Init(void);
  9. uint32_t set_Color_Loop(uint8_t color_length);
  10. void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth);

  11. int main(void)
  12. {
  13.     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  14.     uart_init(115200);
  15.     delay_init();
  16.     LED_Init();
  17.        
  18.         WS2812B_TIM_init();
  19.         uint32_t len = set_Color_Loop(32);//每兩種顏色之間的位數
  20.        
  21.     while(1)
  22.     {
  23.                 out_RGB(len,8);//8個燈,每次輸出8個數據
  24.                 delay_ms(80);
  25.     }
  26. }

  27. /**
  28. * colorwidth 每次獲取多少位
  29. */

  30. void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth)
  31. {
  32.         static uint32_t rgb_position = 0;
  33.         for(uint32_t i = 0;i < colorwidth; i++){
  34.                 uint16_t c = (rgb_position + i) % data_Max_Length;//末尾顏色數據結束時將首位的收據填充到數組
  35.                 send_Data(RGB[c]);
  36.         }
  37.         rgb_position ++;
  38.         rgb_position %= data_Max_Length;
  39. }

  40. /**
  41. * color_length 每種顏色漸變最大長度,總顏色長度:color_length * 3
  42. * return 顏色數據總長度
  43. */
  44. uint32_t set_Color_Loop(uint8_t color_length)
  45. {
  46.         RGB = (uint32_t*)malloc(color_length*3*sizeof(uint32_t));//分配數組大小,(所有漸變色顏色長度)
  47.         color_length -= 1;
  48.         for(uint8_t i=0;i<=color_length;i++)
  49.         {
  50.                 RGB[i] = (((0xff/color_length)*i)<<8)|((0xff/color_length)*(color_length-i));                                                //藍到綠
  51.                 RGB[color_length + 1 +i] = (((0xff/color_length)*i)<<16)|((0xff/color_length)*(color_length-i))<<8; //綠到紅
  52.                 RGB[((color_length+1)*2) +i] = ((0xff/color_length)*i)|((0xff/color_length)*(color_length-i))<<16;  //紅到藍
  53.         }
  54.         return color_length*3;
  55. }

  56. void LED_Init()
  57. {
  58.     GPIO_InitTypeDef GPIO_InitTypeStruct;
  59.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB,ENABLE);
  60.     GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_Out_PP;
  61.     GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_5;
  62.     GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
  63.     GPIO_Init(GPIOE,&GPIO_InitTypeStruct);
  64.     GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_5;
  65.     GPIO_Init(GPIOB,&GPIO_InitTypeStruct);
  66.     GPIOB->ODR ^= GPIO_Pin_5;
  67.     GPIOE->ODR ^= GPIO_Pin_5;
  68. }
復制代碼

PWM+DMA驅動WS2812的代碼請查看附件
WS2812B.rar (295.82 KB, 下載次數: 1132)

評分

參與人數 3黑幣 +89 收起 理由
wpppmlah + 30 共享資料的黑幣獎勵!
hzd530 + 9
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:603929 發表于 2019-10-16 08:40 | 顯示全部樓層
正好在做這個,學習一下
回復

使用道具 舉報

ID:394041 發表于 2020-4-10 15:47 | 顯示全部樓層
謝謝分享,學習一下
回復

使用道具 舉報

ID:168165 發表于 2020-4-14 20:39 | 顯示全部樓層
不閃動呀
回復

使用道具 舉報

ID:383785 發表于 2020-5-29 19:24 | 顯示全部樓層
不錯 學習一下
回復

使用道具 舉報

ID:731155 發表于 2020-5-30 13:17 | 顯示全部樓層
非常不錯,感謝分享!!!!
回復

使用道具 舉報

ID:471251 發表于 2020-6-9 20:00 | 顯示全部樓層

謝謝分享,學習一下
回復

使用道具 舉報

ID:219315 發表于 2020-6-12 15:04 | 顯示全部樓層
實際燒到單片機里運行,燈光效果很漂亮。
回復

使用道具 舉報

ID:394041 發表于 2020-7-1 22:26 來自手機 | 顯示全部樓層
謝謝,有空試一下。
回復

使用道具 舉報

ID:610978 發表于 2020-9-11 11:02 | 顯示全部樓層
感謝樓主分享,下載到板子里可以正常工作,我嘗試吧TIM2換成TIM1就不能亮了,這是為什么呢?
是我哪里漏修改了么?

void WS2812B_TIM_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_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
    /* Compute the prescaler value */
    //PrescalerValue = (uint16_t) (SystemCoreClock / 24000000) - 1;
    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = 89; // 800kHz
    TIM_TimeBaseStructure.TIM_Prescaler = 0;
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
          TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
    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(TIM1, &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)&TIM1->CCR1;        // 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 = 24;
    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 */
        /* 只能使用通道1 TIMx_UP */
    TIM_DMACmd(TIM1, TIM_DMA_Update, ENABLE);
}
回復

使用道具 舉報

ID:791100 發表于 2020-11-10 16:39 | 顯示全部樓層
非常感謝,值得學習一下,非常好
回復

使用道具 舉報

ID:384489 發表于 2020-11-20 15:06 | 顯示全部樓層
感謝分享,學習一下,非SPI方式。
回復

使用道具 舉報

ID:235359 發表于 2020-12-28 16:40 | 顯示全部樓層
正好在做這個,學習一下
回復

使用道具 舉報

ID:585349 發表于 2020-12-30 11:28 | 顯示全部樓層
我有一條晚上2812燈帶是三根線的,引腳怎么去接
回復

使用道具 舉報

ID:831068 發表于 2021-1-7 15:41 | 顯示全部樓層
孫少 發表于 2020-12-30 11:28
我有一條晚上2812燈帶是三根線的,引腳怎么去接

vcc+gnd+signal=三根線
回復

使用道具 舉報

ID:210471 發表于 2021-3-5 17:04 | 顯示全部樓層
點亮了很好看
回復

使用道具 舉報

ID:48216 發表于 2021-3-9 00:27 | 顯示全部樓層

點亮了很好看
回復

使用道具 舉報

ID:753687 發表于 2021-3-13 15:16 | 顯示全部樓層
正好手里有一個ws2812,也想做這個,學習一下
回復

使用道具 舉報

ID:890487 發表于 2021-3-13 16:33 | 顯示全部樓層
看看能不能移植到esp8266 謝謝樓主
回復

使用道具 舉報

ID:202803 發表于 2021-5-20 14:01 | 顯示全部樓層
請問使用PWM方式的話不使用DMA怎么實現呢,因為有的單片機是沒有DMA控制器的
回復

使用道具 舉報

ID:423238 發表于 2021-5-21 15:46 來自手機 | 顯示全部樓層
有8266的驅動程序沒
回復

使用道具 舉報

ID:963713 發表于 2021-9-2 15:43 | 顯示全部樓層
點亮了很好看
回復

使用道具 舉報

ID:226821 發表于 2021-9-6 08:56 | 顯示全部樓層
Thankjs share nice colorful effect
回復

使用道具 舉報

ID:89237 發表于 2021-9-6 09:03 | 顯示全部樓層

點亮了很好看
回復

使用道具 舉報

ID:436885 發表于 2021-9-14 18:19 | 顯示全部樓層
大家用的是什么型號芯片?
回復

使用道具 舉報

ID:88256 發表于 2021-9-17 01:49 | 顯示全部樓層
改到ESP-12F上試了一下,發現只有8個燈數量太少變化就不明顯,等有空改長了試試
回復

使用道具 舉報

ID:973189 發表于 2021-10-19 07:39 | 顯示全部樓層
先記錄下來,后面學習一下
回復

使用道具 舉報

ID:986209 發表于 2021-11-30 22:48 | 顯示全部樓層
牛呀,才學習就可以寫出這樣的程序不簡單
回復

使用道具 舉報

ID:384489 發表于 2022-1-10 16:47 | 顯示全部樓層
用過SPI,試試PWM的。
回復

使用道具 舉報

ID:837560 發表于 2022-1-25 17:14 | 顯示全部樓層
不錯,不錯有空研究一下
回復

使用道具 舉報

ID:947605 發表于 2022-4-25 19:30 | 顯示全部樓層
很漂亮,帥啊
回復

使用道具 舉報

ID:375944 發表于 2022-8-12 08:52 | 顯示全部樓層
正用到這款做機器人控制燈用,學習下!
回復

使用道具 舉報

ID:1040201 發表于 2022-9-2 16:29 | 顯示全部樓層
感謝樓主,我去抽點時間學習一下 。
回復

使用道具 舉報

ID:651494 發表于 2022-9-3 15:30 | 顯示全部樓層
主循環用個大DELAY,還讓不讓其他進程活?改天給你們寫個,估計都還是大學生。
回復

使用道具 舉報

ID:46750 發表于 2023-5-11 10:43 | 顯示全部樓層
漂亮,這種算法有乘除法運算,運行效率和儲存空間都是挑戰,對于成本較低的MCU,就...
有沒有高手來完善一下
回復

使用道具 舉報

ID:339520 發表于 2023-6-19 13:46 | 顯示全部樓層
1毛錢的應廣單片機PMS150G驅動WS2812代碼寫完了。
回復

使用道具 舉報

ID:356964 發表于 2023-8-18 08:01 | 顯示全部樓層
謝謝分享,學習一下!學習這個有癮!
回復

使用道具 舉報

ID:356964 發表于 2023-8-18 08:02 | 顯示全部樓層
樂此不疲!樂此不疲!感謝分享!
回復

使用道具 舉報

ID:31514 發表于 2024-1-5 22:45 | 顯示全部樓層
請教一下樓主,我移植到51單片機上,只有白色,不知道是什么原因
回復

使用道具 舉報

ID:349598 發表于 2024-1-12 21:49 | 顯示全部樓層
不錯!謝謝樓主分享。
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 极品销魂美女一区二区 | 国产精品99999999| 亚洲精品一区二区 | 求毛片 | 精品视频在线观看 | 久操伊人 | 亚洲成av人片在线观看无码 | 欧美全黄| 超碰伊人| 嫩草网 | 91精品国产91久久久 | 国产精品一区在线观看 | 国产在线精品一区二区三区 | 91av在线看| 色婷综合网 | 亚洲精品美女视频 | 日本高清精品 | 国产黄色小视频 | 蜜桃在线视频 | 毛片一区二区三区 | 久久这里只有精品首页 | av av在线| 国产一区二区三区视频在线观看 | 给我免费的视频在线观看 | 国产精品成人一区二区三区 | 亚洲国产精品区 | 日本欧美在线观看视频 | 国产精品完整版 | 成人免费看片网 | 免费观看黄网站 | 欧美激情一区二区三区 | 激情视频中文字幕 | 欧美成人精品 | 欧美一级黄视频 | 日韩免费视频 | 日韩三 | 毛片一区二区三区 | 伊色综合久久之综合久久 | 亚洲一区二区三区在线免费 | 国产一区免费 | 一区二视频 |