关于ws2812b详细的相关信息可以参考(15条消息) WS2812B全彩LED驱动__祥子@的博客-CSDN博客_ws2812b
代码会放在最下方,话不多说直接开始
一.新建rt-thread项目
ps:由于我用的开发板是STM32F407VET6,各位·可以按自己芯片型号创建工程。
二.使用cubemx生成代码
1.配置时钟:
注意:使用cubemx生成代码一定要先打开串口下载和使能USART1,否则可能会出错!!!
2.打开串口下载:
3.打开USART1:
4.打开spi:
由于我们只用到发送功能。所以配置为只发送,节省资源
5.修改引脚:
由于我用cubemx默认的spi2引脚做开发会造成冲突,所以需要修改默认引脚,只需修改SCK和MOSI,其他默认不变,修改如下:
RGB灯的信号线插在SPI_MOSI上
6.生成代码并关闭cubemx
三.配置rt-thread工程
(ps:最新4.1.0已经不需要再次配置,直接编译即可,如果编译不通过再看以下步骤)
1.把cubemx生成的配置代码拷贝到driver.c文件最下方:
复制完之后要删除stm32f4xx_hal_msp.c内所有代码,不然编译会报一大堆错!!!!!!
然后编译一下代码,会有一个报错:
发现是void Error_Handler(void);重复定义,注释掉这一行代码就可以。
再编译就没有报错了:
2.rt-thread配置spi:
使能spi模块
恭喜,到此为止准备工作全部完成!
四.添加代码:
ps:ws2812b代码框架由github大佬Shifeng Li编写,主页:hepingood (Shifeng Li) (github.com)
ws2812b Interface由Ryan_CW帮助修改
只需要把四个文件全部拖到RT-ThreadStudio\workspace\(你自己的工程)\applications目录下,然后进入rtthread重新编译就能看到添加成功
核心代码说明:
//RT—thread SPI框架初始化
static int rt_hw_spi_ws2812_init(void)
{
rt_hw_spi_device_attach("spi2", "spi20", GPIOB, GPIO_PIN_12);//把spi2的0号设备设备挂载在总线上
spi_dev = rt_device_find("spi20");
if (NULL == spi_dev)
return 1;
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_3 | RT_SPI_MSB;
cfg.max_hz = 20 * 1000 * 1000; /* 20M */ //如果rgb显示有问题就改这里,8m,10m都可以
rt_spi_configure(spi_dev, &cfg);
return RT_EOK;
}
/* 导出到自动初始化 */
INIT_COMPONENT_EXPORT(rt_hw_spi_ws2812_init);
//ws2812初始化
uint8_t ws2812_init()
{
uint8_t res;
/* link interface function */
DRIVER_WS2812B_LINK_INIT(&gs_handle, ws2812b_handle_t);
//等价于:gs_handle.spi_10mhz_init = ws2812b_interface_spi_10mhz_init;
DRIVER_WS2812B_LINK_SPI_10MHZ_INIT(&gs_handle, ws2812b_interface_spi_10mhz_init);
DRIVER_WS2812B_LINK_SPI_DEINIT(&gs_handle, ws2812b_interface_spi_deinit);
DRIVER_WS2812B_LINK_SPI_WRITE_COMMAND(&gs_handle, ws2812b_interface_spi_write_cmd);
DRIVER_WS2812B_LINK_DELAY_MS(&gs_handle, ws2812b_interface_delay_ms);
DRIVER_WS2812B_LINK_DEBUG_PRINT(&gs_handle, ws2812b_interface_debug_print);
/* ws2812b initialization */
res = ws2812b_init(&gs_handle);
if (res != 0)
{
ws2812b_interface_debug_print("ws2812b: init failed.\n");
return 1;
}
return 0;
}
/**
* @brief 向ws2812写数据
* @param cnt:节点(灯珠)个数。colors:颜色
* @return status code
* - 0 success
* - 1 write byte failed
* @note none
*/
uint8_t ws2812b_write_test(uint32_t cnt,uint32_t colors)
{
uint8_t res;
uint32_t num;
uint32_t j;
const uint32_t color[1] = {colors};
/* set number */
num = cnt > 21 ? 21 : cnt;
for (j = 0; j < num; j++)
{
gs_rgb[j] = color[0];
}
res = ws2812b_write(&gs_handle, (uint32_t *)gs_rgb, num, gs_buffer, 1024);
if (res != 0)
{
ws2812b_interface_debug_print("ws2812b: write failed.\n");
(void)ws2812b_deinit(&gs_handle);
return 1;
}
/* delay 1000 ms */
ws2812b_interface_delay_ms(100);
return 0;
}
//关闭所有灯
uint8_t ws2812_clearn_all(uint32_t cnt1)
{
uint8_t res;
uint32_t num1;
uint32_t j;
num1 = cnt1 > 21 ? 21 : cnt1;
for (j = 0; j < num1; j++)
{
gs_rgb[j] = 0x00;
}
res = ws2812b_write(&gs_handle, (uint32_t *)gs_rgb, num1, gs_buffer, 1024);
ws2812b_interface_delay_ms(100);
return 0;
}
然后编译烧录就可以了
五.效果展示
ws2812b_write_test(10,red);
ws2812b_write_test(10,yellow);
ws2812b_write_test(5,blue);
示例代码:链接:百度网盘 请输入提取码提取码:wbv5