基于 RT-Thread Stduio 的 SPI 驱动开发文档

简介

SPI 是一种高速、全双工、同步串行通信总线,常用于 MCU 与数字芯片之间的短距离通讯。RT-Thread 的 SFUD 组件,RW007 WIFI 模块均使用到了 SPI 驱动。下面将基于 stm32l475-atk-pandora 开发板,讲解基于 RT-Thread Studio 开发 SPI 驱动。

新建 RT-Thread 项目

使用 RT-Thread Studio 新建基于 v4.0.2 的工程,界面如下图所示

spi-project

配置过程可总结为以下步骤:

  • 定义自己的工程名及工程生成文件的存放路径

  • 选择 基于芯片 创建工程,选择的 RT-Thread 版本为 v4.0.2

  • 选择厂商及芯片型号

  • 配置串口信息

  • 配置调试器信息

工程配置完成后点击下方的 完成 按钮即可创建 RT-Thread 的工程。

打开 SPI 框架

RT-Thread Setting 文件中借助图形化配置工具打开软件 SPI 的驱动框架,如下图所示

open-frame

左键单击即可开启 SPI 驱动框架(组件开启,相应的图标会高亮),在该选项上右键,可查看 SPI 的 详细配置,具体配置路径如下所示

RT-Thread Setting
----组件
--------设备驱动程序
------------使用 SPI 总线/设备驱动程序

配置结果如下图所示

open-spi

添加 SPI 驱动源码

下载驱动源码

上节中只是打开了 SPI 的驱动框架,具体芯片的 SPI 驱动源码还需要自己手动添加到工程驱动文件所在的路径。本例中使用的是 stm32l475-atk-pandora 开发板,所以需要下载 STM32 系列的 SPI 驱动。Github 下载地址Gitee 下载地址

添加 SPI 驱动

将下载的 SPI 驱动源码 drv_spi.cdrv_spi.h 文件添加到自己工程驱动文件所在的路径,例如 F:\work\IDE\spi-project\drivers (如果不放在驱动文件所在的路径,需要自己手动添加头文件的路劲)。并刷新工程,可以看到 SPI 驱动源码已经添加到工程中,如下图所示

spi-source

初始化引脚和时钟

drv_spi.c 文件中只是配置了 SPI 的工作方式和传输函数,具体 SPI 外设的时钟和引脚的初始化需要借助 CubeMx 生成的代码。

例如 stm32l475-atk-pandora 开发板的 SPI3 外设连接了一个 LCD 屏幕,所以需要将 CubeMx 生成的 SPI3 的初始化代码复制到工程中并参与编译(建议放在 drv_spi.c 文件中),如下所示

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(hspi->Instance == SPI3)
    {
        /* USER CODE BEGIN SPI3_MspInit 0 */

        /* USER CODE END SPI3_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_SPI3_CLK_ENABLE();

        __HAL_RCC_GPIOC_CLK_ENABLE();
        __HAL_RCC_GPIOB_CLK_ENABLE();
        /**SPI3 GPIO Configuration
        PC11     ------> SPI3_MISO
        PB3 (JTDO-TRACESWO)     ------> SPI3_SCK
        PB5     ------> SPI3_MOSI
        */
        GPIO_InitStruct.Pin = GPIO_PIN_11;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

        GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_5;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

        /* USER CODE BEGIN SPI3_MspInit 1 */

        /* USER CODE END SPI3_MspInit 1 */
    }
}

注册 SPI 总线设备

SPI 驱动和初始化等函数添加到工程中之后就可以调用 SPI 注册函数 rt_hw_spi_bus_register 来注册 SPI 总线设备了。该函数的原型如下

rt_err_t rt_hw_spi_bus_register(SPI_TypeDef *spi_num, char *bus_name)

函数的各个参数含义

参数 描述
spi_num SPI 外设基地址
bus_name SPI 总线设备注册到系统中的名字

示例开发板的 SPI 总线注册函数如下

int rt_hw_spi_init(void)
{
    rt_hw_spi_bus_register(SPI3, "spi3");
}
INIT_BOARD_EXPORT(rt_hw_spi_init);

如果需要注册更多的 SPI 总线设备,只需要调用 rt_hw_spi_bus_register 函数进行注册即可。

编译并下载程序输入 list_device 测试命令可以看到 SPI 总线设备已经成功注册到系统中了,如下图所示

list_device

注意事项

  • 当前使用 RT-Thread Studio 开发的 SPI 驱动尚未支持 DMA。

  • SPI 驱动需要在 stm32xxxx_hal_config.h 文件中开启 SPI 支持。即取消如下宏的注释

#define HAL_SPI_MODULE_ENABLED
  • 这里只是注册了一个 SPI 总线设备,SPI 从设备的挂载参考 挂载 SPI 设备

更多关于 SPI 的使用请参考 SPI 总线设备

Question && Feedback