<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
1、SPI总线速度:
波特率可以高达5Mbps,具体速度大小取决于SPI硬件。
例如,Xicor公司的SPI串行器件传输速度能达到5MHz;
ATMEL的AT45DB021B,20 MHz Max Clock Frequency;
LPC2214的SPI,最大数据位速率为输入时钟速率的1/8。
2、SPI简介:
同步外设接口(SPI)是由摩托罗拉公司开发的全双工同步串行总线,该总线大量用在与EEPROM、ADC、FLASH和显示驱动器之类的慢速外设器件通信。
SPI(Serial Peripheral Interface)是一种串行同步通讯协议,由一个主设备和一个或多个从设备组成,主设备启动一个与从设备的同步通讯,从而完成数据的交换。通讯时,数据由MOSI 输出,MISO 输入,数据在时钟的上升或下降沿由MOSI 输出,在紧接着的下降或上升沿由MISO 读入,这样经过8/16 次时钟的改变,完成8/16 位数据的传输。
====在一次数据传输过程中,接口上只能有一个主机和一个从机能够通信。并且,主机总是向从机发送一个字节数据,而从机也总是向主机发送一个字节数据。
该总线通信基于主-从配置。它有4个信号:
MOSI:主出/从入
MISO:主入/从出
SCK:串行时钟
SS:从属选择 。即CS(从使能信号),CS 决定了唯一的与主设备通信的从设备,如 没有CS 信号,则只能存在一个从设备,主设备通过产生移位时钟来发起通讯。
在SPI传输中,数据是同步进行发送和接收的。数据传输的时钟基于来自主处理器的时钟脉冲,摩托罗拉没有定义任何通用SPI的时钟规范。然而,最常用的时钟设置基于时钟极性(CPOL)和时钟相位(CPHA)两个参数,CPOL定义SPI串行时钟的活动状态,而CPHA定义相对于SO-数据位的时钟相位。CPOL和CPHA的设置决定了数据取样的时钟.
3、例子:
LPC2214有两个SPI接口。
SPI 从机选择信号是一个低有效信号,用于指示被选择参与数据传输
的从机。每个从机都有各自特定的从机选择输入信号。在数据处理之前,SSEL
必须为低电平并在整个处理过程中保持低电平。如果在数据传输中SSEL 信号变
为高电平,传输将被中止。这种情况下,从机返回到空闲状态并将任何接收到
的数据丢弃。对于这样的异常没有其它的指示。该信号不直接由主机驱动。可
通过软件使用一个通用I/O 口来驱动。
注:配置为SPI 主机的LPC2114/2124/2212/2214 必须选择一个合适的管脚用作
SSEL 功能并使其保持高电平,只有这样,器件才能真正执行主机的功能。
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
例程:XFT-8001部分SPI软体;
/*----定义SPI相关控制器的控制位(SPCR)----*/
#define MSTR BIT5 /*-----主模式控制---- #define BIT5 0x00000020 */
#define CPOL BIT4 /*-----时钟极性控制---- #define BIT4 0x00000010 */
#define CPHA BIT3 /*-----时钟相位控制----*/
#define LSBF BIT6 /*-----移位方向控制----*/
#define SCK P0_4 /*------串行时钟-------*/
#define MISO P0_5 /*------主入从出-------*/
#define MOSI P0_6 /*------主出从入------*/
#define SSEL_AD P0_16 /*----从机选择SPI脚---*/
#define FLASH_CS P0_19
void SpiInit(uint8 x)
{
switch(x)
{
case FLASHSPI: //按照flash的要求初始化SPI
S0SPCCR = 0x00000036; //约400KHz的时钟频率 S0SPCCR=Fpclk/SPI频率
S0SPCR = MSTR; //主控制器,模式选择0
break;
case SDSPI: //按照SD卡的要求初始化SPI
S0SPCCR = 0x0000000E;
S0SPCR = MSTR;
break;
case HC595SPI: //按照595的要求初始化SPI
break;
}
}
/***********************************************************************
** 函数名称: SpiSendData()
** 功能描述: 用SPI总线发送数据,由于SPI的特点,SPI在发送数据的时候,也在接收数据;如果仅仅要求接收数据,也要发送数据,不然没有SCK时钟
** 输 入: x:SPI将要发送的数据
** 输 出: 返回接收的数据
** 全局变量: 无
** 调用模块: 无
** 日 期: <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />2006年11月12日
************************************/
uint8 SpiSendData(uint8 x)
{ S0SPDR = x;
while((S0SPSR&0x80)==0);
return S0SPDR;
}
/*************************
** 函数名称: EraseFlashBlock()
** 功能描述: 擦除单个block的数据, 可以擦除器件中的任何一个指定编号的block块,完成擦除之后要读取状态位来判断是否擦除完毕
** 在片选信号CS的上升沿开始擦除
** 输 入: addr:要擦除的块编号,对于AT45DB021B而言,范围从0~127
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 日 期: 2007年5月12日
****************************************************************/
void EraseFlashBlock(uint8 addr)
{ uint16 temp;
uint8 temp1,temp2;
temp = (addr<<4);
temp1=(temp>>8)&0x00FF;
temp2=temp&0x00FF;
SpiSendData(0x50); // 0x50 是AT45DB021B的Block Erase命令。
SpiSendData(temp1); // 给出块的Address Byte。
SpiSendData(temp2);
SpiSendData(0x00);
}
/******************************************************************************
** 函数名称: EraseFlashPage()
** 功能描述: 擦除单个page快的数据, 可以擦除器件中的任何一个指定编号的page块,完成擦除之后要读取状态位来判断是否擦除完毕
** 在片选信号CS的上升沿开始擦除
** 输 入: addr:要擦除的page编号,对于AT45DB021B而言,范围从0~1023
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
***************/
void EraseFlashPage(uint16 addr)
{
uint16 temp;
uint8 temp1,temp2;
temp = (addr<<1);
temp1=(temp>>8)&0x00FF;
temp2=temp&0x00FF;
SpiSendData(0x81); // 0x81 是AT45DB021B的Page Erase命令。
SpiSendData(temp1); // 给出page的Address Byte。
SpiSendData(temp2);
SpiSendData(0x00);
}
/*************************************************************************
** 函数名称: PreReadPage()
** 功能描述: 读取某一页的任何数据,本函数并不从page中读数据,后面跟上SpiSendData函数读数据
** 输 入: page_addr,page_addr是指定的页地址
** byte_addr,byte_addr指定的字节地址
** 输 出: 无
**
** 全局变量: 无
** 调用模块: 无
************************************************/
void PreReadPage(uint16 page_addr,uint16 byte_addr)
{
uint32 temp;
uint8 temp1,temp2,temp3;
temp=byte_addr+page_addr<<9;
temp1=(temp>>16)&0x000000FF;
temp2=(temp>>8)&0x000000FF;
temp3=temp&0x000000FF;
SpiSendData(0xD2); //0xD2 是AT45DB021B的Main Memory Page Read命令。
SpiSendData(temp1); // 给出page的Address Byte。
SpiSendData(temp2);
SpiSendData(temp3);
SpiSendData(0x00); //
SpiSendData(0x00);
SpiSendData(0x00);
SpiSendData(0x00);
}
/**************************************************************************
** 函数名称: ReadFlashState()
** 功能描述: 读取Flash的状态,在对flash进行包含buffer的操作,擦除操作等要检查flash的状态
** 输 入: 无
** 输 出: state:返回Flash的状态
**
** 全局变量: 无
** 调用模块: 无
**********************/
uint8 ReadFlashState(void)
{
uint8 state="0";
SpiSendData(0xD7); // 0xD7 是AT45DB021B的Status Register Read 命令。
state=SpiSendData(0x00);
return state;
}
用户1366686 2012-6-26 22:19
用户78399 2007-3-1 21:17
手持式消费产品的用s3c2410等
工业用飞利浦
用户68661 2007-3-1 18:53
三星的,呵呵