当前位置:   article > 正文

05-STM32F1 - 串行通信3-SPI(1),SPI配置_stm32spi从机的配置

stm32spi从机的配置

05-STM32F1 - 串行通信3-SPI(1),SPI配置

  • STM-SPI作为主机,从机

  • SPI的时钟,最高为Pclk/2,SPI1最高为36Mhz,SPI2最高为18Mhz。

  • SPI的四种模式 CPOL CPHA,数据帧8~16位,LSB,MSB

  • 全双工,双向单线,单线

物理层

在这里插入图片描述

接口标准

序号名称说明
1NSS片选线,低电平有效
2SCK时钟信号线
3MOSI主设备输出,从设备输入
4MISO主设备输入,从设备输出

协议层

起始信号和停止信号

NSS 信号线由高变低,是SPI 通讯的起始信号。NSS 是每个从机各自独占的信号线,当从机在自己的NSS 线检测到起始信号后,就知道自己被主机选中了,开始准备与主机通讯。在图中的标号处,NSS 信号由低变高,是SPI 通讯的停止信号,表示本次通讯结束,从机的选中状态被取消。

CPOL/CPOH

时钟极性CPOL:SPI 通讯设备处于空闲状态时,SCK 信号线的电平信号(即SPI 通讯开始前,NSS 线为高电平时SCK 的状态)。CPOL=0 时,SCK 在空闲状态时为低电平,CPOL=1 时,SCK 在空闲状态时为高电平。

时钟相位CPHA:数据的采样的时刻。当CPHA=0 时,MOSI 或MISO 数据线上的信号将会在SCK 时钟线的“奇数边沿”被采样。当CPHA=1 时,数据线在SCK 的“偶数边沿”采样。

SPI模式CPOLCPHA空闲时SCK时钟采样时刻
000低电平奇数边沿
101低电平偶数边沿
210高电平奇数边沿
311高电平偶数边沿

在这里插入图片描述

在这里插入图片描述

SPI基本结构

在这里插入图片描述

SPI框架主要分为通讯引脚、时钟控制逻辑、数据控制逻辑、整体控制逻辑。

  • 通讯引脚

    NSS可以使用软件控制,其他引脚使用硬件SPI控制

  • 时钟控制逻辑

    时钟控制:波特率发生器:BR[2:0],控制SPI的时钟。CR1寄存器

  • 数据控制逻辑

    SPI的MOSI及MISO都连接到数据移位寄存器上,数据移位寄存器的数据来源于接收缓冲区及发送缓冲区。

  • 整体控制逻辑

    通过写SPI的数据寄存器DR把数据填充到发送缓冲区中。

    通过读SPI的数据寄存器DR,可以获取到接收缓冲区中的内容。

    其中数据帧长度通过DFF为配置成8位及16位。

    模式:配置LSBFIRST位,可选择MSB先行还是LSB先行。

SPI初始化结构体

typedef struct
{
  uint16_t SPI_Direction;           
  uint16_t SPI_Mode;                
  uint16_t SPI_DataSize;           
  uint16_t SPI_CPOL;                
  uint16_t SPI_CPHA;               
  uint16_t SPI_NSS;                                
  uint16_t SPI_BaudRatePrescaler;  
  uint16_t SPI_FirstBit;          
  uint16_t SPI_CRCPolynomial;       
}SPI_InitTypeDef;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

编程要点

在这里插入图片描述

SPI硬件相关宏定义,bsp_spi.h

#ifndef __bsp_spi_h
#define __bsp_spi_h

#include "stm32f10x.h"

#define BSP_SPIx_GPIO_Clk                       RCC_APB2Periph_GPIOA
#define BSP_SPIx_GPIO_Clk_Cmd                   RCC_APB2PeriphClockCmd

#define BSP_SPIx_GPIO_NSS_Port                  GPIOA
#define BSP_SPIx_GPIO_NSS_Pin                   GPIO_Pin_4

#define BSP_SPIx_GPIO_SCK_Port                  GPIOA
#define BSP_SPIx_GPIO_SCK_Pin                   GPIO_Pin_5

#define BSP_SPIx_GPIO_MOSI_Port                 GPIOA
#define BSP_SPIx_GPIO_MOSI_Pin                  GPIO_Pin_7

#define BSP_SPIx_GPIO_MISO_Port                 GPIOA
#define BSP_SPIx_GPIO_MISO_Pin                  GPIO_Pin_6

#define BSP_SPIx_Clk                            RCC_APB2Periph_SPI1
#define BSP_SPIx_Clk_Cmd                        RCC_APB2PeriphClockCmd

#define BSP_SPIx                                SPI1

void BSP_SPI_Init(void);


#endif /* __bsp_spi_h */


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

SPI模块配置,bsp_spi.c

static void BSP_SPI_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    BSP_SPIx_GPIO_Clk_Cmd(BSP_SPIx_GPIO_Clk,ENABLE);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = BSP_SPIx_GPIO_NSS_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BSP_SPIx_GPIO_NSS_Port,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = BSP_SPIx_GPIO_SCK_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BSP_SPIx_GPIO_SCK_Port,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Pin = BSP_SPIx_GPIO_MOSI_Pin;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(BSP_SPIx_GPIO_MOSI_Port,&GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Pin = BSP_SPIx_GPIO_MISO_Pin;
    GPIO_Init(BSP_SPIx_GPIO_MISO_Port,&GPIO_InitStructure);
    BSP_SPIx_GPIO_NSS_Port->BSRR |= BSP_SPIx_GPIO_NSS_Pin;// pull up NSS
}

static void BSP_SPI_Config(void)
{
    SPI_InitTypeDef SPI_InitStructure;
    BSP_SPIx_Clk_Cmd(BSP_SPIx_Clk,ENABLE);
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
    SPI_InitStructure.SPI_CRCPolynomial = 0;
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
    SPI_Init(BSP_SPIx,&SPI_InitStructure);
    SPI_Cmd(BSP_SPIx,ENABLE);
}


void BSP_SPI_Init(void)
{
    BSP_SPI_GPIO_Config();
    BSP_SPI_Config();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

本人能力有限,如果你有好的想法,还望不吝赐教!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50872
推荐阅读
相关标签
  

闽ICP备14008679号