码迷,mamicode.com
首页 > 其他好文 > 详细

嵌入式驱动开发之spi---spi串口通信调试

时间:2015-03-17 14:08:54      阅读:3892      评论:0      收藏:0      [点我收藏+]

标签:

一. 概念

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 驱动开发

嵌入式驱动开发之spi---spi串口通信调试

标签:

原文地址:http://www.cnblogs.com/pengkunfan/p/4344115.html

(1)
(2)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!