SPI总线协议(2020-08-07)

目录

1. SPI简介

2. 通讯引脚

3. 通信原理

3.1 宏观原理

3.2 微观原理

4. 总线时钟的极性与相位

5. SPI拓扑图

6.协议心得

7.SPI协议软件模拟

7.1.单片机软件模拟SPI接口—加深理解SPI总线协议

7.2.93C46存储器SPI总线的工作原理


1. SPI简介

SPI,是英语Serial Peripheral interface(串行外围接口)的缩写,顾名思义就是串行外围设备接口协议。是摩托罗拉公司首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。

 

2. 通讯引脚

SPI使用3条通讯总线和1条片选线。

它们是SDI(数据输入),SDO(数据输出),SCK(时钟),CS(片选)

  • SDO (MOSI)(Master Output / Slave Input) 主设备(主机)输出 / 从设备(从机)输入。数据从主机输出到从机,主机发送数据。
  • SDI (MISO)(Master Iutput / Slave Onput) 主设备(主机)输入 / 从设备(主机)输出。数据由从机输出到主机,主机接收数据。
  • SCK:(Serial Clock)即时钟信号线,用于通讯同步。该信号由主机产生,其支持的最高通讯速率为fpclk/2,即所挂载总线速率的一半。
  • NSS(CS):(Slave Selection)即片选信号线,用于选择通讯的从设备,也可用CS表示。每个从设备都有一条独立的NSS信号线,主机通过将某个设备的NSS线置低电平来选择与之通讯的从设备。所以SPI通讯以NSS线电平置低为起始信号,以NSS线电平被拉高为停止信号。

 

3. 通信原理

SPI主从模式硬件连接如下图

 

3.1 宏观原理

SPI总线的主机和从机都有一个移位寄存器

  • 当主机向自己的移位寄存器写入数据时,数据会通过MOSI信号线进入到从机的移位寄存器;
  • 同时,从机移位寄存器里的数据,通过MISO信号线进入到主机的移位寄存器。

SPI数据的传输是在串行同步时钟信号(Serial Clock,SCK)的控制下进行的。主机的时钟发生器一方面控制主机的移位寄存器,另一方面通过从机的SCK信号线来控制从机的移位寄存器,从而保证主机与从机的数据交换是同步进行的。

这样,主机和从机就完成了一次数据交换。下面这张图,是SPI通信的简明原理图:

https://pic4.zhimg.com/80/v2-11b497be4bb392fd3d02226325f31907_hd.jpg

SPI 16位移位寄存器,每次可以传输8位和16位

串口通信都是先发低位,后发高位。

3.2 微观原理

CS:其中CS是控制芯片是否被选中的,从机的CS管脚(具体从数据手册从机的高电位或低电位)来判断是否选中,对此芯片的操作才有效,这就允许在同一总线上连接多个SPI设备成为可能。

SDI/SDO/SCLK: 通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。

这就是SCK时钟线存在的原因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过 SDO线,数据在时钟上升沿或下降沿时改变,在紧接着的下降沿或上升沿被读取(具体什么上升沿还是下降沿,由主从机CPOL设置)。完成一位数据传输,输入也使用同样原理。

这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。

要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。

这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据,也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。

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

在点对点的通信中,SPI接口不需要进行寻址操作,且为全双工通信,显得简单高效。在多个从设备的系统中,每个从设备需要独立的使能信号,硬件上比I2C系统要稍微复杂一些。

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

 

4. 总线时钟的极性与相位

SPI串行同步时钟可以设置为不同的极性(Clock Polarity ,CPOL)与相位(Clock Phase ,CPHA)。

SPI通信在SPI初始化时设置好时钟的极性和相位。

时钟的极性(CPOL)用来决定在采样时的时钟状态,当时钟极性为0(CPOL=0)时,取下降沿;当时钟极性为1(CPOL=1)时,取上升沿。

时钟的相位(CPHA)用来决定何时进行信号采样。当时钟相位为1时(CPHA=1),在SCK信号线的第二个跳变沿进行采样;当时钟相位为0时(CPHA=0),在SCK信号线的第一个跳变沿进行采样。如下图:

如下表所示的四种SPI通讯模式。

有一点需要注意的是,主机和从机需要工作在相同的模式下才能正常通讯。

 

5. SPI拓扑图

在这里插入图片描述

在SDO和SDI数据线上加上上拉电阻来保证数据传输电流。

 

6.协议心得

SPI接口时钟配置心得:

  在主设备这边配置SPI接口时钟的时候一定要弄清楚从设备的时钟要求,因为主设备这边的时钟极性和相位都是以从设备为基准的。因此在时钟极性的配置上一定要搞清楚从设备是在时钟的上升沿还是下降沿接收数据,是在时钟的下降沿还是上升沿输出数据。

       但要注意的是,由于主设备的SDO连接从设备的SDI,从设备的SDO连接主设备的SDI;从设备SDI接收的数据是主设备的SDO发送过来的,主设备SDI接收的数据是从设备SDO发送过来的,所以主设备这边SPI时钟极性的配置(即SDO的配置)跟从设备的SDI接收数据的极性是相反的,跟从设备SDO发送数据的极性是相同的。下面这段话是Sychip Wlan8100 Module Spec上说的,充分说明了时钟极性是如何配置的:

