0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32C0开发(1)----SPI 驱动WS2812灯珠

嵌入式单片机MCU开发 来源:嵌入式单片机MCU开发 作者:嵌入式单片机MCU开 2023-12-01 16:47 次阅读

概述

本文介绍了如何使用STM32微控制器,结合STM32CubeMX配置工具和SPI通讯接口,来驱动和控制WS2812 LED灯带。这是一个集硬件连接、软件配置和编程开发于一体的综合性项目,目标是实现对LED灯带颜色和亮度的精确控制。

最近在弄ST的课程,需要样片的可以加群申请:615061293 。

在这里插入图片描述

视频教学

[https://www.bilibili.com/video/BV1X94y157W8/

样品申请

[https://www.wjx.top/vm/OhcKxJk.aspx#]
在这里插入图片描述

源码下载

[https://download.csdn.net/download/qq_24312945/88489586

芯片级联方法

在这里插入图片描述

芯片在上电复位以后,接收DIN端打来的数据,接收够24bit后,DO端口开始转发数据,供下一个芯片提供输入数据。在转发之前,DO口一直拉低。此时灯珠将不接收新的数据,内置RGB芯片根据接收到的24bit数据后产生的不同占空比信号,展现不同亮度。如果DIN端输入信号为RESET信号,芯片将接收到的数据送显示,芯片将在该信号结束后重新接收新的数据,在接收完开始的24bit数据后,通过DO口转发数据,灯珠在没有接收到RESET码前,RGB亮度保持不变,当接收到80us以上低电平RESET码后,灯珠内部RGB芯片将根据刚才接收到的24bit数据后产生的不同占空比信号,展现不同亮度。

在这里插入图片描述

数据传输

在这里插入图片描述
24bit数据结构:

在这里插入图片描述

时序

时序波形图如下所示。

在这里插入图片描述
在这里插入图片描述

SPI配置

将SPI的配置速度设为6M,数据宽度设为8位。
CPHA配置为第二边沿采样;在第一个跳变沿时,MOSI在空闲状态保持高电平,而在第二个跳变沿,它会保持上一次传输的最终电平。由于发送数据的最后一位总是低电平,这样配置可以避免WS2812误判。CPOL设置为高,确保SCK在空闲时保持高电平状态。

在这里插入图片描述

系统采用单总线协议,通过总线上高低电平的时长来区分逻辑0和1。WS2811工作在800kHz频率下,将SPI设置为6.4MHz—即其工作频率的8倍—可以确保每个字节(8位)正好对应一个逻辑位。在这种设置下,‘11111000’(0xF8)代表逻辑1,‘11000000’(0xC0)代表逻辑0。

在这里插入图片描述

逻辑0下发送的数据为11000000’(0xC0)。
逻辑0下高电平位320ns。

在这里插入图片描述

逻辑0下低电平位1.01us。

在这里插入图片描述

逻辑1下发送的数据为‘11111000’(0xF8)。
逻辑1下高电平位830ns。

在这里插入图片描述
逻辑1下低电平位500ns。
在这里插入图片描述

这种精确的时序配置和电平控制对于确保WS2812灯带的正确驱动至关重要,可以通过上述配置来优化SPI接口的性能,确保与WS2812的高效通信

CPHA配置

CPHA配置为第二边沿采样下数据传输结束如下所示。

在这里插入图片描述
CPHA配置为第二边沿采样下数据传输结束如下所示。

在这里插入图片描述

由于RESET Code为低电平,且要大于80us,所以数据传输完毕必须为低电平。

在这里插入图片描述

代码

在main.c中添加头文件。

/* USER CODE BEGIN Includes */
#include "ws2812.h"
#include < string.h >
/* USER CODE END Includes */

在main.c中添加函数申明和移位操作。

/* USER CODE BEGIN 0 */
extern tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT];

void move_Front()
{
	uint8_t i;
	uint8_t temp[3];
	temp[0] = gWs2812bDat[0].R;
	temp[1] = gWs2812bDat[0].G;
	temp[2] = gWs2812bDat[0].B;	
	for (i = 0; i < WS2812B_AMOUNT-1; i++)
	{
		gWs2812bDat[i].R = gWs2812bDat[i+1].R;
		gWs2812bDat[i].G = gWs2812bDat[i+1].G;
		gWs2812bDat[i].B = gWs2812bDat[i+1].B;
	}
		gWs2812bDat[7].R = temp[0];
		gWs2812bDat[7].G = temp[1];
		gWs2812bDat[7].B = temp[2];
}


/* USER CODE END 0 */

添加初始化显示。

/* USER CODE BEGIN 2 */
	WS2812B_Task();
	HAL_Delay(1000);
  /* USER CODE END 2 */

添加流水灯。

/* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	WS2812B_Task();	
	move_Front();
	HAL_Delay(100);
    /* USER CODE END WHILE */

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

ws2812.c

#include "ws2812.h"
#include "spi.h"

//灯条显存SPI数据缓存
uint8_t gWs2812bDat_SPI[WS2812B_AMOUNT * 24] = {0};	
//灯条显存
tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT] = {

//R    G      B
0XFF, 0X00, 0X00,	//0
0X00, 0XFF, 0X00,	//1
0X00, 0X00, 0XFF,	//2
0X00, 0XFF, 0XFF,	//3
0XFF, 0X00, 0XFF,	//4
0XFF, 0XFF, 0X00,	//5
0XFF, 0XFF, 0XFF,	//6
0X00, 0X00, 0X00,	//7
};
		
void WS2812b_Set(uint16_t Ws2b812b_NUM, uint8_t r,uint8_t g,uint8_t b)
{
	uint8_t *pR = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24 + 8];
	uint8_t *pG = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24];
	uint8_t *pB = &gWs2812bDat_SPI[(Ws2b812b_NUM) * 24 + 16];
	
	for(uint8_t i = 0; i <  8; i++) {
		if(g & 0x80) {
			*pG = CODE_1;
		}           
		else {           
			*pG = CODE_0;
		}           
		if(r & 0x80) {           
			*pR = CODE_1;
		}           
		else {           
			*pR = CODE_0;
		}           
		if(b & 0x80) {           
			*pB = CODE_1;
		}           
		else {           
			*pB = CODE_0;
		}
		r < <= 1;
		g < <= 1;
		b < <= 1;
		pR++;
		pG++;
		pB++;
	}
}
void WS2812B_Task(void)
{
	uint8_t dat = 0;
	
	//将gWs2812bDat数据解析成SPI数据
	for(uint8_t iLED = 0; iLED < WS2812B_AMOUNT; iLED++)
	{
		WS2812b_Set(iLED, gWs2812bDat[iLED].R, gWs2812bDat[iLED].G, gWs2812bDat[iLED].B);
	}
	//总线输出数据
	HAL_SPI_Transmit(&hspi1, gWs2812bDat_SPI, sizeof(gWs2812bDat_SPI),0XFFFF);
	//使总线输出低电平
	HAL_SPI_Transmit(&hspi1, &dat, 1,0XFFFF);
	//帧信号:一个大于50us的低电平
	HAL_Delay(1);	
}

