原理部分我打算听江科大的课复习一下,代码部分工作大概率用HAL库敲了。
出处:[11-1] SPI通信协议_哔哩哔哩_bilibili
& 百问网瑞士军刀HAL库编程课程
简介
SPI(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线。
硬件资源方面需要四根通信线:SCK(Serial Clock)、MOSI(Master Output Slave Input)、MISO (Master Input Slave Output)、SS (Slave Select)。
特点:同步,全双工,它可以支持支持总线挂载多设备(一主多从)。
I2C开漏外加上拉电阻的硬件结构,限制了高电平的驱动能力,也就是说当SDA由低电平变为高电平时,往往需要耗费较多的时间。间接地限制了I2C的最大通信速度。标准I2C速度为100kHZ,高速I2C速度为400kHZ,改进后的极限值大概在3.4M左右。
SPI相较于I2C而言速度通常会更快,直接取决于通信IC因为协议并没有严格规定最大传输速率。
SPI没有应答机制,无法检测从机设备能否正常运转。一般来讲只有永远充当从设备的器件才可以简写为DI\DO。
电路设计
所有SPI设备的SCK、MOSI、MISO分别连在一起。主机另外引出多条SS控制线,分别接到各从机的SS引脚。输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入。为了实现信号回流,实际上所有设备还需要共地。SS线低电平有效,主机想要指定谁就把对应的SS输出线拉低。当一个设备的片选线为高电平状态时,MISO必须切换为高阻态(相当于引脚断开不输出任何电平),这样可以防止同一条通信线路上出现电平冲突问题。当SS为低电平时,MISO才可以切换为推挽输出。
基本收发电路的移位示意图:
SPI的数据遵循高位先行,当主机的移位寄存器接收到来自时钟输入端的一个上升沿之后,它会向左进行移位,并通过MOSI输入到SPI从机。注意整个系统的时钟源都由SPI的主机来提供。当主机的移位寄存器接收到来自时钟输入端的一个下降沿之后,它会对MISO端口进行电平采样。相反地,SPI从机会和主机进行字节交换。
时序讲解
起始条件:SS从高电平切换到低电平
终止条件:SS从低电平切换到高电平
SPI外设中的CPOL\CPHA寄存器使得SPI的通信存在四种模式(00、01、10、11)。
模式1
课上主要先讲了模式1,CPOL=0:空闲状态时,SCK为低电平;CPHA=1: SCK第一个边沿移出数据,第二个边沿移入数据(进行了数据采样)。
如图所示,SS在高电平期间,MISO(主机输入,从机输出)始终处于高阻态用来关断输出(中间的一条线)。SCK输出第一个上升沿时,主机和从机同时移出数据,主机通过MOSI移出最高位,从机通过MISO移出数据最高位;当SCK产生下降沿时,主机和从机同时移入数据,外设通过引脚进行了数据采样,此刻一个时钟脉冲产生完毕,一个数据位传输完毕。注意在SS的上升沿,MOSI可以再变化一次,将MOSI置位到一个默认的高电平或者低电平,但MISO必须置回高阻态。此时如果主机的MISO为上拉输入状态,那么MISO通信线上就是默认的高电平;如果主机MISO为浮空输入,那MISO引脚的电平不确定,这是交换一个字节就结束的流程。
模式0
交换一个字节(模式0)
CPOL=0:空闲状态时,SCK为低电平;CPHA=0: SCK第一个边沿移入数据,第二个边沿移出数据。
SS的下降沿用来开启通信,触发寄存器移位输出,SCK进入上升沿时就可以采样输入数据(B7)了,SCK的下降沿会移出数据B6,下一个上升边沿会移入B6。最后一个SCK的下降沿会使得MOSI进入默认电平状态,MISO也会变化一次移入下一个字节的B7数据位,如果不需要就将它置回高阻态。模式0会将数据变化的时机提前,在实际应用中模式0应用较广。
模式0与魔石的区别是时钟信号极性相反,模式1与模式3的区别同理。
通信示例
不同于IIC通过发送不同从机地址读写寄存器的通信模式,支持SPI通信的IC往往出厂集成了内部指令集。
W25Q64介绍
固件存储可以使系统实现就地执行XIP(execute in place),列如计算机的BIOS。
Dual SPI是双重SPI,Quad SPI是四重SPI, 原理是让两根通信线同时兼具发送和接收的功能,二重一个clk时钟期间发送两位四重就是发送四位。
串行通信是指双方根据同一个时钟一位一位发送数据,并行是指一个时钟8位同时发送。
一个int类型数据占4个字节,一个字节占8个二进制位。因此得到计算规则为4Mbit/8=512KB。
WP写保护低电平有效,接入低电平后IC无法被读写,HOLD也是低电平有效。注意为了实现多重SPI,这两个引脚也可以被复用为通信引脚。
对8M的存储空间进行划分,先划分为若干个块(block)。每一块再划分出若干个扇区(sector),对于扇区内部由可以细分出很多的页(page)。W25Q64的地址宽度为24位|3个字节(最大范围16MB),又因为总量为8MB,所以地址取值为00 00 00h到7F FF FFh。IC设计时规定每个块的容量为64KB。8✖1024/64=128,所以块的序号为块0到快127。在一个块内,我们又以4KB作为一个扇区进行划分。最小的一页占256byte,一个扇区里面有16页。
接下来讨论框图左下角的SPI控制逻辑,IC内部的地址锁存与数据读写等操作都由它来控制。主控通过SPI引脚把数据和指令发送给控制逻辑单元,控制逻辑单元就会自动去操作内部电路。
status register状态寄存器可以体现芯片是否处于忙状态、写使能状态、写保护状态。
高电压生成器可以配合Flash进行数据擦写。
Page Address Latch/Counter页地址锁存/计数器与Byte Address Latch/Counter字节地址锁存/计数器就是用来指定地址的,SPI发送来了24位3个字节位宽的地址,一页有256个字节,因此一页内的字节地址就取决于最低一个字节,而高位的2个字节对应的就是页地址。前两个字节会进入页地址锁存/计数器,最后一个字节会进入字节地址锁存/计数器。页地址会通过写保护\行解码单元来选择我要操作哪一页。字节地址则通过列解码和256字节页缓存来进行指定字节的读写操作。两个计数器确保地址指针在读写之后可以自动加一,从而实现从指定地址开始,连续读写多个字节的目的了。256字节的页缓冲区大的本质是一个RAM存储器,数据的读写都要经过它。写入的数据都需要先放入这个缓冲区,等待时序结束之后,芯片再将缓存区的数据复制到对应的Flash里面进行永久保存。这个机制的产生原因是由于SPI的数据传输速度远远大于Flash的擦写,写入时序结束之后芯片会进入一段忙状态(这个RAM可以直接把状态寄存器的BUSY位置为1)。
Flash操作注意事项
写入操作时:
· 写入操作前,必须先进行写使能;
· 每个数据位只能由1改写为0,不能由0改写为1;
· 写入数据前必须先擦除,擦除后,所有数据位变为1;
· 擦除必须按最小擦除单元进行(一般是一个扇区,4KB=4096字节);因此使用频繁的数据可以放入RAM空间,需要记录后再存入Flash。
· 连续写入多字节时,最多写入一页的数据,超过页尾位置的数据,会回到页首覆盖写入;
· 写入操作结束后,芯片进入忙状态,不响应新的读写操作。
读取操作时:
· 直接调用读取时序,无需使能,无需额外操作,没有页的限制,读取操作结束后不会进入忙状态,但不能在忙状态时读取。
手册领读
状态寄存器1 BUSY位
BUSY是状态寄存器中的一个只读位,当设备在执行页编程、扇区擦除、块擦除、芯片擦除或写状态寄存器指令是时会被置1。在此期间,设备将忽略除读状态寄存器和擦除暂停指令之外的其他指令(参见交流特性中的tw, tpP, tsE, be和tCE)。当程序、擦除或写状态寄存器指令完成时,BUSY位将被清除为0状态,表明设备已准备好接受进一步的指令。
状态寄存器2 Write Enable Latch位
写使能锁存(WEL)是状态寄存器(S1)中的一个只读位,在执行写使能指令后被设置为1。当设备禁止写时,WEL状态位被清除为0。写禁用状态发生在上电或以下任何指令之后:写禁用、页程序、扇区擦除、块擦除、芯片擦除和写状态寄存器。一次写使能,只能确保后续一条指令能够正常运行。但我们不需要写失能,因为写入操作会顺便完成“关门”。
指令集
写使能指令 06h
读状态寄存器1 05h 交换接受S7-S0
页编程 02h
扇区擦拭 20h
查看ID 9Fh
读取数据