国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

這篇具有很好參考價值的文章主要介紹了STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

誰不想擁有炫酷的小彩燈呢?WS2812B可以給你機會......

博主使用STM32驅(qū)動WS2812B主要參考了這位佬的文章,因為需求問題,采用了Cortex-M0的stm32f030f4p6(16k的flash,4k的sram)來驅(qū)動,原文中寫的是stm32f103c8t6,個人認為其實區(qū)別并不是很大,需要修改部分參數(shù)即可移植(cv戰(zhàn)士申請出戰(zhàn))。

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

上圖是我的一圈燈,一共8個,第一個LED的數(shù)據(jù)輸入端接的是定時器1的通道2,想看底層原理可以去看佬的文章,本文只介紹如何移植。

CUBEMX配置

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

首先選擇外部石英晶振,我用的是外部12M晶振,然后配置時鐘樹:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

然后打開串行調(diào)試:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

?找到使用的定時器(輸出PWM的),并打開定時器時鐘,選定輸出PWM的通道以及模式:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

重點來了:

佬的文章中說的0碼PWM占空比(CCR值)算到約為28,1碼PWM占空比(CCR值)算到約為58;但人家用的是f1啊,72M時鐘頻率的,咱的是f0,自然低人一等,只有48M時鐘頻率。所以在滿足燈帶頻率固定為800KHz的前提下,略微修改即可,設(shè)置參數(shù)如下:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

下面來簡單說一下如何修改

因為PWM頻率F需要為800KHz,而時鐘頻率固定為48MHz,根據(jù)Fpwm=Fclk / (arr+1)(psc+1),我取psc為0,取arr=59,恰好可以得到?800KHz的頻率,所以arr取值為59。因此,計算出PWM0碼的CCR值為:0.32 × (59+1)=19.2 ≈ 19;PWM1碼的CCR值為:0.64 × (59+1)=38.4 ≈ 38;

接下來配置DMA:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

?再由于我后面切換顯示需要用到定時器中斷,所以用了一個定時器3的1ms中斷:

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)

STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)?配置好生成路徑后直接生成代碼即可

代碼部分:

主函數(shù)頭文件加個#include "ws2812b.h"即可

int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_TIM1_Init();
  MX_TIM3_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  led_loop();	//循環(huán)顯示
  }
  /* USER CODE END 3 */
}

?ws2812b.h文件如下:

#ifndef __WS2812B_H__
#define __WS2812B_H__
 
#include "main.h"
 
/*這里是上文計算所得CCR的宏定義*/
#define CODE_1       (38)       //1碼定時器計數(shù)次數(shù)
#define CODE_0       (19)       //0碼定時器計數(shù)次數(shù)
 
/*建立一個定義單個LED三原色值大小的結(jié)構(gòu)體*/
typedef struct
{
	uint8_t R;
	uint8_t G;
	uint8_t B;
}RGB_Color_TypeDef;
 
#define Pixel_NUM 8  //LED數(shù)量宏定義,這里我使用一個LED,(單詞pixel為像素的意思)
 
void RGB_SetColor(uint8_t LedId,RGB_Color_TypeDef Color);//給一個LED裝載24個顏色數(shù)據(jù)碼(0碼和1碼)
void Reset_Load(void); //該函數(shù)用于將數(shù)組最后24個數(shù)據(jù)變?yōu)?,代表RESET_code
void RGB_SendArray(void);          //發(fā)送最終數(shù)組
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);//顯示白燈

void led_loop(void);
 
#endif





ws2812b.c文件如下:

#include "ws2812b.h"
#include "tim.h"
 
/*Some Static Colors------------------------------*/
const RGB_Color_TypeDef RED      = {255,0,0};   //顯示紅色RGB數(shù)據(jù)
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};

 
/*二維數(shù)組存放最終PWM輸出數(shù)組,每一行24個
數(shù)據(jù)代表一個LED,最后一行24個0代表RESET碼*/
uint32_t Pixel_Buf[Pixel_NUM+1][24];       
 
