在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用STM32CubeMx驅動WS2812B實現幻彩燈

CHANBAEK ? 來源:小李的創客實驗室 ? 作者:小李的創客實驗室 ? 2023-08-21 11:46 ? 次閱讀

STM32CubeMx驅動WS2812B實現幻彩(超詳)

1.創建基于STM32F03C8T6工程

1.1配置時鐘

  • 選擇外部高速時鐘源HSE

圖片
在這里插入圖片描述

1.2配置系統時鐘樹使其達到最大時鐘72MHz(最大系統時鐘)

圖片
在這里插入圖片描述

由時鐘樹可以知道APB1上定時器時鐘頻率是72MHz,實驗使用的硬件接的是PA2,用的定時器TIM2_CH3, 查閱數據手冊可知

TIM2外設在APB1上所以TIM2的定時器頻率是72MHz。

圖片
在這里插入圖片描述

圖片
在這里插入圖片描述

3.理論分析

之前寫過一篇文章,文章鏈接在此:創客實驗第一彈之驅動WS2812B彩燈;不了解的可以直接跳轉,今天主要講解如何使用STM32CubeMx驅動WS2812B實現幻彩,這里做部分內容截取,完整可以跳轉文章閱讀。

3.1WS2812B的邏輯“1”和邏輯“0”

圖片
圖片

由上圖可知“0”碼和“1”碼都是既有高電平又有低電平不過高電平和低電平的比例不同,這點很好理解,重點是分析一下它的特點,首先直觀的特點就是編碼“0”的電平高電平時間短一些低電平時間長一些,這也恰好符合我們的邏輯畢竟它還是低電平多一些的,編碼“1”的電平高電平時間就長一些,而低電平就短一些。

但是不管是高電平還是低電平他們占用整個時間長度是一樣的,這里還有一個很長的低電平這個代表復位信號

3.2WS2812B控制波形的精準描述如何?

這里涉及到嚴格的數學描述了,長一點是多長?短一點是多短?這個肯定是有標準或者是約束的

圖片
圖片

理論上來說,高電平時長和低電平時長加起來應該是0.4us+0.85us或者0.85us+0.4us也就是說總共要占用1.25us的時間才可以編碼出來一個“0”或者“1”出來。復位是要求50us以上,顯然是要比編碼的0或者1占用的時間要多的。

當然既然是電路的高低電平時長就會引入誤差這個在誤差允許的范圍內我們可以接受,這個范圍就是上下不超過150ns這里是ns比us還要小的時間,這個其實時間要求還是很嚴格的。

3.3分析結果

定時器主頻是72MHz 要想實現1.25us 周期的波形也就是頻率是800KHz波形我們可以采用分頻為1分頻,計數值為90來實現具體原因如下

  • PWM頻率計算公式:

Fpwm =Tclk / ((arr+1)*(psc+1))(單位:Hz)

上面提到數據傳送頻率為800KHz,TCLK為72Mhz,我們這里設置psc = 0,arr= 89,得到頻率剛好為800KHz,也就是計數器計數90個數,每個數計數時間是1/72us,1/72us*90 = 1.25us;

通過控制PWM占空比發送0碼和1碼,額定周期為1.25us,則頻率為800Khz

  • 0碼占空比計算

(0碼高電平時間)/(周期)---> 0.4us / 1.25 us = 0.32

用占空比乘以定時器重裝值加一就是0碼的CCR值(代表PWM高電平計數個數)--->

0.32 * (90) = 28.8(取28,網上網友實測不可以高于28,但23到28都可以,我這里選28)

  • 1碼占空比計算
    同理計算:(1碼高電平時間)/ (周期)---> 0.8 / 1.25 = 0.64
    (占空比)*(90)= CCR ---> 0.64 * 90 = 57.6(取57左右即可這里取58)

4.配置定時器的參數

圖片
在這里插入圖片描述

5.WS2812B燈帶的數據是什么樣的呢?

圖片
圖片

在說數據格式之前先來補充一下關于色彩的知識點,就是三原色,紅綠藍,也就是我們常說的RGB,R就是RED,G就是GREEN,B就是BLUE,一個彩色可以用這三種顏色的比例來混合出來。

