SPI与I2C
SPI
本部分主要总结自这里
应用概述
SPI, Serial Perripheral Interface, 串行外围设备接口,是==全双工==的同步串行方式。
SPI 主要应用在 EEPROM, Flash, 实时时钟(RTC), 数模转换器(ADC), 数字信号处理器(DSP) 以及数字信号解码器之间. 它在芯片中占用==四根管脚 (Pin)== 用来控制以及数据传输
特点
采用主-从模式(Master-Slave) 的控制方式
SPI 规定了两个 SPI 设备之间通信必须由主设备 (Master) 来控制次设备 (Slave). 一个 Master 设备可以通过==提供 Clock== 以及==对 Slave 设备进行片选 (Slave Select)== 来控制多个 Slave 设备, SPI 协议还规定 Slave 设备的 Clock 由 Master 设备通过 SCK 管脚提供给 Slave 设备, Slave 设备本身不能产生或控制 Clock, 没有 Clock 则 Slave 设备不能正常工作.
采用同步方式(Synchronous)传输数据
==Master 设备会根据将要交换的数据来产生相应的时钟脉冲(Clock Pulse)==, 时钟脉冲组成了时钟信号(Clock Signal) , ==时钟信号通过时钟极性 (CPOL) 和 时钟相位 (CPHA) 控制着两个 SPI 设备间何时数据交换以及何时对接收到的数据进行采样==, 来保证数据在两个设备之间是同步传输的.
数据交换
SPI 设备间的数据传输之所以又被称为数据交换, 是因为 SPI 协议规定一个 SPI 设备不能在数据通信过程中仅仅只充当一个 “发送者(Transmitter)” 或者 “接收者(Receiver)”. ==在每个 Clock 周期内, SPI 设备都会发送并接收一个 bit 大小的数据==, 相当于该设备有一个 bit 大小的数据被交换了.
工作原理
概述
- SSPBUF, Synchronous Serial Port Buffer, 泛指 SPI 设备里面的内部缓冲区, 一般在物理上是以 FIFO 的形式, 保存传输过程中的临时数据
- SSPSR, Synchronous Serial Port Register, 泛指 SPI 设备里面的移位寄存器(Shift Regitser), ==它的作用是根据设置好的数据位宽(bit-width) 把数据移入或者移出 SSPBUF,往 SSPBUF 里移入或者移出数据, 每次移动的数据大小由 Bus-Width 以及 Channel-Width 所决定==;
- Controller, 泛指 SPI 设备里面的控制寄存器, 可以通过配置它们来设置 SPI 总线的传输模式.
通常情况下, 我们只需要对上图所描述的四个管脚(pin) 进行编程即可控制整个 SPI 设备之间的数据通信:
SCK, Serial Clock, 主要的作用是 Master 设备往 Slave 设备传输时钟信号, 控制数据交换的时机以及速率;
SS/CS, Slave Select/Chip Select, 用于 Master 设备片选 Slave 设备, 使被选中的 Slave 设备能够被 Master 设备所访问;==Master 设备的片选操作必须由程序所实现==. 例如: 由程序把 SS/CS 管脚的时钟信号拉低电平, 完成 SPI 设备数据通信的前期工作; 当程序想让 SPI 设备结束数据通信时, 再把 SS/CS 管脚上的时钟信号拉高电平;
SDO/MOSI, Serial Data Output/Master Out Slave In, 在 Master 上面也被称为 Tx-Channel, 作为数据的出口, 主要用于 SPI 设备发送数据;
SDI/MISO, Serial Data Input/Master In Slave Out, 在 Master 上面也被称为 Rx-Channel, 作为数据的入口, 主要用于SPI 设备接收数据;
SPI 设备在进行通信的过程中, Master 设备和 Slave 设备之间会产生一个数据链路回环(Data Loop), 就像上图所画的那样, 通过 SDO 和 SDI 管脚, SSPSR 控制数据移入移出 SSPBUF, Controller 确定 SPI 总线的通信模式, SCK 传输时钟信号.
Bus-Width 与Channel-Width
==Bus-Width 的作用是指定地址总线到 Master 设备之间数据传输的单位==
例如, 我们想要往 Master 设备里面的 SSPBUF 写入 16 Byte 大小的数据: 首先, 给 Master 设备的配置寄存器设置 Bus-Width 为 Byte; 然后往 Master 设备的 Tx-Data 移位寄存器在地址总线的入口写入数据, 每次写入 1 Byte 大小的数据(使用 writeb 函数); 写完 1 Byte 数据之后, Master 设备里面的 Tx-Data 移位寄存器会自动把从地址总线传来的1 Byte 数据移入 SSPBUF 里; 上述动作一共需要重复执行 16 次.
==Channel-Width 的作用是指定 Master 设备与 Slave 设备之间数据传输的单位==
与 Bus-Width 相似, Master 设备内部的移位寄存器会依据 Channel-Width 自动地把数据从 Master-SSPBUF 里通过 Master-SDO 管脚搬运到 Slave 设备里的 Slave-SDI 引脚, Slave-SSPSR 再把每次接收的数据移入 Slave-SSPBUF里.
通常情况下, ==Bus-Width 总是会大于或等于 Channel-Width==, 这样能保证不会出现因 Master 与 Slave 之间数据交换的频率比地址总线与 Master 之间的数据交换频率要快, 导致 SSPBUF 里面存放的数据为无效数据这样的情况.
Timing
上图通过 Master 设备与 Slave 设备之间交换1 Byte 数据来说明 SPI 协议的工作机制.
首先, 在这里解释一下两个概念:
CPOL: 时钟极性, 表示 SPI 在空闲时, 时钟信号是高电平还是低电平. 若 CPOL 被设为 1, 那么该设备在空闲时 SCK 管脚下的时钟信号为高电平. 当 CPOL 被设为 0 时则正好相反.
CPHA: 时钟相位, 表示 SPI 设备是在 SCK 管脚上的时钟信号变为上升沿时触发数据采样, 还是在时钟信号变为下降沿时触发数据采样. 若 CPHA 被设置为 1, 则 SPI 设备在时钟信号变为下降沿时触发数据采样, 在上升沿时发送数据. 当 CPHA 被设为 0 时也正好相反.
上图里的 “Mode 1, 1” 说明了本例所使用的 SPI 数据传输模式被设置成 CPOL = 1, CPHA = 1. 这样, ==在一个 Clock 周期内, 每个单独的 SPI 设备都能以全双工(Full-Duplex) 的方式, 同时发送和接收 1 bit 数据==, 即相当于交换了 1 bit 大小的数据.==如果 SPI 总线的 Channel-Width 被设置成 Byte, 表示 SPI 总线上每次数据传输的最小单位为Byte==, 那么挂载在该 SPI 总线的设备每次数据传输的过程至少需要 8 个 Clock 周期(忽略设备的物理延迟). 因此, ==SPI 总线的频率越快, Clock 周期越短, 则 SPI 设备间数据交换的速率就越快==.
LPC2138(ARM7)应用实例
本部分内容摘自ARM嵌入式应用技术
寄存器概述
LPC2138中SPI接口包含5个寄存器
- SPCR:用于控制SPI模块功能,该寄存器==必须在数据传输之前进行设置==。它可以设置主从模式选择、CPOL、CPHA等。
- SPSR:用于显示SPI总线状态,==可以监测传输是否完成(查询SPIF位),以及指示异常状况==。
- SPDR:用于提供发送和接受数据字节。
- SPCCR:用于控制主机SCK的频率,==寄存器的值必须是大于等于8的偶数==。
- SPINT:中断标志。
作为主机时的设置
- 设置SPI时钟计数寄存器SPCCR,获得期望的SPI时钟;
- 设置SPI控制寄存器SPCR,控制SPI为主机模式,配置SPI时钟极性;
- 选择从机,将要发送的数据写入SPI数据寄存器SPDR,启动SPI数据传输;
- 等待SPI状态寄存器SPSR中的SPIF位置位,SPIF将在SPI数据传输的最后一个周期之后置位;
- 读取SPI状态寄存器SPSR;
- 从SPI数据寄存器SPDR中读出接受到的数据(可选);
- 如果有更多数据需要发送,则跳到第3步。
作为从机时的设置
设置SPI控制寄存器SPCR,控制SPI为从机模式,配置SPI时钟极性等;
将要发送的数据写入SPI数据寄存器SPDR(可选)(注意:这只能在从SPI传输没有进行时执行);
- 等待SPI状态寄存器SPSR中SPIF位置位,SPIF位将在SPI数据传输的最后一个采样钟沿之后置位;
- 读取SPI状态寄存器SPSR;
- 从SPI数据寄存器SPDR中读出接收到的数据(可选);
- 如果有更多数据需要发送,则跳到第2步。