SPI总线 速度比IIC快
SCK信号时钟线
MOSI为主输出从输入
MISO为主输入从输出
SS片选信号线(也称NSS、CS),每个信号单独使用一根
SPI协议中没有设备地址,SS信号为低时选中设别,SS信号为高时作为结束信号。
数据传输分为高位先行和低位先行
CPOL及CPHA的不同状态,SPI分为四种模式,主机与从机需要工作在相同的模式下才可以正常通讯,实际中采用较多的是“模式0”与“模式3”.
SPI模式 CPOL CPHA 空闲时SCK时钟 采样时刻
0 0 0 低电平 奇数边沿
1 0 1 低电平 偶数边沿
2 1 0 高电平 奇数边沿
3 1 1 高电平 偶数边沿
STM32 的SPI外设可用作通讯的主机及从机,支持最高的SCK时钟频率为Fpclk/2(STM32F10X型号的默认Fpclk1为72M,Fpclk2为36M),完全支持SPI的四种模式,数据帧长度可设置为8为或16位,可设置数据MSB先行或者LSB先行,支持全双工、双线单行及单线模式。
STM32 SPI初始化结构体
typedef struct
{
uint16_t SPI_Direction; /*设置SPI的单双向模式 */
{SPI_Direction_2Lines_FullDuplex //双线全双工
SPI_Direction_2Lines_RxOnly //双线只接收
SPI_Direction_1Line_Rx //单线只接收
SPI_Direction_1Line_Tx //单线只发送
}
uint16_t SPI_Mode; /*设置SPI的主/从机端模式 */
uint16_t SPI_DataSize; /*设置SPI的数据帧长度,可选8/16位 */
uint16_t SPI_CPOL; /*设置时钟极性CPOL,可选高/低电平 */
uint16_t SPI_CPHA; /*设置时钟相位,可选奇/偶边沿采样 */
uint16_t SPI_NSS; /*设置NSS引脚由SPI硬件控制还是软件控制*/
uint16_t SPI_BaudRatePrescaler; /*设置时钟分频因子,fpclk/分频数 = fsck */
uint16_t SPI_FirstBit; /*设置MSB/LSB先行 */
uint16_t SPI_CRCPolynomial; /*设置CRC校验的表达式 */
}SPI_InitTypeDef;
void SPI_FLASH_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
//SPI SCK
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Pin = SPI_SCK_GPIO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_SCK_GPIO_Port, &GPIO_InitStruct);
//SPI MOSI
GPIO_InitStruct.GPIO_Pin = SPI_MOSI_GPIO_PIN;
GPIO_Init(SPI_MOSI_GPIO_Port, &GPIO_InitStruct);
//SPI MISO
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = SPI_MISO_GPIO_PIN;
GPIO_Init(SPI_MISO_GPIO_Port, &GPIO_InitStruct);
//SPI SS
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Pin = SPI_SS_GPIO_PIN;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SPI_SS_GPIO_Port, &GPIO_InitStruct);
GPIO_SetBits( GPIOB, SPI_SS_GPIO_PIN);
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStruct.SPI_CRCPolynomial = SPI_SPEED;
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(SPI_FLASH, &SPI_InitStruct);
SPI_Cmd(SPI_FLASH, ENABLE);
}
//flash 必须先擦除才能再写入
nor flash 除擦除必须以一个扇区完成外,其余均可以字节为单位操作
nand flash 擦除 读写均必须以扇区为最小的单位进行操作
|