spi-spec详解
- 格式:doc
- 大小:459.00 KB
- 文档页数:9
Serial Peripheral Interface Bus
SPI 总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟
线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于CPU与各种外围器件进行全
双工、同步串行通讯。SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机
工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。
1、数据传输:
During each SPI clock cycle, a full duplex data transmission occurs:
(主
要是在sclk的控制下,两个双向移位寄存器进行数据交换。)
the master sends a bit on the MOSI line; the slave reads it from
that same line
the slave sends a bit on the MISO line; the master reads it from
that same line
2、时钟极性及相位:
In addition to setting the clock frequency, the master must also
configure the clock polarity and phase with respect to the data.
Freescale's SPI Block Guide [1] names these two options as CPOL and CPHA
respectively, and most vendors have adopted that convention.
The timing diagram is shown to the right. The timing is further
described below and applies to both the master and the slave device.
At CPOL=0 the base value of the clock is zero
o
For CPHA=0, data is captured on the clock's rising edge
(low→high transition) and data is propagated on a falling
edge (high→low clock transition).
o
For CPHA=1, data is captured on the clock's falling edge and
data is propagated on a rising edge.
At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
o
For CPHA=0, data is captured on clock's falling edge and data
is propagated on a rising edge.
o
For CPHA=1, data is captured on clock's rising edge and data
is propagated on a falling edge.
3、以MX29L12845E为例:
(1) read bytes
主机把一位数据放到MISO(主出从进)上,其实就是把相应的线拉高(1)或者拉低(0);然
后主机让SCLK(时钟)上升一次,数据将在SCLK的上升沿被slave接受;主机再把时钟拉
低,以备下次将其拉高;这样重复8次,就可以把一个byte的指令送到slave了。第一次
传指令,第二次就是传要读的地址;传完指令和地址,主机就可以一次次把时钟拉高,一位
一位地读取到slave传来的数据了。
command description
Timing analysis
伪代码:
set_line(SPI_S, low); //选中,表示要开始交互
set_line(SPI_C, low); //clock拉低,以保证待会可以“拉高”
for(i=0;i < 8; i++) { //传指令 0X03
set_line(SPI_D, BIT(command, i));
set_line(SPI_C, high); ------|
set_line(SPI_C, low);--------|
}
for(i=0;i < 24; i++) { //传3 bytes offset地址
set_line(SPI_D, BIT(addr, i));
set_line(SPI_C, high);
set_line(SPI_C, low);
}
for(i=0;i < 8; i++) { //读数据
set_line(SPI_C, high);
tmp_bit = get_line(SPI_Q);
tmp |= tmp_bit << i;
set_line(SPI_C, low);
}
.....
set_line(SPI_S, high);//把chip select拉高,交互结束
(2)write bytes
command description
Timing analysis
伪代码:
set_line(SPI_S, low); //选中,表示要开始交互
set_line(SPI_C, low); //clock拉低,以保证待会可以“拉高”
for(i=0;i < 8; i++) { //传指令 0X02
set_line(SPI_D, BIT(command, i));
set_line(SPI_C, high); ------|
set_line(SPI_C, low);--------|
}
for(i=0;i < 24; i++) { //传3 bytes地址
set_line(SPI_D, BIT(addr, i));
set_line(SPI_C, high);
set_line(SPI_C, low);
}
for(i=0;i < 8; i++) { //传bytes到flash
set_line(SPI_D, BIT(addr, i));
set_line(SPI_C, high);
set_line(SPI_C, low);
}
.....
set_line(SPI_S, high);//把chip select拉高,交互结束
(3)erase chip
command description
Timing analysis
伪代码:
set_line(SPI_S, low); //选中,表示要开始交互
set_line(SPI_C, low); //clock拉低,以保证待会可以“拉高”
for(i=0;i < 8; i++) { //传指令 0XD8
set_line(SPI_D, BIT(command, i));
set_line(SPI_C, high); ------|
set_line(SPI_C, low);--------|
}
for(i=0;i < 24; i++) { //传3 bytes地址
set_line(SPI_D, BIT(addr, i));
set_line(SPI_C, high);
set_line(SPI_C, low);
}
.....
set_line(SPI_S, high);//把chip select拉高,交互结束
(4) SPI总线的缺点
SPI 总线的缺点是缺乏数据流控制机制。也就是说,无论主机方还是从机方
均不对消息进行确认,主机方无法知道从机方繁忙/空闲。因此,一定要通过软
件来处理确认的问题。
H108LV2中通过read status register来确认是否写完,如下:
/* RDSR Command */
spi_ready();
*(volatile unsigned int *) SFCSR = LENGTH(0) | CS(1) | READY
(1); //片选芯片
*(volatile unsigned int *) SFDR = 0x05 << 24;
while (1)
{ unsigned int status;
status = *(volatile unsigned int *) SFDR;
/* RDSR Command */
if ( (status & 0x01000000) == 0x00000000)//
break;
}
*(volatile unsigned int *) SFCSR = LENGTH(3) | CS(3) | READY
(1);//取消选定