[应用相关]

基于STM32 HAL库的SPI通信原理分析与调试

[复制链接]
5126|11
手机看帖
扫描二维码
随时随地手机跟帖
xiyaoko2365|  楼主 | 2021-6-23 22:59 | 显示全部楼层 |阅读模式
一、 SPI原理分析
SPI是串行外设接口(Serial Peripheral Interface)的缩写。 Motorola 公司推出的一种同步串行接口技术,是一种高速的,同步的通信总线。四线(CS,CLK,MOSI和MISO)的SPI通信时全双工模式,三线(CS,CLK,MOMI)的SPI通信时半双工模式。省略cs虽然也是三线(当只有一个从机时,可以把从机的片选设置为有效电平,使其一致处于使能状态。这也造成可以最少使用2根线进行通信。),但是并不是完全意义上的三线。
————————————————
版权声明:本文为CSDN博主「不止冬雷和夏雪」的原创**,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wang_518/article/details/115446711

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 22:59 | 显示全部楼层
1、SPI优点
支持全双工通信、通信简单、数据传输速率块

2、缺点
没有指定的流控制,没有应答机制确认是否接收到数据,所以跟IIC总线协议比较在数据可靠性上有一定的缺陷。

3、特点
1):高速、同步、全双工、非差分、总线式
2):主从机通信模式

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:00 | 显示全部楼层
二、SPI的四种通信模式
1、CPOL
CPOL即Clock Polarity,就是时钟的极性。
通信的整个过程分为空闲时刻和通信时刻,如果SCLK在数据发送之前和之后的空闲状态是高电平,那么就是CPOL=1;如果空闲状态SCLK是低电平,那么就是 CPOL=0。

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:01 | 显示全部楼层
2、CPHA
CPHA即Clock Phase,就是时钟的相位。
同步通信的一个特点就是所有数据的变化和采样都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近变化或被采样。而一个时钟周期必定包含了一个上升沿和一个下降沿,这是周期的定义所决定的,只是这两个沿的先后并无规定。

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:01 | 显示全部楼层
又因为数据从产生的时刻到它的稳定是需要一定时间的,那么,如果主机在上升沿输出数据到MOSI上,从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据,那么另一方就必须在上升沿采样这个数据。

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:02 | 显示全部楼层
CPOL=0,表示当SCLK=0时处于空闲态,所以有效状态就是SCLK处于高电平时
CPOL=1,表示当SCLK=1时处于空闲态,所以有效状态就是SCLK处于低电平时
CPHA=0,表示数据采样是在第1个边沿,数据发送在第2个边沿
CPHA=1,表示数据采样是在第2个边沿,数据发送在第1个边沿

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:06 | 显示全部楼层
例如:
CPOL=0,CPHA=0:此时空闲态时,SCLK处于低电平,数据采样是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在上升沿,数据发送是在下降沿。
CPOL=0,CPHA=1:此时空闲态时,SCLK处于低电平,数据发送是在第1个边沿,也就是SCLK由低电平到高电平的跳变,所以数据采样是在下降沿,数据发送是在上升沿。
CPOL=1,CPHA=0:此时空闲态时,SCLK处于高电平,数据采集是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在下降沿,数据发送是在上升沿。
CPOL=1,CPHA=1:此时空闲态时,SCLK处于高电平,数据发送是在第1个边沿,也就是SCLK由高电平到低电平的跳变,所以数据采集是在上升沿,数据发送是在下降沿。

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:07 | 显示全部楼层
三、HEL 库配置
/* SPI2 init function */
void MX_SPI2_Init(void)
{

  hspi2.Instance = SPI2;
  hspi2.Init.Mode = SPI_MODE_MASTER;                          //MASTER 模式
  hspi2.Init.Direction = SPI_DIRECTION_2LINES;                //全双工
  hspi2.Init.DataSize = SPI_DATASIZE_8BIT;                    //数据大小为8bit
  hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;                  //时钟空闲状态为低电平
  hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;                      //第一个边沿采样
  hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;                       //配置spi在master下,NSS作为SPI专用IO,由MCU自动控制片选,只能1主1从
  hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
  hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;                     //数据传输模式为MSB
  hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
  hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
  hspi2.Init.CRCPolynomial = 0x0;
  hspi2.Init.NSSPMode = SPI_NSS_PULSE_ENABLE;
  hspi2.Init.NSSPolarity = SPI_NSS_POLARITY_LOW;              //用于设置NSS引脚上的高电平或者低电平作为激活电平。
  hspi2.Init.FifoThreshold = SPI_FIFO_THRESHOLD_01DATA;
  hspi2.Init.TxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.RxCRCInitializationPattern = SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN;
  hspi2.Init.MasterSSIdleness = SPI_MASTER_SS_IDLENESS_00CYCLE;
  hspi2.Init.MasterInterDataIdleness = SPI_MASTER_INTERDATA_IDLENESS_00CYCLE;
  hspi2.Init.MasterReceiverAutoSusp = SPI_MASTER_RX_AUTOSUSP_DISABLE;
  hspi2.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;
  hspi2.Init.IOSwap = SPI_IO_SWAP_DISABLE;
  if (HAL_SPI_Init(&hspi2) != HAL_OK)
  {
    Error_Handler();
  }

}

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:09 | 显示全部楼层
hspi2.Init.NSS = SPI_NSS_SOFT;//配置spi在master下,NSS作为普通IO,由用户自己写代码控制片选,可以1主多从
hspi2.Init.NSS = SPI_NSS_HARD_OUTPUT;//配置spi在master下,NSS作为SPI专用IO,由MCU自动控制片选,只能1主1从
hspi2.Init.NSS = SPI_NSS_HARD_INPUT;//仅当配置spi在slave下,作为从机片选输入

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:10 | 显示全部楼层
四、逻辑分析以设置
对应的选择要和程序设置的一样。

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:10 | 显示全部楼层
3666460d34ed2f3edb.png

使用特权

评论回复
xiyaoko2365|  楼主 | 2021-6-23 23:12 | 显示全部楼层
9637160d34f06a8686.png

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

25

主题

356

帖子

0

粉丝