/*
功能:設(shè)定單個RGB LED的顏色,把結(jié)構(gòu)體中RGB的24BIT轉(zhuǎn)換為0碼和1碼
參數(shù):LedId為LED序號,Color:定義的顏色結(jié)構(gòu)體
*/
void RGB_SetColor(uint8_t LedId,RGB_Color_TypeDef Color)
{
	uint8_t i; 
	if(LedId > Pixel_NUM)return; //avoid overflow 防止寫入ID大于LED總數(shù)
	
	for(i=0;i<8;i++) Pixel_Buf[LedId][i]   = ( (Color.G & (1 << (7 -i)))? (CODE_1):CODE_0 );//數(shù)組某一行0~7轉(zhuǎn)化存放G
	for(i=8;i<16;i++) Pixel_Buf[LedId][i]  = ( (Color.R & (1 << (15-i)))? (CODE_1):CODE_0 );//數(shù)組某一行8~15轉(zhuǎn)化存放R
	for(i=16;i<24;i++) Pixel_Buf[LedId][i] = ( (Color.B & (1 << (23-i)))? (CODE_1):CODE_0 );//數(shù)組某一行16~23轉(zhuǎn)化存放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[Pixel_NUM][i] = 0;
	}
}
 
/*
功能:發(fā)送數(shù)組
參數(shù):(&htim1)定時器1,(TIM_CHANNEL_2)通道2,((uint32_t *)Pixel_Buf)待發(fā)送數(shù)組,
			(Pixel_NUM+1)*24)發(fā)送個數(shù),數(shù)組行列相乘
*/
void RGB_SendArray(void)
{
	HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_2, (uint32_t *)Pixel_Buf,(Pixel_NUM+1)*24);
}
 
/*
功能:顯示紅色
參數(shù):Pixel_Len為顯示LED個數(shù)
*/
void RGB_RED(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i<Pixel_Len;i++)//給對應(yīng)個數(shù)LED寫入紅色
	{
		RGB_SetColor(i,RED);
	}
	Reset_Load();
	RGB_SendArray();
}
 
/*
功能:顯示綠色
參數(shù):Pixel_Len為顯示LED個數(shù)
*/
void RGB_GREEN(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i<Pixel_Len;i++)//給對應(yīng)個數(shù)LED寫入綠色
	{
		RGB_SetColor(i,GREEN);
	}
	Reset_Load();
	RGB_SendArray();
}
 
/*
功能:顯示藍色
參數(shù):Pixel_Len為顯示LED個數(shù)
*/
void RGB_BLUE(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i<Pixel_Len;i++)//給對應(yīng)個數(shù)LED寫入藍色
	{
		RGB_SetColor(i,BLUE);
	}
	Reset_Load();
	RGB_SendArray();
}
 
/*
功能:顯示白色
參數(shù):Pixel_Len為顯示LED個數(shù)
*/
void RGB_WHITE(uint16_t Pixel_Len)
{
	uint16_t i;
	for(i=0;i<Pixel_Len;i++)//給對應(yīng)個數(shù)LED寫入白色
	{
		RGB_SetColor(i,WHITE);
	}
	Reset_Load();
	RGB_SendArray();
}
 
//也可以繼續(xù)添加其他顏色,和顏色變化函數(shù)等

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

//顯示指定顏色
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();
}

//顏色循環(huán)轉(zhuǎn)換
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;
	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)    // && (timestamp - next_time < wait*5))
	{
		j++;
		next_time = timestamp + wait;
		for (i = 0; i < Pixel_NUM; i++)
		{
			RGB_SetColor(i, Wheel((i + j) & 255));
		}
	}
	RGB_SendArray();
}

//彩虹燈旋轉(zhuǎn)
static void rainbowCycle(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;    //首次調(diào)用初始化

	if ((timestamp > next_time))    // && (timestamp - next_time < wait*5))
	{
		j++;
		next_time = timestamp + wait;
		for (i = 0; i < Pixel_NUM; i++)
		{
			RGB_SetColor(i, Wheel(((i * 256 / (Pixel_NUM)) + j) & 255));
		}
	}
	RGB_SendArray();
}


