• 数字ic设计——SPI


    SPI总线概念 

            SPI ( Serial Peripheral Interface,串行外围设备接口)是一种同步、全双工、主从式,高速接口(UART是异步)。

            来自主机或 从机 的数据在时钟上升沿或下降沿同步。主机和从机可以同时传输数据。

     串行外设接口(SPI)应用:

            串行外设接口(SPI)是微控制器和外围IC(如传感器、ADC、DAC、移位寄存器、SRAM等)之间使用最广泛的接口之一。 

    SPI总线具有以下特点:

    1. 连线较少,简化电路设计。并行总线扩展方法通常需要8根数据线、8~16根地址线、2~3根控制线。而这种设计,仅需4根数据和控制线即可完成并行扩展所实现的功能。
    2. 器件统一编址,并与系统地址无关,操作SPI独立性好。
    3. 器件操作遵循统一的规范,使系统软硬件具有良好的通用性。

    SPI总线的系统构架

            SPI是一个环形总线结构由SS(CS)、SCK、MOSI、MISO构成,主要是在SCK的控制下,两个双向移位寄存器进行数据交换。 

    SPI信号:

    • 时钟((Serial Clock,SCK)SPI CLK,SCLK):产生时钟信号的器件称为主机。
    • 片选信号(外围设备片选信号线(Slave Selection,SS)CS): 从机使能信号,由主机控制。。来自主机的片选信号用于选择从机。(这通常是一个低电平有效信号,拉高时从机与SPI总线断开连接。当使用多个从机时,主机需要为每个从机提供单独的片选信号。)
    • 主机输出、从机输入((Master Out Slave In,MOSI)MOSI):数据线,将数据从主机发送到从机。
    • 主机输入、从机输出((Master In Slave Out,MISO)MISO):数据线,将数据从从机发送到主机。

    主机和从机之间的关系:

    • 主机和从机之间传输的数据与主机产生的时钟同步。
    • SPI接口只能有一个主机,但可以有一个或多个从机。

    SPI数据传输 

             SPI数据的传输是在串行同步时钟信号(Serial Clock,SCK)的控制下进行的。

    SPI怎么保证同步:

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

    SPI开始通信

            主机发送时钟信号。

            主机通过使能片选信号CS(低电平有效选择从机。

     SPI通信期间   

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

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

             同时

            从机移位寄存器里的数据,通过MISO信号线进入到主机的移位寄存器。

            这样,主机和从机就完成了一次数据交换。

    ⚠注意:

             SPI是全双工接口,主机和从机可以分别通过MOSI和MISO线路同时发送数据。【数据的发送(串行移出到MOSI/SDO总线上)和接收(采样或读入总线(MISO/SDI)上的数据)同时进行。】

           串行时钟沿  同步  数据的移位和采样。

           SPI接口允许用户灵活选择时钟的上升沿或下降沿来采样和/或移位数据。

    四种SPI模式

    时钟相位(CPHA)和时钟极性(CPOL)

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

    ❤ 时钟的极性(CPOL)

        用来决定在总线空闲时,同步时钟(SCK)信号线上的电位是高电平还是低电平。

    • 当时钟极性为0时(CPOL=0),SCK信号线在空闲时低电平
    • 当时钟极性为1时(CPOL=1),SCK信号线在空闲时高电平

          🗡   空闲状态:

                    传输开始时CS为高电平且在向低电平转变的期间,

                    传输结束时CS为低电平且在向高电平转变的期间。 

    ❤ 时钟的相位(CPHA)

         读取数据和发送数据的时钟沿(上升沿还是下降沿)。     

    ⭐ CPHA=1(在SCK信号线的第二个跳变沿进行采样 )

    •  当时钟极性为0(CPOL=0),取下降沿
    •  当时钟极性为1(CPOL=1),取上升沿

    ⭐ CPHA=0(在SCK信号线的第一个跳变沿进行采样)

    • 当时钟极性为0(CPOL=0),取上升沿
    • 当时钟极性为1(CPOL=1),取下降沿

     四种SPI模式

            主机必须根据从机的要求选择时钟极性和时钟相位。

            根据CPOL和CPHA位的选择,有四种SPI模式可用。 

    SPI模式CPOLCPHA空闲状态下时钟极性用于采样和/或移动数据的时钟相位
    00 0逻辑低电平上升沿采样,下降沿移出
    101逻辑低电平

    下降沿采样,上升沿移出

    210逻辑高电平下降沿采样,上升沿移出
    311逻辑高电平 下降沿采样,上升沿移出

    Mode0:CPOL= 0,CPHA = 0在SCK信号线的第一个跳变沿进行采样 )

            CPOL =0 :

                    时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)

            CPHA =0:

                    在第一个时钟沿(上升沿)采样数据,

                    在第二个时钟沿(下降沿)输出数据。

    MODE0的传输时序:

     Mode1:CPOL = 0,CPHA = 1在SCK信号线的第二个跳变沿进行采样 )

             CPOL =0 :

                    时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)

            CPHA =1:

                    在第二个时钟沿(上升沿)采样数据,

                    在第一个时钟沿(下降沿)输出数据。

    MODE1的传输时序:

     Mode2:CPOL= 1,CPHA = 0在SCK信号线的第一个跳变沿进行采样 )

             CPOL =1:

                    时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)

            CPHA =0:

                    在第一个时钟沿(上升沿)采样数据,

                    在第二个时钟沿(下降沿)输出数据。

    MODE2的传输时序:

      Mode3:CPOL = 1,CPHA = 1在SCK信号线的第二个跳变沿进行采样 )

             CPOL =1:

                    时钟在数据传输前和完成后都保持高电平(时钟空闲电平为高电平)

            CPHA =1:

                    在第二个时钟沿(上升沿)采样数据,

                    在第一个时钟沿(下降沿)输出数据。

    MODE3的传输时序:

    SPI时序

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

    ※时钟极性和时钟相位两种选择: 

    •  CPHA = 0CPOL = 1 
    •  CPHA = 1CPOL = 0 

    ※根据片选信号CS选择从机 

    ※SPI时序 

    主机和从机初始化就绪

            主机寄存器=0xaa=10101010

            从机寄存器=0x55 =01010101

    第一个上升沿来的时候

             MOSI=1;主机寄存器=0101010x

             MISO=0;从机寄存器=1010101x

    第一个下降沿到来的时候

            MOSI传递到从机寄存器中,从机寄存器=0101010MOSI=01010101

            MISO传递到主机寄存器中,主机寄存器=0101010MISO=01010100

    8个时钟脉冲以后,两个寄存器的内容互相交换一次。

            主机寄存器=01010101

            从机寄存器=10101010 

    这样就完成里一个SPI时序。

    根据以上分析,一个完整的传送周期是16位,即两个字节。

    解释:

            主机先发送命令过去,然后从机根据主机的名准备数据,

            主机在下一个8位时钟周期才把数据读回来  

    脉冲主机寄存器master buffer从机slave bufferMISOMOSI
    0101010100101010100
    第1个脉冲上升沿(发送)0101010x1010101x01
    第1个脉冲下降沿(接收)010101001010101101
    第2个脉冲上升沿(发送)1010100x0101011x10
    第2个脉冲下降沿(接收)101010010101011010
    第3个脉冲上升沿(发送)0101001x1010110x01
    第3个脉冲下降沿(接收)010100101010110101
    第4个脉冲上升沿(发送)1010010x0101101x10
    第4个脉冲下降沿(接收)101001010101101010
    第5个脉冲上升沿(发送)0100101x1011010x01
    第5个脉冲下降沿(接收)010010101011010101
    第6个脉冲上升沿(发送)1001010x0110101x10
    第6个脉冲下降沿(接收)100101010110101010
    第7个脉冲上升沿(发送)0010101x1101010x01
    第7个脉冲下降沿(接收)001010101101010101
    第8个脉冲上升沿(发送)0101010x1010101x10
    第8个脉冲下降沿(接收)010101011010101010

    SPI功能模块的设计

    SPI的主、从设备内部均为一个8位的移位寄存器。

    实际实现时,可以利用主机的Sclk信号作为移位时钟信号,按照高位在前,低位在后的顺序,依次将总线上的数据送入内部移位寄存器中,从而完成SPI的接收与发送。
     

    design spec

    1. SCLK采用10MHz
    2.模块工作时钟100MHz
    3.当接收到的串行数据做串并转换,将并行数据反馈给上一级模块

    4、采用 CPOL = 0 ,CPHA = 1

            CPOL =0 :

                    时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平)

            CPHA =1:

                    在第一个时钟沿(上升沿)采样数据,

                    在第二个时钟沿(下降沿)输出数据。

     SPI的SCLK信号的生成

    模块时钟CLK,频率F=100MHz , 时钟周期 =10ns

    SCLK,            频率f=10MHz   ,  时钟周期 =100ns (10分频)

    1. //模块时钟:clk
    2. //spi时钟:sclk
    3. //复位信号:rst_n
    4. //计数时钟个数的计数器:clk_cnt
    5. //CPOL =0 (时钟在数据传输前和完成后都保持低电平(时钟空闲电平为低电平))
    6. always@(posedge clk or negedge rst_n)
    7. begin
    8. if(!rst_n)
    9. clk_cnt<=0;
    10. sclk<=0;
    11. else
    12. begin
    13. //(10分频/2-1)
    14. if(clk_cnt==4'd4)
    15. begin
    16. sclk<=~sclk;
    17. clk_cnt<=0;
    18. end
    19. else
    20. begin
    21. clk_cnt<=clk_cnt+1;
    22. end
    23. end

    master同时的采样和输出

    1. //master发送数据
    2. always@(negedge sclk or negedge rst_n)
    3. begin
    4. if(!rst_n)
    5. mosi<=1'b1;
    6. else if(spi_done)
    7. mosi<=1'b1;
    8. else(!sclk&&!cs)
    9. begin
    10. mosi<=master_buf[7];
    11. end
    12. end
    13. //master接收数据
    14. always@(negedge sclk or negedge rst_n)
    15. begin
    16. if(!rst_n)
    17. master_buf[7:0]<=8'b0;
    18. else if(spi_done)
    19. master_buf[7:0]<=8'b0;
    20. else(!sclk&&!cs)
    21. begin
    22. master_buf[7:0]<={master_buf[6:0],miso};
    23. end
    24. end

    slave同时的采样和输出

    1. //slave发送数据
    2. always@(negedge sclk or negedge rst_n)
    3. begin
    4. if(!rst_n)
    5. miso<=slave_buf[0];
    6. else if(spi_done)
    7. miso<=slave_buf[0];
    8. else(!sclk&&!cs)
    9. begin
    10. miso<=slave_buf[7];
    11. end
    12. end
    13. //slave接收数据
    14. always@(negedge sclk or negedge rst_n)
    15. begin
    16. if(!rst_n)
    17. slave_buf[7:0]<=8'b0;
    18. else if(spi_done)
    19. slave_buf[7:0]<=8'b0;
    20. else(!sclk&&!cs)
    21. begin
    22. slave_buf[7:0]<={slave_buf[6:0],mosi};
    23. end
    24. end


    参考: 

    SPI接口简介 - 模拟/电源 - -EETOP-创芯网

    【新提醒】SPI总线协议 - 霡霂的日志 - EETOP 创芯网论坛 (原名:电子顶级开发网) -

    怎样理解SPI总线时钟的极性(COL)与相位(CPHA)? - 知乎 (zhihu.com)

  • 相关阅读:
    码住!双11支付宝小程序云云市集,享骨折优惠最强购物清单,抽奖赢iPhone 15 Pro!
    JavaScript中this关键字实践
    工程机械流通行业BI经营分析框架(一)四大关注方向
    今日睡眠质量记录79
    ios手动符号表解析
    在qt的设计师界面没有QVTKOpenGLWidget这个类,只有QOpenGLWidget,那么我们如何得到QVTKOpenGLWidget呢?
    上传文件sftp和base 64上传的优缺点?
    NPM install 中:-save 、 -save-dev 和 没有--save的区别
    SpringCloud常用组件
    Failed to process, please exclude the tableName or statementId.
  • 原文地址:https://blog.csdn.net/weixin_41788560/article/details/125459584