每一個LED的R、G、B分別由八位數據控制顏色濃度,(每種顏色濃度有0~255檔,理論上RGB就可以組成256的3次方中顏色組合)即每個LED需要24BIT數據,那么需要發送數據的總長度則為(要控制LED數量 n)*(24),每個LED保存24BIT將剩余位傳給后面LED。全部數據發送完成后要繼續發送大于24us的低電平作為RESET_CODE等才可以點亮。

既然是24bit數據代表三種顏色,我們就要首先知道一個bit的意義是什么,我們傳統意義上來說1個bit代表一個數據位,但是對于數據位bit的理解好像就是“1”或者“0”在數電里我們很容易把高低電平跟邏輯1和邏輯0對應起來,但是表示燈珠的邏輯電平不是簡單的高低電平。在數值上0xFFFFFF就是24bit的1,0x000000就是24bit的0.這里有8個bit代表顏色G分量,G7G6G5G4G3G2G1G0,有8個bit代表R分量R7R6R5R4R3R2R1R0,有8個bit代表B分量B7B6B5B4B3B2B1B0,當不同分量組合時候就會有不同的數據產生,這個數據背后其實是邏輯電平,這里要說明的是彩燈的邏輯“1”并不是簡簡單單的高電平,彩燈的邏輯“0”也不是簡簡單單的低電平。而是上面分析的占空比不同的PWM波形。

4.配置定時器的DMA參數

這里解釋下為什么要就一顆燈也要用DMA,這里僅僅是拿一個燈做,其實多個燈串起來數據量還是很大的使用DMA才可以充分釋放其性能優勢。

  • 內存向外設傳輸
  • 內存遞增遞增
  • DMA普通模式
  • 32為字長傳輸

圖片
在這里插入圖片描述

4.生產代碼修改完善

生成工程配置可參考上篇博客

STM32CubeMx定時器編碼器模式(超詳)

4.1添加自定義ws2812b.c文件跟ws2812b.h文件

圖片
在這里插入圖片描述

圖片
在這里插入圖片描述

4.2修改自定義ws2812b.c文件跟ws2812b.h文件

  • ws2812.c文件內容
#include "ws2812b.h"
#include "tim.h"

/*Some Static Colors------------------------------*/
const RGB_Color_TypeDef RED      = {255,0,0};   //顯示紅色RGB數據
const RGB_Color_TypeDef ORANGE   = {127,106,0};
const RGB_Color_TypeDef YELLOW   = {127,216,0};
const RGB_Color_TypeDef GREEN    = {0,255,0};
const RGB_Color_TypeDef CYAN	   = {0,255,255};
const RGB_Color_TypeDef BLUE     = {0,0,255};
const RGB_Color_TypeDef PURPLE	 = {238,130,238};
const RGB_Color_TypeDef BLACK    = {0,0,0};
const RGB_Color_TypeDef WHITE    = {255,255,255};
const RGB_Color_TypeDef MAGENTA  = {255,0,220};


/*二維數組存放最終PWM輸出數組,每一行24個
數據代表一個LED,最后一行24個0代表RESET碼*/
uint32_t Pixel_Buf[LED_NUM+1][24];       

/*
功能:設定單個RGB LED的顏色,把結構體中RGB的24BIT轉換為0碼和1碼
參數:LedId為LED序號,Color:定義的顏色結構體
*/
void RGB_SetColor(uint8_t LedId,RGB_Color_TypeDef Color)
{
	uint8_t i; 
	if(LedId > LED_NUM)return; //avoid overflow 防止寫入ID大于LED總數
	
	for(i=0;i< 8;i++)   Pixel_Buf[LedId][i]   = ( (Color.G & (1 < < (7 -i)))? (CODE_1):CODE_0);//數組某一行0~7轉化存放G
	for(i=8;i< 16;i++)  Pixel_Buf[LedId][i]   = ( (Color.R & (1 < < (15-i)))? (CODE_1):CODE_0);//數組某一行8~15轉化存放R
	for(i=16;i< 24;i++) Pixel_Buf[LedId][i]   = ( (Color.B & (1 < < (23-i)))? (CODE_1):CODE_0);//數組某一行16~23轉化存放B
}