ws2812.h

#ifndef __WS2812_H__
#define __WS2812_H__

#include < stdint.h >

//            编码 0 : 11000000
#define CODE_0		0xC0
//            编码 1 : 11111000
#define CODE_1		0xF8
/*ws2812b灯珠数量*/
#define WS2812B_AMOUNT		8

typedef struct
{
	uint8_t R;
	uint8_t G;
	uint8_t B;
} tWs2812bCache_TypeDef;

extern tWs2812bCache_TypeDef gWs2812bDat[WS2812B_AMOUNT];

void WS2812b_Set(uint16_t Ws2b812b_NUM, uint8_t r,uint8_t g,uint8_t b);
void WS2812B_Task(void);

#endif
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 驱动
    +关注

    关注

    12

    文章

    1824

    浏览量

    85168
  • SPI
    SPI
    +关注

    关注

    17

    文章

    1700

    浏览量

    91291
  • WS2812
    +关注

    关注

    0

    文章

    32

    浏览量

    6125
  • stm32cubemx
    +关注

    关注

    5

    文章

    280

    浏览量

    14746
收藏 人收藏

    评论

    相关推荐

    瑞萨e2studio(28)----SPI 驱动WS2812

    本文介绍了如何使用瑞萨RA微控制器,结合E2STUDIO配置工具和SPI通讯接口,来驱动和控制WS2812 LED带。这是一个集硬件连接、软件配置和编程
    的头像 发表于 12-01 16:48 1916次阅读
    瑞萨e2studio(28)----<b class='flag-5'>SPI</b> <b class='flag-5'>驱动</b><b class='flag-5'>WS2812</b><b class='flag-5'>灯</b><b class='flag-5'>珠</b>

    stm32F767 控制WS2812的问题

    使用stm32F767 PWM+DMA控制108个WS2812, 第一个颜色有时不正常,其它
    发表于 08-19 17:43

    WS2812B RGB全彩LED

    WS2812B RGB全彩LED,只需通过一根信号线控制多个显示,本教程使用X-CTR100控制器驱动
    发表于 08-06 08:15

    STM32控制WS2812 RGB带的代码分享

    STM32控制WS2812 RGB带的代码分享
    发表于 12-15 07:09

    Arduino控制WS2812带的方法

    形与一个5050LED相同,每个元件即为一个像素点。像素点内部包含了智能数字接口数据锁存信号整形放大电路,还包括有高精度的内部振荡器和可编程电流控制部分,有效保证了像素点的颜色高度一致。1)FastLED库FastLED 是
    发表于 01-12 08:08

    为什么用树莓派驱动WS2812会不亮呢

    为什么用树莓派驱动WS2812会不亮呢?是什么原因?如何解决?
    发表于 01-18 06:11

    STM32F103C8T6+PWM+DMA驱动WS2812带的方法

    #STM32+PWM+DMA驱动 WS2812带#文章目录1.理论:2代码:理论:使用STM32F10
    发表于 02-22 06:59

    【感芯科技MC3172开发板体验】WS2812音乐

    首先是确保能够正常驱动WS2812,这里我借鉴了一位大佬的文章:【代码分享】用spi驱动任意数量ws2812 / 感芯科技 / WhyCa
    发表于 06-09 00:49

    【悟空派H3开发板免费体验】基于spi驱动WS2812

    使用spi引脚驱动WS2812,接线端口如下 程序如下spi_ws2812.c: #include \"sys/types.h\" #include \"sys
    发表于 10-10 22:33

    如何进行WS2812的面板制作详细资料合集免费下载

    本文档的主要内容详细介绍的是如何进行WS2812的面板制作详细资料合集免费下载包括了:DMX512转WS2812 面板程序,STC8系列单片机技术参考手册,
    发表于 05-29 17:36 163次下载
    如何进行<b class='flag-5'>WS2812</b>的面板<b class='flag-5'>灯</b>制作详细资料合集免费下载

    STM32使用LL库PWM的DMA模式驱动ws2812

    驱动n个,当然n是有限制的。时序超级简单,也有一定难度。类似的帖子网上有很多,在此不再赘述。WS2812驱动方式大概有以下几种:1.使用GPIO模拟,中间加延时实现“
    发表于 11-30 10:21 66次下载
    <b class='flag-5'>STM32</b>使用LL库PWM的DMA模式<b class='flag-5'>驱动</b><b class='flag-5'>ws2812</b>

    STM32F103C8T6+PWM+DMA驱动 WS2812

    #STM32+PWM+DMA驱动 WS2812带#文章目录1.理论:2代码:理论:使用STM32F10
    发表于 12-27 19:29 213次下载
    <b class='flag-5'>STM32F103C</b>8T6+PWM+DMA<b class='flag-5'>驱动</b> <b class='flag-5'>WS2812</b><b class='flag-5'>灯</b>带

    最简WS2812类似RGB驱动方法

    最简WS2812类似RGB驱动方法
    的头像 发表于 06-19 17:51 3402次阅读
    最简<b class='flag-5'>WS2812</b>类似RGB<b class='flag-5'>灯</b>条<b class='flag-5'>驱动</b>方法

    迪文屏控制WS2812氛围

    ——来自迪文开发者论坛本期为大家推送迪文开发者论坛获奖开源案例——迪文屏控制WS2812氛围。工程师通过COF智能屏的OS核精准控制WS2812
    的头像 发表于 01-26 08:12 945次阅读
    迪文屏控制<b class='flag-5'>WS2812</b>氛围<b class='flag-5'>灯</b>

    论如何使用WS2812以及类似

    ​  WS2812 LED,这是一种非常流行的可寻址RGB LED。每个WS2812 LED内部集成了控制电路,因此可以通过一个数据输入线来单独控制每一个LED的颜色和亮度。这种特
    的头像 发表于 09-30 15:11 294次阅读
    论如何使用<b class='flag-5'>WS2812</b>以及类似<b class='flag-5'>灯</b><b class='flag-5'>珠</b>