The 81xx module will always input data bits at the rising edge of the clock, and the host will always output data bits on the falling edge of the clock.

意思是:主设备在时钟的下降沿发送数据,从设备在时钟的上升沿接收数据。因此主设备这边SPI时钟极性应该配置为下降沿有效。

又如,下面这段话是摘自LCD Driver IC SSD1289:

SDI is shifted into 8-bit shift register on every rising edge of SCK in the order of data bit 7, data bit 6 …… data bit 0.

意思是:从设备SSD1289在时钟的上升沿接收数据,而且是按照从高位到地位的顺序接收数据的。因此主设备的SPI时钟极性同样应该配置为下降沿有效。

时钟极性和相位配置正确后,数据才能够被准确的发送和接收, 因此应该对照从设备的SPI接口时序或者Spec文档说明来正确配置主设备的时钟。

 

 

7.SPI协议软件模拟

7.1.单片机软件模拟SPI接口—加深理解SPI总线协议

        现以 AT89C205l单片机模拟SPI总线操作串行EEPROM 93CA6为例,如图1所示,介绍利用单片机的I/O口通过软件模拟SPI总线的实现方法。在这里,仅介绍读命令的时序和应用子程序。 

7.2.93C46存储器SPI总线的工作原理

          93CA6作为从设备,其SPI接口使用4条I/O口线:串行时钟线(SK)、输出数据线DO、输入数据线DI和高电平有效的从机选择线CS。其数据的传输格式是高位(MSB)在前,低位(LsB)在后。93C46的SPI总线接口读命令时序如图2所示。 

7.3.软件模拟SPI接口的实现方法 

          对于不带SPI串行总线接口的AT89C2051单片 机来说,可以使用软件来模拟SPI的操作,图1所示 为AT89C2051单片机与串行EEPROM 93C46的硬件 连接图,其中,P1.0模拟SPI主设备的数据输出端 SDO,P1.2模拟SPI的时钟输出端SCK,P1.3模拟 SPI的从机选择端SCS,P1.1模拟SPI的数据输入 SDI。
         上电复位后首先先将P1.2(SCK)的初始状态设置为0(空闲状态)。
         读操作:AT89C2051首先通过P1.0口发送1位起始位(1),2位操作码(10),6位被读的数据地址(A5A4A3A2A1A0),然后通过P1.1口读1位空位(0),之后再读l6位数据(高位在前)。
         写操作:AT89C2051首先通过P1.0口发送1位起始位(1),2位操作码(01),6位被写的数据地址(A5A4A3A2A1A0),之后通过P1.0口发送被写的l6位数据(高位在前),写操作之前要发送写允许命令,写之后要发送写禁止命令。
         写允许操作(WEN)):写操作首先发送1位起始位(1),2位操作码(00),6位数据(11XXXX)。              

         写禁止操作(WDS)):写操作首先发送1位起始位(1),2位操作码(00),6位数据(00XXXX)。

        下面介绍用C51模拟SPI的子程序。

/*例子1*/
//首先定义好I/O口
sbit SDO=P1^0;
sbit SDI=P1^1;
sbit SCK=P1^ 2;
sbit SCS=P1^3;
sbit ACC_7= ACC^7;
unsigned int SpiRead(unsigned char add)
{
    unsigned char i;
    unsigned int datal6;
    add&=0x3f;/*6位地址*/
    add |=0x80;/*读操作码l0*/
    SDO=1;/*发送1为起始位*/
    SCK=0;
    SCK=1;
    for(i=0;<8;i++)/*发送操作码和地址*/
    {
        if(add&0x80==1)
            SDO=1;
        else 
            SDO=0;
        SCK=0;/*从设备上升沿接收数据*/
        SCK=1;
        add<<= 1;
    }
    SCK=1;/*从设备时钟线下降沿后发送数据,空读1位数据*/
    SCK=0;
    datal6<<= 1;/*读16位数据*/
    for(i=0;<16;i++)
    {
        SCK= 1;
        _nop_();
        if(SDI==1)
            datal6|=0x01;
        SCK =0;
        datal6< < =1;
    }
    return datal6;
}
    