/*
功能:最后一行裝在24個0,輸出24個周期占空比為0的PWM波,作為最后reset延時,這里總時長為24*1.2=30us > 24us(要求大于24us)
*/
void Reset_Load(void)
{
	uint8_t i;
	for(i=0;i< 24;i++)
	{
		Pixel_Buf[LED_NUM][i] = 0;
	}
}

/*
功能:發送數組
參數:(&htim1)定時器1,(TIM_CHANNEL_2)通道2,((uint32_t *)Pixel_Buf)待發送數組,
			(Pixel_NUM+1)*24)發送個數,數組行列相乘
*/
void RGB_SendArray(void)
{
	HAL_TIM_PWM_Start_DMA(&htim2, TIM_CHANNEL_3, (uint32_t *)Pixel_Buf,(LED_NUM+1)*24);
}

/*
功能:顯示紅色
參數:Pixel_Len為顯示LED個數
*/
void RGB_RED(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i< Pixel_Len;i++)//給對應個數LED寫入紅色
	{
		RGB_SetColor(i,RED);
	}
	Reset_Load();
	RGB_SendArray();
}

/*
功能:顯示綠色
參數:Pixel_Len為顯示LED個數
*/
void RGB_GREEN(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i< Pixel_Len;i++)//給對應個數LED寫入綠色
	{
		RGB_SetColor(i,GREEN);
	}
	Reset_Load();
	RGB_SendArray();
}

/*
功能:顯示藍色
參數:Pixel_Len為顯示LED個數
*/
void RGB_BLUE(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i< Pixel_Len;i++)//給對應個數LED寫入藍色
	{
		RGB_SetColor(i,BLUE);
	}
	Reset_Load();
	RGB_SendArray();
}

/*
功能:顯示白色
參數:Pixel_Len為顯示LED個數
*/
void RGB_WHITE(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i< Pixel_Len;i++)//給對應個數LED寫入白色
	{
		RGB_SetColor(i,WHITE);
	}
	Reset_Load();
	RGB_SendArray();
}

//用戶自定義API接口可根據實際拓展

/*******************************************************************************/
/*									添加部分									   */

//顯示指定顏色
static void rgb_show(uint32_t Pixel_Len, RGB_Color_TypeDef rgb)
{
	uint16_t i;
	for(i=0;i< Pixel_Len;i++)
	{
		RGB_SetColor(i,rgb);
	}
	Reset_Load();
	RGB_SendArray();
}

//顏色循環轉換
static RGB_Color_TypeDef Wheel(uint8_t WheelPos)
{
	RGB_Color_TypeDef rgb;
	WheelPos = 255 - WheelPos;
	if (WheelPos < 85)
	{
		rgb.R = 255 - WheelPos * 3;
		rgb.G = 0;
		rgb.B = WheelPos * 3;
		return rgb;
	}
	if (WheelPos < 170)
	{
		WheelPos -= 85;
		rgb.R = 0;
		rgb.G = WheelPos * 3;
		rgb.B = 255 - WheelPos * 3;
		return rgb;
	}
	WheelPos -= 170;
	rgb.R = WheelPos * 3;
	rgb.G = 255 - WheelPos * 3;
	rgb.B = 0;
	return rgb;
}

//彩虹呼吸燈
static void rainbow(uint8_t wait)
{
	uint32_t timestamp = HAL_GetTick();
	uint16_t i;
	staticuint8_t j;
	staticuint32_t next_time = 0;

	uint32_t flag = 0;
	if (next_time < wait)
	{
		if ((uint64_t)timestamp + wait - next_time > 0)
			flag = 1;
	}
	elseif (timestamp > next_time)
	{
		flag = 1;
	}
	if (flag)    // && (timestamp - next_time < wait*5))
	{
		j++;
		next_time = timestamp + wait;
		for (i = 0; i < LED_NUM; i++)
		{
			RGB_SetColor(i, Wheel((i + j) & 255));
		}
	}
	RGB_SendArray();
}

//彩虹燈旋轉
static void rainbowCycle(uint8_t wait)
{
	uint32_t timestamp = HAL_GetTick();
	uint16_t i;
	staticuint8_t j;
	staticuint32_t next_time = 0;

	staticuint8_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_NUM; i++)
		{
			RGB_SetColor(i, Wheel(((i * 256 / (LED_NUM)) + j) & 255));
		}
	}
	RGB_SendArray();
}
  • ws2812.h文件內容
