RT-thread使用SPI驱动WS2812B多图小白教程

关于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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值