SPI
物理层 1》SPI通信是摩托罗拉公司研发通信 2》SPI需要四线串?同步通信, 分别是MCLK(同步时钟线), MOSI(主机输出从机输? 线), MISO(主机输?从机输出线), NSS(?选信号线)。 3》SPI是?低位先?可选择的,8bit和16bit数据位可选择的通信?式 4》SPI的通信速率在stm32中可达18MHZ 5》SPI通信是?种全双?的通信?式 6》SPI可实现单主机多从机的通信?式 7》 MSB(?位先?),LSB(低位先?) 协议层 4种?作模式 CPOL:时钟极性,?于确定空闲时,时钟线的状态 CPHA:时钟相位,?于确定数据的采样和输出在哪?个时钟边沿(采样不变,输出允许发 ?改变) MODE CPOL CPHA 0 0 0 时钟线空闲时为低电平,在时钟线前沿采样,在时钟线的后沿输 出 1 0 1 时钟线空闲时为低电平,在时钟线前沿输出,在时钟线的后沿采 样 2 1 0 时钟线空闲时为?电平,在时钟线前沿采样,在时钟线的后沿输出 3 1 1 时钟线空闲时为?电平,在时钟线前沿输出,在时钟线的后沿采 样 // 读取W25Qxx的制造商和设备ID 1》打开时钟----GPIOA,SPI1,AFIO 2》初始化GPIOA –GPIO_Pin_4 –通?推挽输出 –输出速度–50M –GPIO_Pin_5|6|7 –复?推挽输出 –输出速度–50M 3》SPI初始化 –双线全双? –主机 –数据位数8bit –时钟悬空? –数据捕获于第?个时钟边沿 –?选引脚由软件控制 –波特率预分频器–4分频 –?位先?MSB –CRC校验–7 4》SPI使能
#include "spi.h"
#define CS_HI GPIO_SetBits(GPIOA, GPIO_Pin_4)
#define CS_LO GPIO_ResetBits(GPIOA, GPIO_Pin_4)
void SPI_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1,ENABLE);
GPIOA GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft;
SPI_Init(SPI1,&SPI_InitStruct);
}
uint8_t SPI_SendRxData(uint8_t txdata)
{
while(SET != SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE));
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_FLAG_TXE);
SPI_I2S_SendData(SPI1,txdata);
while(SET != SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE));
SPI_I2S_ClearITPendingBit(SPI1,SPI_I2S_FLAG_RXNE);
return SPI_I2S_ReceiveData(SPI1);
}
uint16_t SPI_W25QXX_ID(void)
{
uint16_t read_data = 0;
CS_LO;
SPI_SendRxData(0x90);
SPI_SendRxData(0x00);
SPI_SendRxData(0x00);
SPI_SendRxData(0x00);
read_data = SPI_SendRxData(0x11);
read_data = read_data<<8;
read_data |= SPI_SendRxData(0x11);
CS_HI;
return read_data;
}
|