新闻  |   论坛  |   博客  |   在线研讨会
spi介绍
刘海 | 2010-07-07 12:36:06    阅读:1637   发布文章

 
查看文章
   
spi介绍
2007-09-14 11:40

SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束 中断标志;写冲突保护;总线竞争保护等。图3示出SPI总线工作的四种方式,其中使用的最为广泛的是SPI0和SPI3方式(实线表示):

?/P>

图2   SPI总线四种工作方式

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

二,.SPI功能模块的设计

根据功能定义及SPI的工作原理,将整个IP Core分为8个子模块:uC接口模块、时钟分频模块、发送数据FIFO模块、接收数据FIFO模块、状态机模块、发送数据逻辑模块、接收数据逻辑模块以及中断形式模块。

深入分析SPI的四种传输协议可以发现,根据一种协议,只要对串行同步时钟进行转换,就能得到其余的三种协议。为了简化设计规定,如果要连续传输多个数据,在两个数据传输之间插入一个串行时钟的空闲等待,这样状态机只需两种状态(空闲和工作)就能正确工作。

SPI是一个环形总线结构,由SS(CS)、SCD、SDI、SDO构成,其时序其实很简单,主要是在SCK的控制下,两个双向移位寄存器进行数据交换。

假设下面的8位寄存器装的是待发送的数据10101010,上升沿发送、下降沿接收、高位先发送。

那么第一个上升沿来的时候数据将会是SDO=1;寄存器=0101010x。下降沿到来的时候,SDI上的电平将所存到寄存器中去,那么这时寄存器=0101010SDI,这样在8个时钟脉冲以后,两个寄存器的内容互相交换一次。这样就完成里一个SPI时序。

例子:

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

脉冲

主机sbuff

从机sbuff

sdi

sdo

0

10101010

01010101

0

0

1上

0101010x

1010101x

0

1

1下

01010100

10101011

0

1

2上

1010100x

0101011x

1

0

2下

10101001

01010110

1

0

3上

0101001x

1010110x

0

1

3下

01010010

10101101

0

1

4上

1010010x

0101101x

1

0

4下

10100101

01011010

1

0

5上

0100101x

1011010x

0

1

5下

01001010

10110101

0

1

6上

1001010x

0110101x

1

0

6下

10010101

01101010

1

0

7上

0010101x

1101010x

0

1

7下

00101010

11010101

0

1

8上

0101010x

1010101x

1

0

8下

01010101

10101010

1

0

这样就完成了两个寄存器8位的交换,上面的上表示上升沿、下表示下降沿,SDI、SDO相对于主机而言的。其中SS引脚作为主机的时候,从机可以把它拉底 被动选为从机,作为从机的是时候,可以作为片选脚用。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根 据主机的名准备数据,主机在下一个8位时钟周期才把数据读回来.


 

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