#ifndef _WS2812B_H_
#define _WS2812B_H_

#include "main.h"

/*這里是上文計算所得CCR的宏定義*/
#define CODE_1       (58)       //1碼定時器計數次數
#define CODE_0       (28)       //0碼定時器計數次數

/*建立一個定義單個LED三原色值大小的結構體*/
typedefstruct
{
	uint8_t R;
	uint8_t G;
	uint8_t B;
}RGB_Color_TypeDef;

#define LED_NUM 1                            //LED數量宏定義,這里我使用一個LED

void RGB_SetColor(uint8_t LedId,RGB_Color_TypeDef Color);//給一個LED裝載24個顏色數據碼(0碼和1碼)
void Reset_Load(void);             //該函數用于將數組最后24個數據變為0,代表RESET_code
void RGB_SendArray(void);          //發送最終數組
void RGB_RED(uint16_t Pixel_Len);  //顯示紅燈
void RGB_GREEN(uint16_t Pixel_Len);//顯示綠燈
void RGB_BLUE(uint16_t Pixel_Len); //顯示藍燈
void RGB_WHITE(uint16_t Pixel_Len);//顯示白燈


#endif

4.3修改主函數實現測試功能

/* USER CODE BEGIN Includes */
#include "ws2812b.h"
/* USER CODE END Includes */


/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    RGB_RED(1);
    HAL_Delay(1000);
    RGB_GREEN(1);
    HAL_Delay(1000);
    RGB_BLUE(1);
    HAL_Delay(1000);
    RGB_WHITE(1);
    HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

5.下載驗證

顏色好像有點色差,基本沒啥問題。OK 到這如何使用STM32CubeMx驅動WS2812B實現幻彩基本搞定,后面有機會再更新幻彩燈的實現部分。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • PWM
    PWM
    +關注

    關注

    114

    文章

    5186

    瀏覽量

    213937
  • 定時器
    +關注

    關注

    23

    文章

    3248

    瀏覽量

    114800
  • 時鐘樹
    +關注

    關注

    0

    文章

    54

    瀏覽量

    10750
  • stm32cubemx
    +關注

    關注

    5

    文章

    283

    瀏覽量

    14809
  • WS2812B
    +關注

    關注

    1

    文章

    38

    瀏覽量

    2182
