SPI协议详解( 三 )


CPHA=1 , 表示第二个边沿:
对于CPOL=0 , idle时候的是低电平 , 第二个边沿就是从高变到低 , 所以是下降沿;
对于CPOL=1 , idle时候的是高电平 , 第一个边沿就是从低变到高 , 所以是上升沿;
还是上图大家更容易看懂
SPI协议详解文章插图
3.2.5 软件中如何设置SPI的极性和相位
SPI分主设备和从设备 , 两者通过SPI协议通讯 。
而设置SPI的模式 , 是从设备的模式 , 决定了主设备的模式 。
所以要先去搞懂从设备的SPI是何种模式 , 然后再将主设备的SPI的模式 , 设置和从设备相同的模式 , 即可正常通讯 。
对于从设备的SPI是什么模式 , 有两种:
3.2.5.1固定的 , 有SPI从设备硬件决定的
SPI从设备 , 具体是什么模式 , 相关的datasheet中会有描述 , 需要自己去datasheet中找到相关的描述 , 即:
关于SPI从设备 , 在空闲的时候 , 是高电平还是低电平 , 即决定了CPOL是0还是1;
然后再找到关于设备是在上升沿还是下降沿去采样数据 , 这样就是 , 在定了CPOL的值的前提下 , 对应着可以推算出CPHA是0还是1了 。
3.2.5.2 可配置的 , 由软件自己设定
从设备也是一个SPI控制器 , 4种模式都支持 , 此时只要自己设置为某种模式即可 。
然后知道了从设备的模式后 , 再去将SPI主设备的模式 , 设置为和从设备模式一样 , 即可 。
对于如何配置SPI的CPOL和CPHA的话 , 不多细说 , 多数都是直接去写对应的SPI控制器中对应寄存器中的CPOL和CPHA那两位 , 写0或写1即可 。
3.3 SSPSR
SPI协议详解文章插图
SSPSR 是 SPI 设备内部的移位寄存器(Shift Register). 它的主要作用是根据 SPI 时钟信号状态, 往 SSPBUF 里移入或者移出数据, 每次移动的数据大小由 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 里面存放的数据为无效数据这样的情况.
3.4 SSPBUF
SPI协议详解文章插图
我们知道, 在每个时钟周期内, Master 与 Slave 之间交换的数据其实都是 SPI 内部移位寄存器从 SSPBUF 里面拷贝的. 我们可以通过往 SSPBUF 对应的寄存器 (Tx-Data / Rx-Data register) 里读写数据, 间接地操控 SPI 设备内部的 SSPBUF.
例如, 在发送数据之前, 我们应该先往 Master 的 Tx-Data 寄存器写入将要发送出去的数据, 这些数据会被 Master-SSPSR 移位寄存器根据 Bus-Width 自动移入 Master-SSPBUF 里, 然后这些数据又会被 Master-SSPSR 根据 Channel-Width 从 Master-SSPBUF 中移出, 通过 Master-SDO 管脚传给 Slave-SDI 管脚, Slave-SSPSR 则把从 Slave-SDI 接收到的数据移入 Slave-SSPBUF 里. 与此同时, Slave-SSPBUF 里面的数据根据每次接收数据的大小(Channel-Width), 通过 Slave-SDO 发往 Master-SDI, Master-SSPSR 再把从 Master-SDI 接收的数据移入 Master-SSPBUF.在单次数据传输完成之后, 用户程序可以通过从 Master 设备的 Rx-Data 寄存器读取 Master 设备数据交换得到的数据.