static uint8_t rainbow_change_flag = 0;
void led_loop(void)
{
	int i;
	rgb_show(8, BLACK);		HAL_Delay(300);
	for(i = 1; i <= 8 ;i++) {	//紅
		rgb_show(i, RED);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//橙
		rgb_show(i, ORANGE);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//黃
		rgb_show(i, YELLOW);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//綠
		rgb_show(i, GREEN);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//青
		rgb_show(i, CYAN);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//藍
		rgb_show(i, BLUE);		
		HAL_Delay(50);		
	}
	for(i = 1; i <= 8 ;i++) {	//紫
		rgb_show(i, PURPLE);		
		HAL_Delay(50);		
	}
	
	HAL_TIM_Base_Start_IT(&htim3);	//使能定時器中斷->時間:1ms
	while(1) {
		if(!rainbow_change_flag)
			rainbow(5);
		else 
			rainbowCycle(2);
	}
	
}


//定時器3中斷回調(diào)函數(shù)
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(htim);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_TIM_PeriodElapsedCallback could be implemented in the user file
   */
	static uint32_t time_counter = 0;
	if(htim->Instance == TIM3) {
		if(++time_counter == 10000) {	//10s后切換
			rainbow_change_flag = ~rainbow_change_flag;
			time_counter = 0;
		}
	}
}






工程鏈接:https://pan.baidu.com/s/1QXB_ALAOFp-71YSm94Po-g?
提取碼:0xFF

The END文章來源地址http://www.zghlxwxcb.cn/news/detail-462253.html

