找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2349|回复: 0
收起左侧

STM32 SPI总线介绍

[复制链接]
ID:327671 发表于 2019-11-24 20:30 | 显示全部楼层 |阅读模式
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 擦除 读写均必须以扇区为最小的单位进行操作  

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表