基于STM32G070RB的七彩星空燈教程(二)
上次我們完成了工程的新建,這次我們開(kāi)始點(diǎn)亮RGB
本文引用地址:http://dyxdggzs.com/article/202205/434254.htm打開(kāi)我們上次教程生成的代碼
我們打開(kāi)工程,將一下代碼 復制到下圖所在位置
#define ONE_PULSE (59) //1 碼計數個(gè)數 #define ZERO_PULSE (29) //0 碼計數個(gè)數 #define RESET_PULSE (80) //80 復位電平個(gè)數(不能低于40) #define LED_NUMS (12) //led 個(gè)數 #define LED_DATA_LEN (24) //led 長(cháng)度,單個(gè)需要24個(gè)字節 #define WS2812_DATA_LEN (LED_NUMS*LED_DATA_LEN) //ws2812燈條需要的數組長(cháng)度 uint16_t static RGB_buffur[RESET_PULSE + WS2812_DATA_LEN] = { 0 };
接下來(lái)就是DMA傳輸完成回調函數(根據你使用的定時(shí)器配置),以下函數都復制到main.c 的/* USER CODE BEGIN 4 */代碼區
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { HAL_TIM_PWM_Stop_DMA(&htim1,TIM_CHANNEL_1); }
下面就是今天的最后一步WS2812的驅動(dòng)函數了,以下函數的作用是根據WS2812的數量將燈的GRB顏色數據寫(xiě)到需要DMA傳送的數組中
void WS281x_SetPixelColor(uint16_t n, uint32_t GRBColor) { uint8_t i; if (n < LED_NUMS) { for (i = 0; i < 24; ++i) RGB_buffur[24 * n + i] = (((GRBColor << i) & 0X800000) ? ONE_PULSE : ZERO_PULSE); } }
將三個(gè)顏色的數據合并成GRB數據
uint32_t WS281x_Color(uint8_t red, uint8_t green, uint8_t blue) { return green << 16 | red << 8 | blue; }
這是一個(gè)簡(jiǎn)單的顏色漸變算法 ,感興趣的可以研究研究
uint32_t 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); }
這里我簡(jiǎn)單的寫(xiě)了兩個(gè)演示程序
void Mode2_LED(uint8_t wait) { uint32_t timestamp = HAL_GetTick(); uint16_t i; static uint8_t j; static uint32_t next_time = 0; uint32_t flag = 0; if (next_time < wait) { if ((uint64_t)timestamp + wait - next_time > 0) flag = 1; } else if (timestamp > next_time) { flag = 1; } if (flag) { j++; next_time = timestamp + wait; for (i = 0; i < LED_NUMS; i++) { WS281x_SetPixelColor(i, Wheel((i + j) & 255)); } } HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN); } void Mode1_LED(uint8_t wait) { uint32_t timestamp = HAL_GetTick(); uint16_t i; static uint8_t j; static uint32_t next_time = 0; static uint8_t loop = 0; if (loop == 0) next_time = timestamp; loop = 1; //首次調用初始化 if ((timestamp > next_time)) // && (timestamp - next_time < wait*5)) { j++; next_time = timestamp + wait; for (i = 0; i < LED_NUMS; i++) { WS281x_SetPixelColor(i, Wheel(((i * 256 / (LED_NUMS)) + j) & 255)); } } HAL_TIM_PWM_Start_DMA(&htim1,TIM_CHANNEL_1,(uint32_t *)RGB_buffur,RESET_PULSE + WS2812_DATA_LEN); }
在主函數中直接調用Mode1_LED和Mode2_LED函數即可。
OK 到這里就結束了,點(diǎn)亮之后相當炫酷。,大家可以借鑒 ,修改出自己獨特的風(fēng)格。
評論