全称Serial Peripheral Interface,是一种全双工,同步通信
共四条线:MOSI、MISO、SCK、NSS
信号线 | 作用 |
---|---|
MOSI | 主机输出,从机输入 |
MISO | 主机输入,从机输出 |
SCK | 时钟信号,由主机产生,用于通讯同步 |
NSS | 从机使能信号,由主机控制(片选线) |
通讯起始:NSS线信号由高变低,对应的从机被选中,开始通讯
通讯结束:NSS线信号由低变高,对应的从机取消选中状态
四种模式的区别:总线空闲时sck的时钟状态(CPOL)及数据采样时刻(CPHA)。
CPOL:SPI通讯设备处于空闲时(NSS为高电平时)SCK的状态。CPOL=0,则SCK线在空闲时为低电平;CPOL=1,则SCK线在空闲时为高电平
CPHA:数据采样的时刻。CPHA=0,MOSI或MISO线上的信号将在SCK线的奇数个跳变沿被采样;CPHA=1,MOSI或MISO线上的信号在SCK线的偶数个个跳变沿被采样。
注:四种模式都可以使用,但是主从设备必须采用同一种模式。
STM32中SPI个数从3到6个不等,支持Motorola和TI协议。STM32还支持I2S功能。
Mode | 含义 |
---|---|
Full-Duplex Master | 全双工主模式 |
Full-Duplex Slave | 全双工从模式 |
Half-Duplex Master | 半双工主模式 |
Half-Duplex Slave | 半双工从模式 |
Receive Only Master | 仅接收主模式 |
Receive Only Slave | 仅接收从模式 |
Transmit Only Master | 仅发送主模式 |
参数 | 含义 |
---|---|
Frame Format | 框架格式,有Motorola和TI两种 |
Data Size | 数据长度,8bit和16bit两种 |
First Bit | 对齐形式,高位先行和低位先行 |
Prescaler | 预分频,用于控制波特率,波特率=16MHz/Prescaler |
Clock Polarity | CPOL,前面有讲 |
Clock Phase | CPHA,前面有讲 |
CRC Calculation | 是否启用CRC |
NSS Signal Type | 片选形式,硬件实现还是软件实现 |
HAL库关于CAN的所有函数定义和结构体分别在 Drivers/STM32F4xx_HAL_Driver 文件夹下 stm32f4xx_HAL_Driver.c 和 stm32f4xx_HAL_Driver.h 中
下面列举一些基本的和常用的
只有SPI_InitTypeDef和SPI_HandleTypeDef,分别用于初始化定义和句柄定义。如果配合CubeMx,这两个都用不上
SPI关于IO的定义在stm32f4xx_HAL_Driver.c文件中701-2563行
函数 | 功能 |
---|---|
HAL_SPI_Transmit | 发送数据 |
HAL_SPI_Receive | 接收数据 |
HAL_SPI_TransmitReceive | 全双工,接收和发送数据 |
HAL_SPI_Transmit_IT | 发送成功中断 |
HAL_SPI_Receive_IT | 接收成功中断 |
HAL_SPI_TransmitReceive_IT | 发送接收成功中断 |
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
功能:发送一段数据
参数:spi句柄指针 发送数据数组名
发送数组长度
timeout,超出这个时间就报错,单位是ms
返回值:返回值:HAL状态
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
功能:接收一段数据
参数:spi句柄指针 接收数据数组名
接收数组长度
timeout,超出这个时间就报错,单位是ms
返回值:返回值:HAL状态
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout)
功能:接收并发送一段数据
参数:spi句柄指针 发送数据数组名
接收数据数组名
接收发送数组长度
timeout,超出这个时间就报错,单位是ms
返回值:返回值:HAL状态
SPI 的编程较CAN来说方便了很多,配合Cubemx的话就不需要做初始化配置了。
然而由于实际使用过程中所使用的STM可能作为上位机也可能作为下位机,也就是主机和从机。作为从机,相当于一个部门的下属,只需要管输入输出就完事了,不需要操心片选的事。作为主机就需要协调各从机了,相当于一个部门的主管,需要给下级授意,它改接收任务或者给主机汇报
CS(片选信号)有硬件片选和软件片选两种形式。硬件片选是单片机在收发消息时自动进行了片选线拉低并抬高的步骤,软件片选则需要在每次收发前将片选线拉低,通讯结束再将片选线拉高。
硬件片选是硬件已经封装好了通讯时序和片选信号开始终止,所以只需要调用上述的IO类函数即可
软件片选稍微麻烦一点。需要另外分一个单片机引脚给CS信号,GPIO输出功能,最好配置为上拉。
当需要和某从机通信时,需要给它发送片选命令,即手动将片选线的高电平置低。例如下面这个给从机的发送过程:
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_RESET) //将片选线置低,告诉从机开始通信
HAL_SPI_Tramsmit(&hspix, (uint8_t*)data, len, timeout) //发送一个数据
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, GPIO_PIN_SET) //将片选线重新置高,告诉从机结束通信
再次强调,通讯过程一定要在片选线为低电平时才有效!!!