SPI协议及IO模拟

SPI协议

SPI协议网上资料比较多,但是也比较乱,当初在网上搜集的错误资料导致现在比较混乱。
SPI协议资料比较正规的是:
1.SPI的规约协议英文文档,例如《摩托罗拉spi协议规范》
2.许多IC的datasheet中关于SPI协议的介绍

下图摘自《摩托罗拉spi协议规范》:

  1. CPOL和CPHA的描述和定义

    注意画线部分的描述:第一个边沿锁存(或者叫采样),第二个边沿发送,注意,发送的是之前锁存好的。
  2. 时序图
  3. 工作模式的定义

    上图《Application Note MLX90363 Getting Started Guide》中关于SPI协议的相关介绍,可以得出SPI 模式0-3的定义

总结

  • CPHA=0,第一个跳变沿采样,第二个跳变沿传送。CPHA=1,则反之。
  • CPOL=0,表示空闲为低电平,CPOL=1,则反之
  • 模式 CPOL CPHA
    0 0 0
    1 0 1
    2 1 0
    3 1 1

IO口模拟

模拟的关键点主要是对采样和发送的理解,例如以模式1为例,根据前面介绍可以得知上升沿发送,下降沿采样。
关键点:

  • 上升沿发送。需理解电平从低到高也是时间的。上升沿发送标准的是,在低电平上升至1/2高电平时进行发送,所以如果是软件模拟,必须是SCL=1后,不要有任何时延,立即拉低或拉高Data口。例图:1/2处发送
  • 下降沿采样。同理也是高电平下降至1/2除,不要有任何时延,立即读取Data口
  • 开始和结束时的设置,以Mode1为例,应该在CS有效之前拉低SCLK半个时钟,结束之后在CS无效之前拉低SCLK半个时钟。CS有效之后应延时半个时钟,CS无效之后也应延时半个时钟

代码如下

//-最小为10-
#define N_Delay    20
unsigned char SPI_Send(unsigned char Data)
{
    int i = 0;
    unsigned char RecvByte = 0;
  
    COMM_CLK_L();
    SPI_Delay(N_Delay);
    COMM_CS_L();
    SPI_Delay(N_Delay);

    for (i = 0; i < 8; i++)
    {
        //-发送-
        COMM_CLK_H();
        if ((Data & 0x80) != 0)
        {
            COMM_MOSI_H();
        }
        else
        {
            COMM_MOSI_L();
        }
        Data <<= 1;
        SPI_Delay(N_Delay);

        //-接收-
        COMM_CLK_L();
        if (COMM_MISO_Get() != 0)
        {
            RecvByte |= 0x01 << (7 - i);
        }
        SPI_Delay(N_Delay);

    }
    COMM_CLK_L();
    SPI_Delay(N_Delay);
    COMM_CS_H();
    SPI_Delay(N_Delay);
    return RecvByte;
}

产生的波形如图:

posted on 2017-01-07 11:08  樊四郎  阅读(1872)  评论(0编辑  收藏  举报

导航