收藏 人收藏

    評論

    相關推薦

    什么是WS2812BWS2812B燈帶是怎么連接的呢?

    WS2812B是一款全彩LED控制IC,單總線控制,何為單總線我的理解就是數據線在一根線上傳輸的控制方式就是單總線。
    的頭像 發表于 07-08 14:53 ?1.1w次閱讀
    什么是<b class='flag-5'>WS2812B</b>?<b class='flag-5'>WS2812B</b>燈帶是怎么連接的呢?

    哪位大神有完整的STM32F205驅動WS2812B燈帶的程序

    哪位大神有完整的STM32F205驅動WS2812B燈帶的程序
    發表于 09-03 18:08

    使用ESP8266驅動WS2812B型RGB LED智能燈制作分享

    這個智能燈方案很不錯,只用了一個無線WIFI esp8266芯片,驅動ws2812b型RGB LED,效果很贊,在群里看到的,特分享下,若是侵犯了版權,聯系我刪除就行了
    發表于 07-16 04:35

    WS2812B RGB全彩LED燈珠

    WS2812B RGB全彩LED燈珠,只需通過一根信號線控制多個燈顯示,本教程使用X-CTR100控制器驅動WS2812燈環。原理WS2812B是一個集控制電路與發光電路于一體的智能外
    發表于 08-06 08:15

    怎樣給WS2812B發送數據呢

    1. 對于寫驅動來說WS2812B芯片手冊主要就是看通訊。簡單來說就是給WS2812B發送數據,數據就是RGB對應的值,先發高位,按照GRB的順序發送數據。通常我們用高電平表示數字信號“1”,低電平
    發表于 02-22 06:51

    怎樣使用PWM+DMA的方式去驅動WS2812B

    PWM+DMA 驅動 WS2812一、項目要求(主要目的)使用 PWM+DMA 的方式驅動 WS2812B, 并每隔 800ms 隨機顯示不同顏色。(附加目的)探索一下
    發表于 02-22 06:42

    WS2812B RGB 彩燈 51單片機 STC15W 驅動代碼

    WS2812B RGB 彩燈 51單片機 STC15W 驅動代碼
    發表于 04-04 15:29

    基于GD32F427開發板點亮WS2812B彩燈環的設計實現

    1、如何點亮WS2812B彩燈環呢  我有一個WS2812B彩燈環,搭配精選的背景  在玩過的板子上,我都要把它點亮。  關于WS2812B
    發表于 11-25 15:51

    使用ESP8266驅動WS2812B型RGB LED簡單3步打造智能燈

    使用ESP8266驅動WS2812B型RGB LED簡單3步打造智能燈
    發表于 03-26 17:15 ?141次下載

    【有趣的全彩LED | 編程】用STM32 HAL庫讓WS2812B為你所動

    【有趣的全彩LED | 編程】用STM32 HAL庫讓WS2812B為你所動
    發表于 12-05 15:06 ?35次下載
    【有趣的全彩LED | 編程】用<b class='flag-5'>STM32</b> HAL庫讓<b class='flag-5'>WS2812B</b>為你所動

    STM32F1 DMA+PWM 控制WS2812B LED燈

    1. 對于寫驅動來說WS2812B芯片手冊主要就是看通訊。簡單來說就是給WS2812B發送數據,數據就是RGB對應的值,先發高位,按照GRB的順序發送數據。通常我們用高電平表示數字信號“1”,低電平
    發表于 12-28 19:11 ?77次下載
    <b class='flag-5'>STM32</b>F1 DMA+PWM 控制<b class='flag-5'>WS2812B</b> LED燈

    WS2812B遠程區域面板控制器

    電子發燒友網站提供《WS2812B遠程區域面板控制器.zip》資料免費下載
    發表于 07-18 09:07 ?3次下載
    <b class='flag-5'>WS2812B</b>遠程區域面板控制器

    ESP32 WS2812b分線板開源分享

    電子發燒友網站提供《ESP32 WS2812b分線板開源分享.zip》資料免費下載
    發表于 07-29 10:04 ?3次下載
    ESP32 <b class='flag-5'>WS2812b</b>分線板開源分享

    WS2812B遙控燈控制器

    電子發燒友網站提供《WS2812B遙控燈控制器.zip》資料免費下載
    發表于 11-25 09:16 ?8次下載
    <b class='flag-5'>WS2812B</b>遙控燈控制器

    適用于Azure Sphere的WS2812B LED燈帶驅動

    電子發燒友網站提供《適用于Azure Sphere的WS2812B LED燈帶驅動器.zip》資料免費下載
    發表于 12-06 14:42 ?0次下載
    適用于Azure Sphere的<b class='flag-5'>WS2812B</b> LED燈帶<b class='flag-5'>驅動</b>器
    主站蜘蛛池模板: 亚洲欧美在线视频免费| 四虎亚洲精品| 人人插97| 18女人毛片| 男人日女人的网站| 在线免费国产| 综合啪啪| 婷婷在线五月| 97人人做人人爱| 色www国产阿娇| 四虎看黄| 无毒不卡| 国产亚洲欧美一区| 激情婷婷丁香| 国产小视频在线观看www| 一级毛片一片毛| 国产精品久久精品牛牛影视| 2021国产精品自在拍在线播放| 五月婷婷深爱| 中文网丁香综合网| 亚洲精品在线视频观看 | 国产片一区二区三区| 看片在线| 新四虎影院| 伊人成年综合网| 人人添人人澡人人澡人人人爽| 六月婷婷综合| 国产精品天天操| 色www视频永久免费| 天天视频国产免费入口| 1024国产手机视频基地| 四虎永久精品免费观看| 婷婷爱五月天| 黄网站在线观看| 国产高清美女一级a毛片| 黑人40厘米全进去xxxx猛交| 日本经典在线三级视频| 免费观看在线aa| 四虎永久免费在线| 日日夜操| 五月情婷婷|