程序小白
认证:优质创作者
所在专题目录 查看专题
RT-Thread驱动之路:stm32设备驱动开发之uart操作方法③
RT-Thread驱动之路:stm32设备驱动开发之uart中断处理④
RT-Thread驱动之路:stm32设备驱动开发之浅析注册机制⑤
RT-Thread驱动之路:stm32设备驱动开发之SPI原理①
RT-Thread驱动之路:stm32设备驱动开发之SPI对象创建②
RT-Thread驱动之路:stm32设备驱动开发之SPI总线操作方法③
作者动态 更多
RT-Thread Studio:硬件移植篇①
1天前
RT-Thread驱动之路:stm32设备驱动开发之HWTIMER开发①
1星期前
RT-Thread驱动之路:stm32设备驱动开发之SPI总线操作方法③
2星期前
RT-Thread驱动之路:stm32设备驱动开发之SPI对象创建②
2星期前
电子元器件那些事儿:三极管工作区的判断如此简单①
3星期前

RT-Thread驱动之路:stm32设备驱动开发之SPI对象创建②


开篇分割线,再研究驱动程序之前我们先看下RTT 关于SPI应用的代码层级结构:

      应用层:只做应用层开发的小伙伴是有福的,你不需要了解整个驱动是怎样构架的,只需要了解驱动构架层提供的API接口函数直接调用,即可操作SPI设备。 

      设备驱动框架层:由RTT系统提供的一个重要的中间层,用于驱动层和应用层之间联系的建立,对应用层开放API调用接口,对驱动层开放注册函数和操作函数,将驱动层的操作注册到系统中,实现应用与驱动之间的软连接。 

      总线设备驱动层:该层是驱动开发工程师的主攻战场,后面展开详细讲。 

      硬件SPI控制器层:一般情况下就是MCU自带的控制外设,这里当然就是SPI控制器,玩过单片机的小伙伴最熟悉的部分。 

      外挂模块层:最后一层就是SPI类型总线通信设备的模块,常用的flash芯片、网络控制模块等都生活在这一层,实际电路中通过SPI通信线与MCU连接。 

       接下来就是看下基于STM32开发SPI的设备模型(模型即结构体定义)了,代码如下:

/* stm32 spi dirver class */
struct stm32_spi
{
    SPI_HandleTypeDef handle;
    struct stm32_spi_config *config;
    struct rt_spi_configuration *cfg;

    struct
    {
        DMA_HandleTypeDef handle_rx;
        DMA_HandleTypeDef handle_tx;
    } dma;

    rt_uint8_t spi_dma_flag;
    struct rt_spi_bus spi_bus;
};

      这里需要注意的是,模型的最后一个成员spi_bus,它是由RTT系统提供,有了它这个模型就与系统之间产生了联系,spi_bus是系统的一个SPI类型硬件设备模型。  有了模型以后,我们就是针对这个模型进行设备的实例化,一般来讲MCU会有多个SPI控制器,所以针对这一情况,我们就定义了另一个模型专门用于实例化SPI对象模型:

struct stm32_spi_config
{
    SPI_TypeDef *Instance;  /*SPI外设*/
    char *bus_name;         /*SPI总线设备名称*/
    struct dma_config *dma_rx, *dma_tx; /*DMA发送及接收配置参数*/
};

      接下来需要采用预处理命令宏定义硬件外设所有的SPI设备配置项,至于是否开启我们可以通过rt_config.h文件是否定义该宏来决定:

#ifdef BSP_USING_SPI1
#ifndef SPI1_BUS_CONFIG
#define SPI1_BUS_CONFIG                             \
    {                                               \
        .Instance = SPI1,                           \
        .bus_name = "spi1",                         \
    }
#endif /* SPI1_BUS_CONFIG */
#endif /* BSP_USING_SPI1 */

#ifdef BSP_USING_SPI2
#ifndef SPI2_BUS_CONFIG
#define SPI2_BUS_CONFIG                             \
    {                                               \
        .Instance = SPI2,                           \
        .bus_name = "spi2",                         \
    }
#endif /* SPI2_BUS_CONFIG */
#endif /* BSP_USING_SPI2 */

      有了设备配置模型,就需要定义一个真实的需要配置的设备模型数据,用于实例化多个SPI控制器,实际上就一个数组搞定:

static struct stm32_spi_config spi_config[] =
{
#ifdef BSP_USING_SPI1
    SPI1_BUS_CONFIG,
#endif

#ifdef BSP_USING_SPI2
    SPI2_BUS_CONFIG,
#endif
};

      有了设备类型模型,也有了配置模型数组,就需要定义通过模型来定义真实的设备实例,定义完并没有进行初始化:

/*定义SPI总线对象*/
static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};

      到这里,关于SPI总线对象的创建就完了,但是关于SPI总线对象还是一个空空如也的数组,我想你也应该知道如何基于配置对象给总线对象进行初始化,当然这个我们下篇接着讲。

声明:本内容为作者独立观点,不代表电子星球立场。未经允许不得转载。授权事宜与稿件投诉,请联系:editor@netbroad.com
觉得内容不错的朋友,别忘了一键三连哦!
赞 3
收藏 4
关注 138
成为作者 赚取收益
全部留言
0/200
成为第一个和作者交流的人吧