zoukankan      html  css  js  c++  java
  • 嵌入式驱动开发之spi---spi串口通信调试

    一. 概念

    SPI是 Serial Peripheral Interface(串型外部接口)的缩写。SPI接口有4根PIN脚,分别是:
              * SPICLK     : 用于传输数据的同步时钟
              * SPIMISO    : 用于主模式下的输入,或从模式下的输出信号线
              * SPIMOSI    : 用于主模式下的输出,或从模式下的输入信号线
              * PSS        : 用于从设备的片选信号,低有效

       SPI 通信两端各自扮演主设备(Master)和从设备(Slave)的角色。主设备在移位寄存器进行传输时(SPIMISO/SPIMOSI上面有信号时),提供SPICLK时钟作为对方同步和采样的依据,同时在传输的过程中,PSS要一直被Master拉底。传输完成,PSS拉高,SPICLK信号消失。具体传输时序,请浏览后续的“传输时序”章节。

       SPI接口有点类似于UART接口,他们通常都用于满足一些低速传输的需求,比如通信量小的控制数据传输/或者接入一些低速的输入设备(鼠标/键盘/触摸屏)等等。他们之间的主要区别如下:
            * SPI靠SPICLK作为传输同步信号,因此它走的是串性同步传输信号。
            * UART是通用异步串性传输信号的缩写,他的PIN定义中没有时钟信号,通信两端靠约定好的波特率,以及数据格式中的开始位/停止位/校验位来构造和解析数据。
            因为UART是异步传输,所以他还有RTX/CTS之类的PIN脚用于数据码流控制,现在大部分的UART控制器都支持硬件流控,这样就简化了这种老式数据传输方式的软件设计复杂度。

    1. 通常SPI通信要求4根线,分别是MOSI(mast output salve input), MISO, CLK, CS。

    2. 当发送和接受数据的工作都准备好了,只要有时钟CLK,就发送数据,没有时钟就不发送,而且一个时钟周期发送一位(bit)数据,所以发送数据的快慢由时钟频率来控制。

    3. 至于时钟和数据的相位没有特别严格的要求(而IIC中,数据的变化只能在SCL是低电平的时候发生),SPI数据的变化是一个时钟周期一次,这样的方法来传输数据就简单多了。我们可以根据需求对时钟的极性和相位做调整,看看是在时钟上升沿还是下降沿来发送数据,还有停止发送时时钟的极性,是保持高电平还是低电平。

    4. 另外在多机通信时,SPI只是简单的通过一个片选信号来选择哪个设备占用总线,但是IIC是通过发送从设备地址来自动选择的。

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

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

    (1)SDO – 主设备数据输出,从设备数据输入

    (2)SDI – 主设备数据输入,从设备数据输出

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

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

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

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

    要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。这样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。

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

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

    AT91RM9200的SPI接口主要由4个引脚构成:SPICLK、MOSI、MISO及 /SS,其中SPICLK是整个SPI总线的公用时钟,MOSI、MISO作为主机,从机的输入输出的标志,MOSI是主机的输出,从机的输入,MISO 是主机的输入,从机的输出。/SS是从机的标志管脚,在互相通信的两个SPI总线的器件,/SS管脚的电平低的是从机,相反/SS管脚的电平高的是主机。在一个SPI通信系统中,必须有主机。SPI总线可以配置成单主单从,单主多从,互为主从。

    SPI的片选可以扩充选择16个外设,这时PCS输出=NPCS,说NPCS0~3接4-16译码器,这个译码器是需要外接4-16译码器,译码器的输入为NPCS0~3,输出用于16个外设的选择。

    一. 要点

    1. SPI有四种传输模式,上升沿、下降沿、前沿、后沿触发。当然也有MSB和LSB传输方式。

    2. SPI只有主模式和从模式之分,没有读和写的说法,因为实质上每次SPI是主从设备在交换数据。也就是说,你发一个数据必然会收到一个数据;你要收一个数据必须也要先发一个数据。

    虽然是收发共同但是一般我们会有选择的操作:

    SPI主模式发送:

    [cpp] view plaincopy
     
    1. //先写数据到发送寄存器  
    2. CB0TXL = *gpCsib0TxAddress;    /* start by writing data to CB0TX */  
    3. //在发送中断里再次发送  
    4. __interrupt void MD_INTCB0T(void)  
    5. {  
    6.     if (gCsib0TxCnt > 0)  
    7.     {  
    8.             ......  
    9.             /* Transfer data length is 8 bit */  
    10.             CB0TXL = *gpCsib0TxAddress;    /* writing data to CB0TX */  
    11.             gpCsib0TxAddress++;  
    12.             gCsib0TxCnt--;  
    13.         }  
    14.     }  
    15.     else  
    16.     {  
    17.         CSIB0_SendEndCallback();    /* send complete */  
    18.     }  
    19. }  

    在往发送寄存器里写数据时,控制器会提供时钟,发送完成后就不再提供时钟了。
    SPI主模式接收:

    [cpp] view plaincopy
     
    1. //先从接收寄存器里读取一个dummy  
    2. volatile    USHORT    dummy = 0;  
    3. dummy = CB0RX;    /* dummy read to start receive */  
    4. //在接收中断里再次接收  
    5. __interrupt void MD_INTCB0R(void)  
    6. {  
    7.     ......  
    8.     *gpCsib0RxAddress = CB0RXL;  
    9.     gpCsib0RxAddress ++;  
    10.     gCsib0RxCnt ++;  
    11.     ......  
    12. }  

    SPI主模式即发送也接收:

    [cpp] view plaincopy
     
    1. //先写数据到发送寄存器  
    2. CB0TXL = *gpCsib0TxAddress;    /* start by writing data to CB0TX */  
    3. //在接收中断里接收  
    4. __interrupt void MD_INTCB0R(void)  
    5. {  
    6.     ......  
    7.     /* Transfer data length is 8 bit */  
    8.     *gpCsib0RxAddress = CB0RXL;  
    9.     gpCsib0RxAddress ++;  
    10.     gCsib0RxCnt ++;  
    11.     ......  
    12. }  
    13. //在发送中断里发送  
    14. __interrupt void MD_INTCB0T(void)  
    15. {  
    16.     ......  
    17.     /* Transfer data length is 8 bit */  
    18.     CB0TXL = *gpCsib0TxAddress;    /* writing data to CB0TX */  
    19.     gpCsib0TxAddress++;  
    20.     gCsib0TxCnt--;  
    21.     ......  
    22. }  

    SPI从模式和上面操作一样,只不过不提供时钟了。

    http://blog.csdn.net/lwbeyond/article/details/8749874

    http://www.eefocus.com/ilove314/blog/11-09/231276_8ad6b.html 

    http://blog.csdn.net/jingzhesiye/article/details/8014241 spi 驱动开发

    http://blog.sina.com.cn/s/blog_4a28d94b010004rh.html spi led

    http://blog.chinaunix.net/uid-26817832-id-3172689.html spi flash

    http://www.51hei.com/bbs/dpj-25699-1.html 单片机中spi 和 i2c的区别,spi 四根线,i2c两根线

    http://blog.csdn.net/liangxiaozhang/article/details/7610502

  • 相关阅读:
    构建之法阅读笔记02
    NOPI2018 货币系统 bool完全背包 bitset优化转移
    P4551 最长异或路径 Trie经典应用 bitset应用
    算法分析与设计实验报告 Project2
    ARC-114 C- Sequence Scores 计数
    P2401 不等数列 简单计数DP
    Gym-102569C Manhattan Distance 曼哈顿距离的转换 二分
    GYM-102893J Straight 模拟 思维
    算法分析与设计实验报告 Project1
    CodeForces Round 705-D GCD of an Array 数论 乱搞 or 线段树 + 质因子分解科技
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/4344115.html
Copyright © 2011-2022 走看看