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);}