1, 概述
串行外设接口(Serial Peripheral Interface Bus, SPI)是一种用于短程通信的同步串行通信接口规范,装置之间使用全双工模式通信,是一个主机和一个或多个从机的主从模式。SPI 使用 4 根线完成全双工的通信,这 4 根信号线分别是:CS(片选)、SCLK(时钟)、MOSI(主机输出从机输入)、MISO(主机输入从机输出)。
2, API参考
2.1 重要枚举、结构体介绍
2.1.1 SPI CLK枚举
enum HAL_SPI_MOD_CLK_SEL_T {
HAL_SPI_MOD_CLK_SEL_NONE,
HAL_SPI_MOD_CLK_SEL_OSC,
HAL_SPI_MOD_CLK_SEL_OSC_X2,
HAL_SPI_MOD_CLK_SEL_PLL,
};
2.1.2 SPI CTRL寄存器结构体
struct HAL_SPI_CTRL_T {
uint32_t sspcr0_tx;
uint32_t sspcr0_rx;
uint16_t sspcr1;
uint16_t sspcpsr;
uint16_t sspdmacr;
uint16_t ssprxcr_tx;
uint16_t ssprxcr_rx;
enum HAL_SPI_MOD_CLK_SEL_T clk_sel;
};
2.1.3 SPI配置结构体
struct HAL_SPI_CFG_T {
uint32_t rate;
bool clk_delay_half :1;
bool clk_polarity :1;
bool slave :1;
bool dma_rx :1;
bool dma_tx :1;
bool rx_sep_line :1;
uint8_t cs;
uint8_t tx_bits;
uint8_t rx_bits;
uint8_t rx_frame_bits;
};
2.1.4 SPI DMA模式枚举
enum SPI_RX_DMA_MODE_T {
SPI_RX_DMA_MODE_NORMAL,
SPI_RX_DMA_MODE_PINGPANG,
SPI_RX_DMA_MODE_STREAM,
};
2.1.5 SPI DMA回调函数指针
typedef void (*HAL_SPI_DMA_HANDLER_T)(int error);
2.2 主要函数介绍
- 在介绍函数前首先看一下SPI在7种工作模式下支持的API,每组API基本内容相似,只是用不同SPI_id调用一组后缀带_id的函数,因此接下来将在SPI模式下对API进行介绍
除上表中的API外,还有三个SPI通用API:寄存器初始化、睡眠、唤醒,这三个API所有SPI工作模式下都能使用
2.2.1 SPI CTRL寄存器初始化
函数原型:
int hal_spi_init_ctrl(const struct HAL_SPI_CFG_T *cfg, struct HAL_SPI_CTRL_T *ctrl);
函数功能:初始化SPI的CTRL寄存器
- 函数参数:
- *cfg:SPI配置
- *crtl:寄存器配置
返回值:
函数原型:
void hal_spi_sleep(void);
-
2.2.3 SPI唤醒
函数原型:
void hal_spi_wakeup(void);
-
2.2.4 SPI开启
函数原型:
int hal_spi_open(const struct HAL_SPI_CFG_T *cfg);
函数功能:开启SPI
- 函数参数:
- *cfg:SPI配置
返回值:
函数原型:
int hal_spi_close(uint32_t cs);
函数功能:关闭SPI
- 函数参数:
- cs:需要一同关闭的片选信号
返回值:
函数原型:
int hal_spi_activate_cs(uint32_t cs);
函数功能:开启所选的SPI片选信号
- 函数参数:
- cs:需要开启的片选信号
返回值:
函数原型:
int hal_spi_busy(void);
函数功能:判断SPI是否繁忙
返回值:
函数原型:
int hal_spi_send(const void *data, uint32_t len);
函数功能:SPI发送数据
- 函数参数:
- *data:待发送数据
- len:待发送数据长度
返回值:
函数原型:
int hal_spi_recv(const void *cmd, void *data, uint32_t len);
函数功能:SPI接收数据
- 函数参数:
- *cmd:接收数据地址偏移量
- *data:待接收数据
- len:待接收数据长度
返回值:
函数原型:
int hal_spi_enable_and_send(const struct HAL_SPI_CTRL_T *ctrl, const void *data, uint32_t len);
函数功能:开启SPI并用DMA传输指定数据
- 函数参数:
- *ctrl:SPI控制寄存器配置
- *data:待发送数据
- len:待发送数据长度
返回值:
函数原型:
int hal_spi_enable_and_recv(const struct HAL_SPI_CTRL_T *ctrl, const void *cmd, void *data, uint32_t len);
函数功能:开启SPI并用DMA接收数据
- 函数参数:
- *ctrl:SPI控制寄存器配置
- *cmd:接收数据地址偏移量
- *data:待接收数据
- len:待接收数据长度
返回值:
函数原型:
void hal_spi_stop_dma_send(void);
-
2.2.13 SPI DMA停止接收
函数原型:
void hal_spi_stop_dma_recv(void);
-
3,使用教程
3.1 头文件引用
#include "hal_iomux.h" #include "hal_spi.h"
3.2 SPI初始化与开启
首先对SPI的IO口进行初始化,利用iomux头文件中的API即可
void hal_iomux_set_spi(void);
随后需要实例化HAL_SPI_CFG_T结构体
static const struct HAL_SPI_CFG_T _spi_cfg_default = { .rate = 200000, .clk_delay_half = true, .clk_polarity = true, .slave = false, .dma_rx = true, .dma_tx = true, .rx_sep_line = true, .cs = 0, .tx_bits = 32, .rx_bits = 32, .rx_frame_bits = 0, };
调用SPI开启接口
hal_spi_open(&_spi_cfg_default);
3.3 数据发送
SPI发送数据 ```c uint8_t cmd[4];
cmd[0] = 0XAA; cmd[1] = 0X55; cmd[2] = 0XAA; cmd[3] = 0X55;
hal_spi_send(cmd, sizeof(cmd)); ```