嵌入式驱动开发之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主模式发送:
- //先写数据到发送寄存器
- CB0TXL = *gpCsib0TxAddress; /* start by writing data to CB0TX */
- //在发送中断里再次发送
- __interrupt void MD_INTCB0T(void)
- {
- if (gCsib0TxCnt > 0)
- {
- ......
- /* Transfer data length is 8 bit */
- CB0TXL = *gpCsib0TxAddress; /* writing data to CB0TX */
- gpCsib0TxAddress++;
- gCsib0TxCnt--;
- }
- }
- else
- {
- CSIB0_SendEndCallback(); /* send complete */
- }
- }
在往发送寄存器里写数据时,控制器会提供时钟,发送完成后就不再提供时钟了。
SPI主模式接收:
- //先从接收寄存器里读取一个dummy
- volatile USHORT dummy = 0;
- dummy = CB0RX; /* dummy read to start receive */
- //在接收中断里再次接收
- __interrupt void MD_INTCB0R(void)
- {
- ......
- *gpCsib0RxAddress = CB0RXL;
- gpCsib0RxAddress ++;
- gCsib0RxCnt ++;
- ......
- }
SPI主模式即发送也接收:
- //先写数据到发送寄存器
- CB0TXL = *gpCsib0TxAddress; /* start by writing data to CB0TX */
- //在接收中断里接收
- __interrupt void MD_INTCB0R(void)
- {
- ......
- /* Transfer data length is 8 bit */
- *gpCsib0RxAddress = CB0RXL;
- gpCsib0RxAddress ++;
- gCsib0RxCnt ++;
- ......
- }
- //在发送中断里发送
- __interrupt void MD_INTCB0T(void)
- {
- ......
- /* Transfer data length is 8 bit */
- CB0TXL = *gpCsib0TxAddress; /* writing data to CB0TX */
- gpCsib0TxAddress++;
- gCsib0TxCnt--;
- ......
- }
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