两个STM32之间进行SPI通信

370 阅读2分钟

\

spi

SPI是串行外设接口(Serial Peripheral Interface)的缩写,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,四根线分别为SS 、SCK、MOSI、MISO

1)SS ( Slave Select):片选信号线,

2)SCK (Serial Clock):时钟信号线,

3)MOSI (MasterOutput, Slave Input):主设备输出 / 从设备输入引脚。

4)miso主设备输入/ 从设备输出引脚。

实现方式

采用双向通信模式,主机mosi—从机的mosi 主机从机配置一致。从机的片选引脚要设置成浮空输入。主机片选引脚设置成推挽输出。

特别说明

在做主从机通信的时候,除了通信线之外,一定保持两个设备共地,否则会导致收到的数据不正常。

代码

主机配置

void MB90092_CS_Configuration(void)

{ GPIO_InitTypeDef MB90092_CS_GPIO_InitStructure;

/* GPIOC Periph clock enable */

RCC_APB2PeriphClockCmd(MB90092_GPIO_CLK, ENABLE);

/* Configure PC1 in output pushpull mode */

MB90092_CS_GPIO_InitStructure.GPIO_Pin = MB90092_CS_OUT;

MB90092_CS_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

MB90092_CS_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出

GPIO_Init(MB90092_GPIO, &MB90092_CS_GPIO_InitStructure);

}

void MB90092_CS(u8 sw)

{

if(sw == MB90092_CS_ENABLE)

GPIO_WriteBit(MB90092_GPIO, MB90092_CS_OUT , Bit_RESET);

else

GPIO_WriteBit(MB90092_GPIO, MB90092_CS_OUT,Bit_SET);

}

/**************************************************************/

void RCC_MB90092_SPI_Configuration(void)

{

RCC_APB2PeriphClockCmd(MB90092_GPIO_CLK |RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(MB90092_CLK,ENABLE);

}

void GPIO_MB90092_SPI_Configuration(void)

{ GPIO_InitTypeDef MB90092_GPIO_InitStructure;

/* Configure SPIy pins: SCK and MOSI ---------------------------------*/

MB90092_GPIO_InitStructure.GPIO_Pin = MB90092_SCK_SPI_SCK |MB90092_SIN_SPI_MOSI ;

MB90092_GPIO_InitStructure.GPIO_Speed =GPIO_Speed_2MHz;

MB90092_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(MB90092_GPIO, &MB90092_GPIO_InitStructure);

// MB90092_GPIO_InitStructure.GPIO_Pin = MB90092_SIN_SPI1_MISO;

// MB90092_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

// GPIO_Init(MB90092_GPIO, &MB90092_GPIO_InitStructure);

}

void MB90092_SPI_Configuration(void)

{ SPI_InitTypeDef MB90092_SPI_InitStructure;

SPI_Cmd(MB90092_SPI, DISABLE); //必须先禁能,才能改变MODE

//MB90092_SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;SPI_Direction_1Line_Tx //单线双向模式:只发模式,8bit

MB90092_SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;

     MB90092_SPI_InitStructure.SPI_Mode= SPI_Mode_Master;

MB90092_SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

MB90092_SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;//数据在clk的下降沿锁定

MB90092_SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

MB90092_SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

MB90092_SPI_InitStructure.SPI_BaudRatePrescaler =SPI_BaudRatePrescaler_256;

MB90092_SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;

MB90092_SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(MB90092_SPI,&MB90092_SPI_InitStructure);

//使能

SPI_Cmd(MB90092_SPI, ENABLE);

}

//初始化与MB90092、Encode相连接的SPI口

void MB90092_SPI_Initialize(void)

{

MB90092_CS_Configuration(); //片选管脚配置

RCC_MB90092_SPI_Configuration(); //系统时钟配置函数

GPIO_MB90092_SPI_Configuration(); //GPIO配置函数

MB90092_SPI_Configuration(); //SPI配置函数

}

从机配置

void SPI _Init(void)

{ SPI_InitTypeDef SPI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

/*Enable SPI1 and GPIO clocks */

/*!< SPI_FLASH_SPI_CS_GPIO, SPI_FLASH_SPI_MOSI_GPIO,

  SPI_FLASH_SPI_MISO_GPIO, SPI_FLASH_SPI_DETECT_GPIO

  and SPI_FLASH_SPI_SCK_GPIO Periph clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD,ENABLE);

/*!< SPI_FLASH_SPI Periph clock enable */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

/*!< Configure SPI_FLASH_SPI pins: SCK */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*!< Configure SPI_FLASH_SPI pins: MISO */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*!< Configure SPI_FLASH_SPI pins: MOSI */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*!< Configure SPI_FLASH_SPI_CS_PIN pin: SPI_FLASH Card CS pin */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/*Deselect the FLASH: Chip Select high */

// SPI_FLASH_CS_HIGH();

/*SPI1 configuration */

//W25X16: data input on the DIO pin is sampled on the rising edge of the CLK.

//Data on the DO and DIO pins are clocked out on the falling edge of CLK.

//SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Rx;

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;

//SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_LSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1, &SPI_InitStructure);

/*Enable SPI1 */

SPI_Cmd(SPI1, ENABLE);

}