/*例子2*/
    #define SS      252                     //定义SS所对应的GPIO接口编号  
    #define SCLK    253                     //定义SCLK所对应的GPIO接口编号  
    #define MOSI    254                     //定义SCLK所对应的GPIO接口编号  
    #define MISO    255                     //定义MISO所对应的GPIO接口编号  
    #define OUTP    1                       //表示GPIO接口方向为输出  
    #define INP 0                           //表示GPIO接口方向为输入  
    
    /* SPI端口初始化 */  
    void spi_init()  
    {  
        set_gpio_direction(SS, OUTP);  
        set_gpio_direction(SCLK, OUTP);  
        set_gpio_direction(MOSI, OUTP);  
        set_gpio_direction(MISO, INP);  
        set_gpio_value(SCLK, 0);//CPOL=0 
        set_gpio_value(MOSI, 0);
    }  
    /*  
    从设备使能  
    enable:为1时,使能信号有效,SS低电平  
    为0时,使能信号无效,SS高电平  
    */  
    void ss_enable(int enable)  
    {  
        if (enable)  
            set_gpio_value(SS, 0);//SS低电平,从设备使能有效  
        else  
            set_gpio_value(SS, 1);//SS高电平,从设备使能无效  
    }  
    
    /* SPI字节写 */  
    void spi_write_byte(unsigned char b)  
    {  
        int i;  
        for (i=7; i>=0; i--) {  
            set_gpio_value(SCLK, 0);  
            set_gpio_value(MOSI, b&(1<<i));//从高位7到低位0进行串行写入  
            delay();//延时  
            set_gpio_value(SCLK, 1);// CPHA=1,在时钟的第一个跳变沿采样  
            delay();      
        }  
    }  
    /* SPI字节读 */  
    unsigned char spi_read_byte()  
    {  
        int i;  
        unsigned char r = 0;  
        for (i=0; i<8; i++) {  
            set_gpio_value(SCLK, 0);  
            delay();//延时  
            set_gpio_value(SCLK, 1);// CPHA=1,在时钟的第一个跳变沿采样  
            r = (r <<1) | get_gpio_value(MISO);//从高位7到低位0进行串行读出  
            delay();  
        }  
    }  
    /*  
        SPI写操作  
        buf:写缓冲区  
        len:写入字节的长度  
    */  
    void spi_write (unsigned char* buf, int len)  
    {  
        int i;  
        spi_init();//初始化GPIO接口  
        ss_enable(1);//从设备使能有效,通信开始  
        delay();//延时  
        //写入数据  
        for (i=0; i<len; i++)
            spi_write_byte(buf[i]);
        delay();
        ss_enable(0);//从设备使能无效,通信结束  
    }  
    /*  
    SPI读操作  
    buf:读缓冲区  
    len:读入字节的长度  
    */  
    void spi_read(unsigned char* buf, int len)  
    {  
        int i;  
        spi_init();//初始化GPIO接口  
        ss_enable(1);//从设备使能有效,通信开始  
        delay();//延时  
        //读入数据
        for (i=0; i<len; i++)
            buf[i] = spi_read_byte();
        delay();
        ss_enable(0);//从设备使能无效,通信结束  
    }

  对于不同的串行接口外围芯片,它们的时钟时序是不同的。上述子程序是针对在SCK的上升沿输入(接收)数据和在下降沿输出(发送)数据的器件。这些子程序也适用于在串行时钟)的上升沿输入和下降沿输出的其它各种串行外围接口芯片,只要在程序中改变P1.2(SCK)的输出电平顺序进行相应调整即可。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: SPI总线协议是一种串行外设接口协议,用于在微控制器和外部设备之间进行通信。SPI是Serial Peripheral Interface的缩写,它提供了简单、高效的数据传输方式,常用于连接各种外围芯片,例如传感器、存储器、显示屏等。 要下载SPI总线协议的PDF文档,可以按照以下步骤进行操作: 首先,在互联网上搜索“SPI总线协议PDF下载”。在搜索结果中,可能会得到多个相关的网站和资源链接。 其次,根据搜索结果中提供的链接,点击进入一个可信的网站,以获取SPI总线协议的PDF下载页面。 进入下载页面后,一般会有详细的相关信息和说明。例如,该文档的名称、版本、作者、文件大小等。请务必仔细阅读网站上提供的信息,以确保下载的文件与您所需要的版本和要求相符。 通常,在下载页面上会提供一个下载按钮或链接。点击该按钮或链接,即可开始下载SPI总线协议的PDF文件。 下载完成后,打开下载的PDF文件,您就可以查看和学习SPI总线协议的相关内容了。 总之,通过互联网搜索并进入可信的网站,按照指示下载SPI总线协议的PDF文档,即可获取所需的资料。请注意确保下载的文件来源可靠,并进行合法和合理的使用。 ### 回答2: 关于SPI总线协议的PDF下载可以通过以下步骤进行: 1. 首先,在互联网浏览器中打开搜索引擎,如Google、百度等。 2. 在搜索引擎的搜索框中输入“SPI总线协议PDF下载”等相关关键词。 3. 点击搜索按钮进行搜索。 4. 在搜索结果页面中,可以找到各种相关的网站和资源链接。 5. 根据搜索结果,选择可靠、权威的网站或资源链接,如官方文档或知名技术论坛等。 6. 点击相关的链接,进入到所选择的网站页面。 7. 在网站页面中,寻找与SPI总线协议相关的文档或下载资源。 8. 如果有提供PDF文件下载的选项,点击相应链接。 9. 根据网站要求,可能需要填写一些相关信息或进行注册登录等操作。 10. 完成后,即可开始下载SPI总线协议的PDF文件。 11. 下载完成后,可以在计算机中使用PDF阅读软件打开并阅读。 值得注意的是,下载文件时应注意文件的来源和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值