Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
ws2812
SPI+DMA
STM32F411
stm32f411ceu6最小开发板使用SPI+DMA驱动ws2812b
发布于 2020-07-11 17:33:07 浏览:3017
订阅该版
**发现没有此类软件包和论坛里此类相关信息较少** **小的在此处留个包,供大家测试和使用** **如有BUG,请发消息联系我。** > SPI 配置成 13.333MHZ (我使用开发板是:STM32F411CUE6最小开发板,SPI的通讯频率我测试过 2.5Mhz、3.333Mhz、6.666Mhz、13.333Mhz, 最终选择13.333Mhz的原因:这个稳定) > > 2byte(MCU) == 1bit(ws2812b) > > 1个ws2812b节点需要 2 x 8 x 3 = 48字节 因此,太多节点的人,请谨慎使用。 **ws2812.h** ```c /* * @Author: maplerian * @Date: 2020-07-11 16:03:03 * @LastEditors: maplerian * @LastEditTime: 2020-07-11 16:53:52 * @Description: file content */ #ifndef __WS2812__H__ #define __WS2812__H__ #include
#include
// 一位占用多少个字节 #define OneBitOccupyByte 2 #define OneNodeBuffLength 8 * 3 * OneBitOccupyByte struct ws2812 { struct rt_spi_device *spi; uint8_t *buff; uint16_t node_len; }; typedef struct ws2812 * ws2812_t; ws2812_t ws2812_create(char *spi_name, uint16_t led_node_length); void ws2812_clear_buff(ws2812_t ws2812); void ws2812_write_rgb_to_node(ws2812_t ws2812, uint16_t index, uint8_t r, uint8_t g, uint8_t b); void ws2812_write_rgb_to_all(ws2812_t ws2812, uint8_t r, uint8_t g, uint8_t b); void ws2812_send(ws2812_t ws2812); #endif //!__WS2812__H__ ``` **ws2812.c** ```c /* * @Author: maplerian * @Date: 2020-07-11 16:02:23 * @LastEditors: maplerian * @LastEditTime: 2020-07-11 17:23:30 * @Description: file content */ #include "ws2812.h" ws2812_t ws2812_create(char *spi_name, uint16_t led_node_length) { if (!spi_name || !led_node_length) return RT_NULL; struct rt_spi_device *spi = (struct rt_spi_device *)rt_device_find(spi_name); if (spi == RT_NULL) return RT_NULL; ws2812_t ws2812 = (ws2812_t)rt_malloc(sizeof(struct ws2812)); ws2812->buff = (uint8_t *)rt_malloc(OneNodeBuffLength * led_node_length); if (!ws2812->buff) { rt_kprintf("There is not enough memory to create a buffer.\r\n"); rt_free(ws2812); return RT_NULL; } // 配置 spi struct rt_spi_configuration ws2812_spi_config; ws2812_spi_config.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB; // 高位在前 ws2812_spi_config.max_hz = 13 * 1000 * 1000 + 333 * 1000; // 200ns / bit => 8bit 1.6us => 1.25us < 1.6us < 1.85us 可行 6M 3b = 500ns 5b = 833ns ws2812_spi_config.data_width = 8; rt_spi_configure((struct rt_spi_device *)spi, &ws2812_spi_config); // 赋值 ws2812->spi = spi; ws2812->node_len = led_node_length; return ws2812; } void ws2812_clear_buff(ws2812_t ws2812) { if (!ws2812 || !ws2812->buff || !ws2812->node_len) return; rt_memset(ws2812->buff, 0x00, OneNodeBuffLength * ws2812->node_len); } // 写颜色节点颜色到缓冲区 // 2byte == 1bit void ws2812_write_buff(uint8_t *buff, uint8_t r, uint8_t g, uint8_t b) { uint32_t rgb = g << 24 | r << 16 | b << 8; uint8_t i = 24; while (i--) { // bit 1: 1111 1111 1110 0000 if (rgb & 0x80000000) { *buff++ = 0xff; *buff++ = 0xe0; } // bit 0: 1111 1000 0000 0000 else { *buff++ = 0xf8; *buff++ = 0x00; } // 👆 bit 1: 11bit h, bit 0: 5bit h rgb <<= 1; } } void ws2812_write_rgb_to_node(ws2812_t ws2812, uint16_t index, uint8_t r, uint8_t g, uint8_t b) { ws2812_write_buff(&ws2812->buff[OneNodeBuffLength * index], r, g, b); } void ws2812_write_rgb_to_all(ws2812_t ws2812, uint8_t r, uint8_t g, uint8_t b) { uint16_t i; for (i = 0; i < ws2812->node_len; i++) ws2812_write_rgb_to_node(ws2812, i, r, g, b); } void ws2812_send(ws2812_t ws2812) { if (!ws2812 || !ws2812->spi || !ws2812->buff) { rt_kprintf("Parame is null\r\n"); return; } uint8_t reset[100] = {0x00}; // 新帧信号 // 颜色数据 rt_spi_send_then_send(ws2812->spi, reset, sizeof(reset), ws2812->buff, OneNodeBuffLength * ws2812->node_len); } ``` **示例:** ```c #include "ws2812.h" int ws2812b_test(int argc, char *argv[]) { rt_device_t ws2812b_spi = rt_device_find(WS2812B_SPI_NAME); if (ws2812b_spi == RT_NULL) rt_hw_spi_device_attach("spi1", WS2812B_SPI_NAME, GPIOA, GPIO_PIN_6); rt_thread_mdelay(50); ws2812_t ws2812 = ws2812_create(WS2812B_SPI_NAME, 8); if (!ws2812) { rt_kprintf("create ws2812 object faild.\r\n"); return RT_ERROR; } // 最低颜色值: 低于这个值可能会造成某节点无法显示这个值 #define COLOR_MIN_VALUE 10 ws2812_write_rgb_to_all(ws2812, COLOR_MIN_VALUE, 0, 0); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, 0, COLOR_MIN_VALUE, 0); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, 0, 0, COLOR_MIN_VALUE); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, COLOR_MIN_VALUE, COLOR_MIN_VALUE, 0); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, COLOR_MIN_VALUE, 0, COLOR_MIN_VALUE); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, 0, COLOR_MIN_VALUE, COLOR_MIN_VALUE); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, COLOR_MIN_VALUE, COLOR_MIN_VALUE, COLOR_MIN_VALUE); ws2812_send(ws2812); rt_thread_mdelay(500); ws2812_write_rgb_to_all(ws2812, 0, 0, 0); ws2812_send(ws2812); rt_thread_mdelay(500); return 1; } MSH_CMD_EXPORT(ws2812b_test, ws2812b spi sample); ``` **软件包:** [ws2812b.zip](/uploads/20200711/e50cc24509b16e220e021b8c2260c173.zip)
2
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
昂头向前走
这家伙很懒,什么也没写!
文章
2
回答
12
被采纳
0
关注TA
发私信
相关文章
1
移植finsh遇到问题?
2
正点原子战舰V3+ENC28J60+SPI,开启SPI DMA后,卡死
3
SPI4设置DMA RX 错误
4
spi DMA 发送数据失败
5
spi dma 中断接收的问题
6
关于spi和dma的问题
7
RT Studio中F407芯片SPI的DMA怎么开启?
8
RT Studio中SPI+DMA如何使用?
9
rt-thread 互斥信号量BUG
10
我现在可以使用SPI正常收发数据了,但是怎样使用SPI的DMA模式进行数据的收发
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
a1012112796
19
个答案
2
次被采纳
张世争
9
个答案
2
次被采纳
rv666
6
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部