和菜鸟一起学linux总线驱动之初识spi总线协议

       还记得第一次用spi设备的时候是大三暑假了,那时和队友一起买了无线模块,然后用单片机来无线传输,不过代码都不是自己写的,虽然实现了这个功能,但是当时还不知道什么spi的。大四了,学弟问我怎么用spi flash,顿感惭愧。后来他送我了一块flash,然后我用51参考网上的实现了下,才知道有这么个东西。之后公司里也渐渐用了些spi的设备,flashcodecads7843等,渐渐地也熟悉了这个东东。

       其实,总线协议只是为了减少io口,人为定义的。我们也可以定义协议,只要按照这个时序来就可以了。

       SPIserial peripheral interface),就是串行外围设备接口。她是一种高速的,全双工,同步的通信总线,只有四根线。菜鸟嘛,高速应该好理解的,就是传输速率比较快,而对于什么全双工啊,同步啊的可能没什么概念。网上有举几个例子的,全双工是指在发送数据的同时也能够接收数据,两者同步进行,这好像我们平时打电话一样,说话的同时也能够听到对方的声音。半双工,所谓半双工就是指一个时间段内只有一个动作发生,举个简单例子,一条窄窄的马路,同时只能有一辆车通过,当目前有两辆车对开,这种情况下就只能一辆先过,等到头儿后另一辆再开。单工通信是指通信线路上的数据按单一方向传送,就像传呼机一样。同步传输是指通信双方有共同的时钟参考,能够通过时钟参考准确收发数据,通常这个时钟参考是同步时钟线或同一个时钟源。异步传输是指通信双方没有共同的时钟参考,通常每次收发数据时都需要有前导码进行速率同步。计算机的并口就是同步的,而RS-232串口和USB等就是异步的。

       SPI是一个环形总线结构,由ss(cs)scksdisdo四根线组成,就是在sck的控制下,两个移位寄存器进行数据交换。

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

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

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

        假设主机和从机初始化就绪:并且主机的 sbuff=0xaa (10101010),从机的 sbuff=0x55 (01010101),下面将分步对spi8个时钟周期的数据情况演示一遍(假设上升沿发送数据)

---------------------------------------------------

脉冲           主机 sbuff    从机sbuff      sdi     sdo

---------------------------------------------------

0     00-0      10101010      01010101       0       0

---------------------------------------------------

1     0--1      0101010x      10101011       0       1

1     1--0      01010100      10101011       0       1

---------------------------------------------------

2     0--1      1010100x      01010110       1       0

2     1--0      10101001      01010110       1       0

---------------------------------------------------

3     0--1      0101001x      10101101       0       1

3     1--0      01010010      10101101       0       1

---------------------------------------------------

4     0--1      1010010x      01011010       1       0

4     1--0      10100101      01011010       1       0

---------------------------------------------------

5     0--1      0100101x      10110101       0       1

5     1--0      01001010      10110101       0       1

---------------------------------------------------

6     0--1      1001010x      01101010       1       0

6     1--0      10010101      01101010       1       0

---------------------------------------------------

7     0--1      0010101x      11010101       0       1

7     1--0      00101010      11010101       0       1

---------------------------------------------------

8     0--1      0101010x      10101010       1       0

8     1--0      01010101      10101010       1       0

---------------------------------------------------

        这样就完成了两个寄存器8位的交换,上面的0--1表示上升沿、1--0表示下降沿,sdi sdo相对于主机而言的。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的名准备数据,主机在下一个8位时钟周期才把数据读回来。

       SPI总线是摩托罗拉公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟SCK,一条数据输入线MOSImaster output slave input ),一条数据输出MISOmaster input slave output)。SPI的主要特点有:可以同时发出和接收串行数据;可以当做主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。

       SPI总线有四种工作方式(SPI0SPI1SPI2SPI3),一般我们用到的是SPI0SPI3的方式。

       SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL)对传输协议没有重大的影响,如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA)能够用于选择两种不同的传输协议之一进行数据传输。如果CPHA=0,在串行同步的第一个跳变沿(上升或下降)数据被采样,如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。

       下面看一下网上有的图:

 

       由上图很清晰明了地知道了CPOL分别为01的时候的时钟和CPHA分别为0,1时候的采样时间的区别了。

       不过一般来说都是用模式0的,我用的这些都是模式0的。

 

       就是上图这个时序了,当片选spi设备后,开始有数据在传输,一个时钟采样一个,就以这个传输数据了,总得来说还是挺简单的。

       还是看看SPI内部的结构图吧

 

        切记主机的输出是从机的输入,主机的输入是从机的输出。像串口一样的交叉连接。

        OK,对于SPI的协议就记录下这些了,用于以后的驱动的实现也够用了。

原文地址:https://www.cnblogs.com/wuyida/p/6300061.html