到了這里,關(guān)于STM32 HAL庫 PWM+DMA 驅(qū)動WS2812B彩燈(STM32F030F4P6)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • [HAL]STM32 SPI+DMA驅(qū)動WS2812

    [HAL]STM32 SPI+DMA驅(qū)動WS2812

    該程序是純手敲,非Cube生成!所有代碼均注釋。 源碼在文章后面獲取 Keyword: 單線通訊、歸零碼、Reset、RGB順序 RGB一共有24bit位 -相當于驅(qū)動一個燈要24bit位 -驅(qū)動若干個燈要24* n bit位,通過Reset碼決定數(shù)據(jù)終止(保持) 24bit位應(yīng)該如何發(fā)送? 可見: 表示低電平需要 T0H和T0L的配

    2024年02月09日
    瀏覽(33)
  • 【STM32F4系列】【HAL庫】【自制庫】WS2812(軟件部分)(PWM+DMA)

    【STM32F4系列】【HAL庫】【自制庫】WS2812(軟件部分)(PWM+DMA)

    硬件介紹(PCB設(shè)計方案) 模擬時序發(fā)送 WS2812是一種異步串行通信,它每一位數(shù)據(jù)時間是ns級別的 默認是高電平狀態(tài) 0碼:220-380ns高電平+580-1600ns低電平 1碼:580-1600ns高電平+220-380ns低電平 復(fù)位碼:280us低電平 24Bit數(shù)據(jù)來代表GRB的亮度值 從高位到低位發(fā)送,分別按照G-R-B的順序發(fā)送

    2024年02月15日
    瀏覽(25)
  • STM32G0 定時器PWM DMA輸出驅(qū)動WS2812配置 LL庫

    STM32G0 定時器PWM DMA輸出驅(qū)動WS2812配置 LL庫

    優(yōu)點:不消耗CPU資源 缺點:占用內(nèi)存較大 定時器配置 定時器通道:TIM3 CH2 分頻:0 重裝值:79,芯片主頻64Mhz,因此PWM輸出頻率:64Mhz/79 ≈ 800Khz,滿足芯片要求。 auto-reload preload 要關(guān)閉 output compare preload 要打開 DMA配置 外設(shè)一定要選擇TIM3_UP,不要選TIM_CHx 方向是內(nèi)存到外設(shè),

    2024年02月10日
    瀏覽(118)
  • 關(guān)于STM32利用TIM+PWM+DMA控制WS2812

    關(guān)于STM32利用TIM+PWM+DMA控制WS2812

    MCU:STM32F103c8t6 開發(fā)工具:STM32CubeMX ?使用板子參考原理圖:STM32F103C8T6最小系統(tǒng)板開源鏈接 脈寬調(diào)制(PWM)基本原理:控制方式就是對逆變電路開關(guān)器件的通斷進行控制,使輸出端得到一系列幅值相等但寬度不一致的脈沖,用這些脈沖來代替正弦波或所需要的波形。也就是在輸

    2024年02月01日
    瀏覽(21)
  • 使用STM32F103的SPI+DMA驅(qū)動ws2812 LED

    使用STM32F103的SPI+DMA驅(qū)動ws2812 LED

    目錄 前言 一、WS2812協(xié)議 1.1 數(shù)據(jù)傳輸編碼方式: ?1.2 傳輸?shù)臄?shù)據(jù)結(jié)構(gòu) 二、驅(qū)動方式:SPI+DMA 2.1 原理介紹 2.2 SPI+DMA操作 ?2.3 編寫代碼 2.4 使用 三 總結(jié) 參考文章 主要使用的STM32F103C8T6芯片的SPI+DMA方式實現(xiàn)WS2812的驅(qū)動協(xié)議,總體可以看作是使用SPI來實現(xiàn)一種通信協(xié)議來發(fā)送信號。

    2024年02月09日
    瀏覽(30)
  • 軟件STM32cubeIDE下STM32F1xx使用定時器(TIM8)+DMA+PWM點亮燈帶WS2812-基礎(chǔ)樣例

    軟件STM32cubeIDE下STM32F1xx使用定時器(TIM8)+DMA+PWM點亮燈帶WS2812-基礎(chǔ)樣例

    好長時間不調(diào)試燈帶ws2812了,最近項目上,要在STM32F1上進行點燈帶ws2812,雖然自己之前做了很多了,但是人有個性質(zhì),一旦某個事情做完了,你不在去惦記它了,基本會完全拋在腦后。所以才體現(xiàn)記錄的重要性,本次在做STM32F1上驗證時,即使之前有經(jīng)驗的情況下,還是掉坑

    2024年02月01日
    瀏覽(16)
  • STM32單片機聲控語音識別RGB彩燈多種模式亮度可調(diào)WS2812彩燈
  • 講解STM32驅(qū)動WS281x燈珠的多種實現(xiàn)方式:普通IO、SPI+DMA、以及PWM+DMA驅(qū)動方法

    STM32作為一款高性能、功能豐富的單片機,其豐富的外設(shè)和強大的性能,使其在嵌入式領(lǐng)域得到了廣泛的應(yīng)用。本篇文章將介紹如何利用STM32驅(qū)動WS281x系列的LED燈珠。我們會使用三種不同的驅(qū)動方式進行實現(xiàn):一種是普通IO方式驅(qū)動,一種是SPI+DMA方式驅(qū)動,最后一種是PWM+DMA方

    2024年02月11日
    瀏覽(20)
  • WS2812B燈帶驅(qū)動實驗

    WS2812B燈帶驅(qū)動實驗

    KEIL5、正點原子阿波羅STM32F767開發(fā)板 過多介紹我這里不贅述了,想了解詳情的可以看看手冊,直接開干。 1.1、燈帶連接方式 我們只要控制DIN端就好了。 1.2、傳輸數(shù)據(jù)方式 簡單理解就是單總線發(fā)了一串數(shù)據(jù),第一個燈拿了第一個字節(jié)的數(shù)據(jù),第二個燈拿個第二個字節(jié)的數(shù)據(jù),

    2024年02月08日
    瀏覽(18)
  • WS2812B 驅(qū)動程序

    WS2812B 驅(qū)動程序

    : WS2812 ,STM32G030F6 說 明: 本代碼用于驅(qū)動 16 個RGB LED(WS2812 )模塊,可以按16個預(yù)定顏色的流水顯示, 使用RT-Thread RTOS 基于STM32G030F6 最小系統(tǒng)板的 ws2812 驅(qū)動工程。 ????????WS2812是一個集控制電路與發(fā)光電路于一體的外控LED光源,外形一般為5050封裝,每個LED燈珠為

    2024年02月11日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包