加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

嵌入式外设集-RGB灯珠模块(WS2812B)驱动

03/20 16:29
1652
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
相关方案
  • 方案介绍
    • 一、模块介绍
    • 二、资料获取
    • 三、 实验器材
    • 四、实现效果
    • 五、主要代码
    • 六、参考
  • 相关文件
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

一、模块介绍

WS2812B是一种流行的可编程LED模块,通常被称为“NeoPixel”。它是一种智能LED灯模块,具有以下主要特点和功能:

1. 集成性:WS2812B模块集成了一个RGB LED和一个控制芯片,这意味着每个模块都包含了完整的LED驱动电路,而不需要外部元件。

2. 可编程:每个WS2812B模块都可以通过单个数据线进行编程和控制。通过发送适当的数据信号,您可以精确地控制LED的颜色和亮度。

3. 链接性:多个WS2812B模块可以链接在一起,形成一个LED灯带、LED矩阵或其他形状,以创建更大的光效。

4. 低电压工作:WS2812B模块通常在5V电源下工作,但也有3.3V版本。这使得它们适用于各种不同的电子项目。

5. 简化控制:WS2812B模块的控制相对简单,因为它们只需要一个数据信号线来控制。这使得它们易于与微控制器(如Arduino)或单片机嵌入式系统集成。

6. RGB控制:每个WS2812B模块都包含一个红色(R)、绿色(G)和蓝色(B)LED,允许您混合这些颜色来创建各种颜色效果。

7. 亮度控制:您可以通过调整数据信号中的亮度值来控制LED的亮度级别,从而创建不同的光效。

WS2812B模块广泛用于各种应用,如彩色LED照明、LED艺术装置、LED显示屏和互动装置。它们的灵活性和易于控制使它们成为电子爱好者和制造商的热门选择,用于创建令人惊叹的LED项目。要使用WS2812B模块,您通常需要了解如何编程控制它们,以及如何提供适当的电源和连接。

二、资料获取

关注微信公众号--星之援工作室 发送关键字(WS2812B)

➡️➡️

三、 实验器材

1.单片机:STM32F103C8T6

2.元器件:8灯珠的WS2812B

3.端口占用:WS2812B -- PA2

四、实现效果

跑马灯效果,渐变色

五、主要代码

WS2812B.c

主要使用 PWMDMA 进行控制

#include "WS2812B.h"

uint16_t LED_BYTE_Buffer[24];	//发送数组缓存
uint32_t LED_WORD_Buffer[8];

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

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, 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_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_OC3Init(TIM2, &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)&TIM2->CCR3;	// 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(TIM2, TIM_DMA_Update, ENABLE);
}


void send_Data(uint32_t rgb)
{

	uint8_t r = (rgb&0xff0000)>>16;
	uint8_t g = (rgb&0x00ff00)>>8;
	uint8_t b = (rgb&0xff);
	for(uint16_t i=0;i<8;i++){
		LED_BYTE_Buffer[i] = (0x80&g)>0?TIMING_ONE:TIMING_ZERO;g <<= 1;
	}
	for(uint16_t i=0;i<8;i++){
		LED_BYTE_Buffer[8 + i] = (0x80&r)>0?TIMING_ONE:TIMING_ZERO;r <<= 1;
	}
	for(uint16_t i=0;i<8;i++){
		LED_BYTE_Buffer[16 + i] = (0x80&b)>0?TIMING_ONE:TIMING_ZERO;b <<= 1;
	}
	DMA_SetCurrDataCounter(DMA1_Channel2, 24); 	// load number of bytes to be transferred
    DMA_Cmd(DMA1_Channel2, ENABLE); 			// enable DMA channel 6
    TIM_Cmd(TIM2, ENABLE); 						// enable Timer 3
    while(!DMA_GetFlagStatus(DMA1_FLAG_TC2)) ; 	// wait until transfer complete
	TIM_Cmd(TIM2, DISABLE); 					// disable Timer 3
    DMA_Cmd(DMA1_Channel2, DISABLE); 			// disable DMA channel 6
    DMA_ClearFlag(DMA1_FLAG_TC2); 				// clear DMA1 Channel 6 transfer complete flag
}

WS2812B.h

#ifndef __WS2812B_H
#define __WS2812B_H	
#include "stm32f10x.h"


#define TIMING_ONE  50	//T1H	1码
#define TIMING_ZERO 25	//T0L   0码


void WS2812B_TIM_init(void);
void send_Data(uint32_t rgb);


#endif //__WS2812B_H

main.c

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "WS2812B.h"
#include <stdlib.h>

uint32_t *RGB;//颜色列表数组

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);//每两种颜色之间的位数
	
    while(1)
    {
			out_RGB(len,8);//8个灯,每次输出8个数据
			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;//末尾颜色数据结束时将首位的收据填充到数组
		send_Data(RGB[c]);
	}
	rgb_position ++;
	rgb_position %= data_Max_Length;
}

/**
 * color_length 每种颜色渐变最大长度,总颜色长度:color_length * 3
 * return 颜色数据总长度
 */
uint32_t set_Color_Loop(uint8_t color_length)
{
	RGB = (uint32_t*)malloc(color_length*3*sizeof(uint32_t));//分配数组大小,(所有渐变色颜色长度)
	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;
}


六、参考

【STM32】WS2812B灯珠的PWM+DMA控制(库函数)icon-default.png?t=N7T8https://blog.csdn.net/ii1i2huo/article/details/122619197?ops_request_misc=&request_id=&biz_id=102&utm_term=ws2812b%E6%B5%81%E6%B0%B4%E7%81%AFstm32%E5%90%AF%E5%8A%A8&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-2-122619197.142^v96^pc_search_result_base7&spm=1018.2226.3001.4187


完整代码请关注卫星公众号进行获取和咨询


联系方式 微信号:13648103287

  • 联系方式.docx

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
SA605DK/01,112 1 NXP Semiconductors SA605 - High performance low power mixer FM IF system SSOP2 20-Pin
$5.47 查看
TPA3118D2DAPR 1 Texas Instruments 30-W stereo, 60-W mono, 4.5- to 26-V supply, analog input Class-D audio amplifier 32-HTSSOP -40 to 85
$2.85 查看
TDA8547TS/N1,112 1 NXP Semiconductors TDA8547TS - 2 × 0.7 W BTL audio amplifier with output channel switching SSOP2 20-Pin

ECAD模型

下载ECAD模型
$2.51 查看

相关推荐

电子产业图谱

方案定制,程序设计方案、单片机程序设计与讲解、APP定制开发。本公众号致力于向读者传递关于程序设计和开发的相关知识,并分享一些关于软件开发的最佳实践。如果您有什么问题或建议,请随时联系我们。我们将竭诚为您服务