STM32 SPI读写W25Q64(一)

接口/总线/驱动

1138人已加入

描述

SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议。

SPI的通信原理很简单,它以主从方式工作,这种模式通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以(单线传输时)。也是所有基于SPI的设备共有的,它们是SDI(数据输入)、SDO(数据输出)、SCLK(时钟)、CS(片选)。

(1)SDI – SerialData In,串行数据输入;

(2)SDO – SerialDataOut,串行数据输出;

(3)SCLK – Serial Clock,时钟信号,由主设备产生;

(4)CS – Chip Select,从设备使能信号,由主设备控制。

其中,CS是从芯片是否被主芯片选中的控制信号,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),主芯片对此从芯片的操作才有效。这就使在同一条总线上连接多个SPI设备成为可能。

接下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCLK时钟线存在的原因,由SCLK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取。完成一位数据传输,输入也使用同样原理。因此,至少需要8次时钟信号的改变(上沿和下沿为一次),才能完成8位数据的传输。

SCLK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCLK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。

也就是说,主设备通过对SCLK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。

最后,SPI接口的一个缺点:没有指定的流控制,没有应答机制确认是否接收到数据。

了解完SPI的四条线,现在开始配置GPIO端口的初始化。

//F_CS:PB14       输出
//SPI1_SCK:PB3    输出
//SPI1_MISO:PB4   输入
//SPI1_MOSI:PB5   输出 
void Spi1_Init()  
{
  //1. 开端口时钟
  RCC- >AHB1ENR  |= 1< < 1;
  //2. 端口模式设置(0入1出2复用3模拟)
    //pb4:输入
  GPIOB- >MODER  &= ~(0X3< < 8);
    //pb14/pb3/5:输出
  GPIOB- >MODER  &= ~(0X3< < 6 | 0X3< < 10 | 0X3< < 28);
  GPIOB- >MODER  |= 1< < 6 | 1< < 10 | 1< < 28;
  //3. 输出类型:推挽
  GPIOB- >OTYPER &= ~(1< < 3 | 1< < 5 | 1< < 14);
  //4. 输出速度:50M
  GPIOB- >OSPEEDR  &= ~(0X3< < 6 | 0X3< < 10 | 0X3< < 28);
  GPIOB- >OSPEEDR  |= 2< < 6 | 2< < 10 | 2< < 28;
  //5. 上下拉
  GPIOB- >PUPDR  &= ~(0X3F< < 6 | 0X3< < 28);  //无上下拉
  //6. 引脚的初始电平
    //F_CS:高
  F_CS_H();
    //SPI1_SCK:低(模式0)、高(模式3)
  SPI1_SCK_L();
    //SPI1_MISO:高低均可,由内置上拉决定
    //SPI1_MOSI:高低均可
  SPI1_MOSI_L();
}

IIC只有一条数据线,需要通过时序确定起始、停止、发送、接收。相对于IIC来说,SPI协议可以通过两条数据线直接发送接收数据,不用发送起始和停止信号,通信方式更加简单。

GPIO

SPI协议的时序其实很简单,主要是在SCK的控制下,两个双向移位寄存器进行数据交换。

上升沿发送、下降沿接收、高位先发送。

上升沿到来的时候,sdo上的电平将被发送到从设备的寄存器中。

下降沿到来的时候,sdi上的电平将被接收到主设备的寄存器中。

SPI协议收发数据

//spi收发
//发数据,高位在前
u8 Spi1_RevSendByte(u8 dat)
{
  u8 i = 0;

  for(i=0;i< 8;i++)
  {
    //1.SCL拉低
    SPI1_SCK_L();
    if(dat & 0x80)
      SPI1_MOSI_H();
    else
      SPI1_MOSI_L();
    //2. scl拉高,接收数据
    dat < <= 1;
    SPI1_SCK_H();
    if(GPIOB- >IDR  &  (1< < 4))
      dat  |= 1;
  }
  return dat;
}

至此,SPI协议就编写完成了。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分