最近在學習STM32,到定時器與DMA章節(jié),正巧手頭有先前買的WS2812B模塊,查找相關資料,于是成功點亮了,
又按照自己想法和思路寫了一個漸變色算法,和漸變色流水功能,
可自定義燈的數(shù)量和漸變色的深度
漸變色原理:
假如紅藍兩色變換
紅(亮度):10 8 6 4 2 0
藍(亮度):0 2 4 6 8 10
這樣就形成兩種顏色的過度
加大其分辨率,兩顏色之間顏色差越小,生成顏色數(shù)據(jù)越多
在流水過程中,顏色取到數(shù)組末尾時,要將數(shù)組首端的數(shù)據(jù)加在末尾,使其顏色無差別連接
控制代碼:
生成三種顏色數(shù)據(jù)數(shù)組
- /**
- * color_length 每種顏色漸變最大長度,總顏色長度:color_length * 3
- * return 顏色數(shù)據(jù)總長度
- */
- uint32_t set_Color_Loop(uint8_t color_length)
- {
- RGB = (uint32_t*)malloc(color_length*3*sizeof(uint32_t));//分配數(shù)組大小,(所有漸變色顏色長度)
- color_length -= 1;
- for(uint8_t i=0;i<=color_length;i++)
- {
- RGB[i] = (((0xff/color_length)*i)<<8)|((0xff/color_length)*(color_length-i)); //藍到綠
- RGB[color_length + 1 +i] = (((0xff/color_length)*i)<<16)|((0xff/color_length)*(color_length-i))<<8; //綠到紅
- RGB[((color_length+1)*2) +i] = ((0xff/color_length)*i)|((0xff/color_length)*(color_length-i))<<16; //紅到藍
- }
- return color_length*3;
- }
- 無間斷位移獲取8位顏色數(shù)據(jù)
- /**
- * colorwidth 每次獲取多少位
- */
- void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth)
- {
- static uint32_t rgb_position = 0;
- for(uint32_t i = 0;i < colorwidth; i++){
- uint16_t c = (rgb_position + i) % data_Max_Length;//末尾顏色數(shù)據(jù)結(jié)束時將首位的收據(jù)填充到數(shù)組
- send_Data(RGB[c]);
- }
- rgb_position ++;
- rgb_position %= data_Max_Length;
- }
復制代碼
兩種圖片效果
TIM圖片20190718114706.jpg (1.92 MB, 下載次數(shù): 158)
下載附件
2019-7-18 11:49 上傳
TIM圖片20190718114715.jpg (1.77 MB, 下載次數(shù): 134)
下載附件
2019-7-18 11:49 上傳
手機拍不出燈光效果,實際肉眼看還是非常漂亮的
視頻效果:
游客,本帖隱藏的內(nèi)容需要積分高于 1 才可瀏覽,您當前積分為 0
- #include "sys.h"
- #include "delay.h"
- #include "usart.h"
- #include "WS2812B.h"
- #include <stdlib.h>
- uint32_t *RGB;//顏色列表數(shù)組
- void LED_Init(void);
- void PWM_Init(void);
- uint32_t set_Color_Loop(uint8_t color_length);
- void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth);
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- uart_init(115200);
- delay_init();
- LED_Init();
-
- WS2812B_TIM_init();
- uint32_t len = set_Color_Loop(32);//每兩種顏色之間的位數(shù)
-
- while(1)
- {
- out_RGB(len,8);//8個燈,每次輸出8個數(shù)據(jù)
- delay_ms(80);
- }
- }
- /**
- * colorwidth 每次獲取多少位
- */
- void out_RGB(uint16_t data_Max_Length,uint16_t colorwidth)
- {
- static uint32_t rgb_position = 0;
- for(uint32_t i = 0;i < colorwidth; i++){
- uint16_t c = (rgb_position + i) % data_Max_Length;//末尾顏色數(shù)據(jù)結(jié)束時將首位的收據(jù)填充到數(shù)組
- send_Data(RGB[c]);
- }
- rgb_position ++;
- rgb_position %= data_Max_Length;
- }
- /**
- * color_length 每種顏色漸變最大長度,總顏色長度:color_length * 3
- * return 顏色數(shù)據(jù)總長度
- */
- uint32_t set_Color_Loop(uint8_t color_length)
- {
- RGB = (uint32_t*)malloc(color_length*3*sizeof(uint32_t));//分配數(shù)組大小,(所有漸變色顏色長度)
- color_length -= 1;
- for(uint8_t i=0;i<=color_length;i++)
- {
- RGB[i] = (((0xff/color_length)*i)<<8)|((0xff/color_length)*(color_length-i)); //藍到綠
- RGB[color_length + 1 +i] = (((0xff/color_length)*i)<<16)|((0xff/color_length)*(color_length-i))<<8; //綠到紅
- RGB[((color_length+1)*2) +i] = ((0xff/color_length)*i)|((0xff/color_length)*(color_length-i))<<16; //紅到藍
- }
- return color_length*3;
- }
- void LED_Init()
- {
- GPIO_InitTypeDef GPIO_InitTypeStruct;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOB,ENABLE);
- GPIO_InitTypeStruct.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_5;
- GPIO_InitTypeStruct.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOE,&GPIO_InitTypeStruct);
- GPIO_InitTypeStruct.GPIO_Pin = GPIO_Pin_5;
- GPIO_Init(GPIOB,&GPIO_InitTypeStruct);
- GPIOB->ODR ^= GPIO_Pin_5;
- GPIOE->ODR ^= GPIO_Pin_5;
- }
復制代碼
PWM+DMA驅(qū)動WS2812的代碼請查看附件
WS2812B.rar
(295.82 KB, 下載次數(shù): 1132)
2019-7-18 11:55 上傳
點擊文件名下載附件
STM32源碼 下載積分: 黑幣 -5
|