SPI是Serial Peripheral Interface的简称,NDS中的触摸屏,麦克风,电源控制,固件及DS卡的EEPROM都是基于SPI的。所以弄明白SPI的原理对NDS的研究很有帮助。 CF; zaS z
W Rw `E(
SPI 是一种允许一个主设备启动一个与从设备的同步通讯的协议,从而完成数据的交换。也就是SPI是一种规定好的通讯方式。这种通信方式的优点是占用端口较少, 一般4根就够基本通讯了(不算电源线)。同时传输速度也很高。一般来说要求主设备要有SPI控制器(但可用模拟方式),就可以与基于SPI的芯片通讯了。 这种芯片也许是储存芯片,像DS卡的存档芯片,也许是控制芯片,像DS触摸屏的控制芯片等等。 L' 3 > S}
ym/k'p*HTr
SPI 的通信原理很简单,它需要至少4根线,事实上3根也可以。也是所有基于SPI的设备共有的,它们是SDI(数据输入),SDO(数据输出),SCK(时 钟),CS(片选)。其中CS是控制芯片是否被选中的,也就是说只有片选信号为预先规定的使能信号时(高电位或低电位),对此芯片的操作才有效。这就允许 在同一总线上连接多个SPI设备成为可能。 w oq R,a:|
3F7Q/2Ia&W
接 下来就负责通讯的3根线了。通讯是通过数据交换完成的,这里先要知道SPI是串行通讯协议,也就是说数据是一位一位的传输的。这就是SCK时钟线存在的原 因,由SCK提供时钟脉冲,SDI,SDO则基于此脉冲完成数据传输。数据输出通过SDO线,数据在时钟上沿或下沿时改变,在紧接着的下沿或上沿被读取。 完成一位数据传输,输入也使用同样原理。这样,在至少8次时钟信号的改变(上沿和下沿为一次),就可以完成8位数据的传输。 o 46: *x
Z MJ
要注意的是,SCK信号线只由主设备控制,从设备不能控制信号线。同样,在一个基于SPI的设备中,至少有一个主控设备。 P*t` ]A
_P _ OO
这 样传输的特点:这样的传输方式有一个优点,与普通的串行通讯不同,普通的串行通讯一次连续传送至少8位数据,而SPI允许数据一位一位的传送,甚至允许暂 停,因为SCK时钟线由主控设备控制,当没有时钟跳变时,从设备不采集或传送数据。也就是说,主设备通过对SCK时钟线的控制可以完成对通讯的控制。 (j zr>2)
SPI还是一个数据交换协议:因为SPI的数据输入和输出线独立,所以允许同时完成数据的输入和输出。 bQNSU-( J
)xK &!CQ$
不同的SPI设备的实现方式不尽相同,主要是数据改变和采集的时间不同,在时钟信号上沿或下沿采集有不同定义,具体请参考相关器件的文档。
下面是用单片机实现触摸屏的代码:
[功 能] 8051单片机驱动ADS7846/ADS7843芯片

#include "reg51.h"
#include "intrins.h"


sbit DCLK=P1^6; //根据用户自己的定义
sbit CS=P2^2;
sbit DIN=P2^3;
sbit DOUT=P2^4;
sbit BUSY=P2^5;

delay(unsigned char i--)
{
while(i--);
}


void start() //SPI开始
{
DCLK=0;
CS=1;
DIN=1;
DCLK=1;
CS=0;
}

WriteCharTo7843(unsigned char num) //SPI写数据
{
unsigned char count=0;
DCLK=0;
for(count=0;count<8;count++)
{
num<<=1;
DIN=CY;
DCLK=0; _nop_();_nop_();_nop_(); //上升沿有效
DCLK=1; _nop_();_nop_();_nop_();
}
}


ReadFromCharFrom7843() //SPI 读数据
{
unsigned char count=0;
unsigned int Num=0;
for(count=0;count<12;count++)
{
Num<<=1;
DCLK=1; _nop_();_nop_();_nop_(); //下降沿有效
DCLK=0; _nop_();_nop_();_nop_();
if(DOUT) Num++;
}
return(Num);
}

void ZhongDuan() interrupt 0 //外部中断0 用来接受键盘发来的数据
{
unsigned int X=0,Y=0;
delay(10000); //中断后延时以消除抖动,使得采样数据更准确
start(); //启动SPI
// while(BUSY); //如果BUSY信号不好使可以删除不用
delay(2);
WriteCharTo7843(0x90); //送控制字 10010000 即用差分方式读X坐标 详细请见有关资料
// while(BUSY); //如果BUSY信号不好使可以删除不用
delay(2);
DCLK=1; _nop_();_nop_();_nop_();_nop_();
DCLK=0; _nop_();_nop_();_nop_();_nop_();
X=ReadFromCharFrom7843(); //读X轴坐标
WriteCharTo7843(0xD0); //送控制字 11010000 即用差分方式读Y坐标 详细请见有关资料
DCLK=1; _nop_();_nop_();_nop_();_nop_();
DCLK=0; _nop_();_nop_();_nop_();_nop_();
Y=ReadFromCharFrom7843(); //读Y轴坐标
CS=1;
}


main()
{
TMOD=0x11; // 记数器0 计数器1 都以 16 位 记数
TCON=0x00;
IE=0x83; //1000 0001 EA=1中断允许,
IP=0x01;
while(1);//等待触摸中断
}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
一个没有思想的人是很可怕的!
推荐文章
最近访客