网站怎么做架构,wordpress 取消边栏,海口网站建设介绍,建网页和网站的区别前言
由于I2C开漏外加上拉电阻的电路结构#xff0c;使得通信线高电平的驱动能力比较弱#xff0c;这就会号致#xff0c;通信线由候电平变到高电平的时候#xff0c;这个上升沿耗时比较长#xff0c;这会限制I2C的最大通信速度#xff0c; 所以#xff0c;I2C的标准模…前言
由于I2C开漏外加上拉电阻的电路结构使得通信线高电平的驱动能力比较弱这就会号致通信线由候电平变到高电平的时候这个上升沿耗时比较长这会限制I2C的最大通信速度 所以I2C的标准模式只有100KHz的时钟频率I2C的快速模式也只有400KHZ虽然I2C协议之后又通过改进电路的方式设计出了高速模式可以达到3.4MHZ但是高速模式目前普及程度不是很高所以一般情况下我们认为I2C的时钟速度最多就是400KHZ这个速度相比较SPI而言还是慢了很多的
1.SPI通信 SPl(Serial Peripheral Interface)是由Motorola公司开发的一种通用数据总线四根通信线:SCK(SerialClock)、MOSl(Master Output SlaveInput)、MISO(Master Input Slave Output)、SS(Slave Select) SPl的主机表示有几个从机就开几条SS所有从机一人一根都别抢给你低电平就说明我要找你了同步全双工支持总线挂载多设备一主多从传输速率块SPl协议并没有严格规定最大传输速度这个最大传输速度取决于芯片厂商的设计需求SPl的硬件开销比较大通信线的个数比较多并且通信过程中经常会有资源浪赛的现象
SPI没有应答机制的设计发送数据就发送接收数据就接收至于对面是不是存在SPl是不管的 第一个图型号是W25Q64是一个Flash存储器这个模块的引脚可以看到和刚才说的并不一样这里CLK就是SCKDI和DO就是MOSI和MISO那D到底是MOSl还是MISO呢我们要看一下这个芯片的身份显然这个芯片接在STM32上应该是从机的身份所以这里的Dl数据输入就是从机的数据输入Sl对应需要接在主机的MO上所以这里的Dl就是MOSI那另一个DO就是MISO了一般在这种始终作为从机的设备上可能会用DI和DO的简写像STM32这种可以进行身份转换的设备般都会把MOSI、MISO的全程写完整那最后一个CS片选其实就是SS从机选择了
第三个是一个2.4G元线通信模块芯片型号是NRF24L01这个芯片使用的就是SPI通信协议要想使用这个芯片来进行无线通信那就需要利用SPI来读写这个芯片
最后一个就是常见的Micro SD卡了这个SD卡官方的通信协议是SDIO但是它也是支持SPl协议的我们可以利用SPI对这个SD卡进行读写操作
2.硬件电路
所有SPI设备的SCK、MOSI、MISO分别连在一起主机另外引出多条SS控制线分别接到各从机的SS脚输出引脚配置为推挽输出输入引脚配置为浮空或上拉输入 左边这里是SPI主机主号整个SP总线主机一般都是控制器来作比如STM32下面这里SPI从机1、2、3就是挂载在主机上的从设备了比如存储器、显示屏、通信模块、传感器等等左边SPI主机实际上引出了6根通信线因为有3个从机所以SS线需要3根再加SCK、MOSI、MISO就是6根通信线当然SPI所有通信线都是单端信号它们的高低电平都是相对GND的电压差所以单端信号所有的设备还需要共地这里GND的线没画出来但是是必须要接的然后如果从机没有独立供电的话主机还需要再额外引出电源正极VCC给从机供电
然后我们看一下这几根通信线首先SCK时钟线时钟线完全由主机掌控所以对于主机来说时钟线为输出对于所有从机来说时钟线都为输入这样主机的同步时钟就能送到各个从机了然后下一个MOSI主机输出从机输入这里左边是主机所以就对应MO主机输出下面三个都是从机所以就对应S1从机输入数据传输方向是主机通过MOSI输出所有从机通过MOSI输入接着下一个MISO主机输入从机输出左边是主机对应MI下面三个是从机对应SO数据传输方向是三个从机通过MISO输出主机通过MISO输入
12C并不是不想使用更快的推挽输出而是12C要实现半双工经常要切换输入输出另外I2C又要实现多主机的时钟同步和总线体裁这些功能都不允许12C使用推挽输出要不然一不小心就电源短路了所以12C选择了更多的功能自然就要放弃更强的性能了
对SPI来说首先SPI不支持多主机然后SPI又是全双工SPI的输出引脚始终是输出输入引脚始终是输入基本不会出现冲突所以SPI可以大胆地使用推挽输出不过当然SPl实还是有一个冲突点的就是图上的MISO引脚主机一个是输入但是三个从机全都是输出如果三个从机都始终是推挽输出势必会导致冲突所以在SPIl协议里有一条规定就是当从机的SS引l脚为高电平也就是从机未被选中时它的MISO引脚必须切换为高阻态高阻态就相当于引脚断开不输出任何电平这样就可以防止一条线有多个输出而导致的电平冲突的问题了在SS为低电平时MISO才允许变为推挽输出这就是SPl对这个可能的冲突做出的规定一般是写在从机里所以我们主机的程序中并不需要关注这个问题
3.移位示意图 这个移位示意图是SPI硬件电路设计的核心只要你把这个移位示意图搞懂了那无论是上面的硬件电路还是我们等会学习的软件时序理解起来都会更加轻松SPl的基本收发电路就是使用了这样一个移位的模型左边是SPI主机里面有一个8位的移位寄存器右边是SP从机里面也有一个8位的移位寄存器左侧的移位寄存器有一个时钟输入端因为SPI一般都是高位先行的所以每来一个时钟移位寄存器都会向左进行移位从机中的移位寄存器也是同理然后呢移位寄存器的时钟源是由主机提供的这里叫作波特率发生器它产生的时钟驱动主机的移位寄存器进行移位同时这个时钟也通过SCK引脚进行输出接到从机的移位寄存器里
之后上面移位寄存器的接法是主机移位寄存器左边移出去的数据通过MOSO引脚输入到从机移位寄存器的右边从机移位寄存器左边移出去的数据通过MISO引脚输入到主机移位寄存器的右边
工作流程首先我们规定波特率发生器时钟的上升沿所有移位寄存器向左移动一位移出去的位放到引脚上波特率发生器时钟的下降沿引脚上的位采样输入到移位寄存器的最低位接下来假设主机有个数据10101010要发送到从机同时从机有个数据01010101要发送到主机那我们就可以驱动时钟先产生一个上升沿这时所有的位就会像这样往左移动一次那从最高位移出去的数据就会放到通讯线上数据放到通信线上实际上是放到了输出数据寄存器此时MOSI数据是1所以MOSl的电平就是高电平这就是第一个时钟上升沿执行的结果 之后时钟继续运行上升沿之后下一个边沿就是下降沿在下降沿时主机和从机内都会进行数据采样输入也就是MOSI的1会采样输入到从机这里的最低位MISO的0会采样输入到主机这里的最低位这就是第一个时钟结束后的现象 下一个上升沿同样的操作移位输出SPl的运行过程就是这样SPl的数据收发都是基于字节交换这个基本单元来进行的当主机需要发送一个字节并且同时需要接收一个字节时就可以执行一下字节交换的时序这就完成了发送同时接收的目的
如果我只想发送不想接收怎么办呢其实很简单我们仍然调用交换字节的时序发送同时接收只是这个接收到的数据我们不看它就行了那如果我只想接收不想发送怎么办呢同理我们还是调用交换字节的时序发送同时接收只是我们会随便发送一个数据只要能把从机的数据置换过来就行了我们读取置换过来的数据不就是接收了嘛这里我们随便发过去的数据从机也不会去看它当然这个随便发送的数据并不是真的随便发般在接收的时候我们会统一发送0x00或OxFF去跟从机换数据
4.SPI时序基本单元 期间一直都是低电平
CPOL(Clock Polarity)时钟极性、和CPHA(Clock Phase)时钟相位
模式0和1的区别模式0把这个数据变化的时机给提前了在实际应用中模式0的应用是最多的
4.1 模式0 与模式一区别CPHA1就是这个模武0的数据移出移入的时机会提取半个时钟也就是相位提前了模式0在SCK第一个边沿就要移入数据但是数据总得先移出才能移入对吧所以在模式0的配置下SCK第一个边沿之前就要提前开始移出数据了或者把它称作是在第0个边沿移出第1个边沿移入
时序首先SS下降沿开始通信现在SCK还没有变化但是SCK一旦开始变化就要移入数据了所以此时趁SCK还没有变化SS下降沿时就要立刻触发移位输出所以这里MOSI和MISO的输出是对齐到SS的下降沿的或者说这里把SS的下降沿也当作时钟的一部分了那SS下降沿触发了输出SCK上升沿就可以采样输入数据了这样B7就传输完毕之后SCK下降沿移出B6上升沿移入数据最终在第8个上升沿时最终在第8个上升沿时整个字节交换完成之后SCK还有一个下降沿如果主机只需要交换一个字节就结束那在这个下降沿时MOSI可以置回默认电平或者不去管它MISO也会变化一次这一位实际上是下一个字节的B7 因为这个相位提前了所以下一个字节的B7会露个头如果不需要的话SS上升沿之后从机MISO置回高阻态这是交换一个字节就结束如果主机想交换多个字节的话那就继续调用从这里到这里的时序在随后一个下降沿主机放下一个字节的B7从机也放下一个字节的B7SCK上升沿正好接着采样第二个字节的B7.这样时序才能拼接的上对吧
4.2 模式1 在SS未被选中时SCK默认是低电平的然后CPHA1表示SCK第一个边沿移出数据第二个边沿移入数据采样
第一个SS从机选择在通信开始前SS为高电平在通信过程中SS始终保持低电平通信结束SS恢复高电平
然后最下面一个MISO这是主机输入从机输出因为有多个从机输出连在了一起如果同时开启输出会造成冲突所以我们的解决方法是在SS未被选中的状态从机的MISO引脚必须关断输出即配置输出为高阻状态SS高电平时MISO用一条中间的线表示高阻态SS下降沿之后从机的MISO被允许开启输出SS上升沿之后从机的MISO必须置回高阻态 然后我们看一下移位传输的操作因为CPHA1SCK第一个边沿移出数据所以这里可以看出SCK第一个边沿就是上升沿主机和从机同时移出数据主机通过MOSI移出最高位此时MOSl的电型就表示了主机要发送数据的B7从机通过MISO移出最高位此时MISO表示从机要发送数据的B7然后时钟运行产生下降沿此时主机和从机同时移入数据也就是进行数据采样这里主机移出的B7进入从机移位寄存器的最低位从机移出的B7进入主机移位寄存器的最低位这样一个时钟脉冲产生完毕一个数据位传输完毕接下来就是同样的过程最后一个下降沿数据B0传输完成至此主机和从机就完成了一个字节的数据交换如果主机只想交换一个字节那这时就可以置SS为高电平结束通信了在SS的上升沿MOSl还还可以再变化一次将MOSI置到一个默认的高电平或低电平当然也可以不去管因为SPI也没有硬性规定MOSI的默认电平然后MISO从机必须得置回高阻态此时如果主机的MISO为上拉输入的话那MISO引脚的电平就是默认的高电平如果主机MISO为浮空输入那MISO引脚的电平不确定这是交换一个字节就结束的流程
那如果主机还想继续交换字节呢在此时主机就不必把SS置回高电平了直接重复一下从这里到这里交换一个字节的时序这样就可以交换多个字节了
4.3 模式2 模式0和2的区别就是SCK的极性取反一下剩下的流程上的东西完全一致
4.4 模式3 模式1和3的区别也是模武1的CPOL0模式3的CPOL1两者的波形也是SCK的极性取反一下 这个CPHA表示的是时钟相位决定是第一个时钟采样移入还是第二个时钟采样移入并不是规定上升沿采样还是下降沿采样的当然在CPOL确定的情况下CPHA确实会改变采样时刻的上升沿和下降沿比如模式0的时候是SCK上升沿采样移入模式1的时候是SCK下降沿采样移入这个了解一下CPHA决定是第几个边沿采样并不能单独决定是上升沿还是下降沿 然后在这4种模式里模式0和模式3都是SCK上升沿采样模式1和模式2都是SCK下降沿采样 5.SPI时序W26Q86
当然每个芯片对SPI时序字节流功能的定义不一样在这里我是以我们本课程使用的芯片W25Q64SPIl对字节流功能的规定不像12C那样12C的规定一般是有效数据流第一个字节是寄存器地址之后依次是读写的数据使用的是读写寄存器的模型
而在SPI中通常采用的是指令码加读写数据的模型这个过程就是SPl起始后第一个交换发送给从机的数据一般叫作指令码在从机中对应的会定义一个指令集当我们需要发送什么指令时就可以在起始后第一个字节发送指令集里面的数据这样就能指导从机完成相应的功能了不同的指令可以有不同的数据个数有的指定只需要一个字节的指令码就可以完成比如W25Q64的写使能、写失能等指令而有的指令后面就需要再跟要读写的数据比如W25Q64的写数据、读数据等写数据指令后面就得跟上我要在哪里写我要写什么对吧读数据指令后面就得跟上我要在那里读我读到的是什么对吧这就是指令码加读写数据的模型在SPI从机的芯片手册里都会定义好指令集什么指令对应什么功能什么指令后面得跟上什么数据
5.1 发送指令 首先是SPI发送指令这个指令的功能是向SS指定的设备发送指令(0x06)指令0x06到底代表什么意思可以由芯片厂商自己规定在W25Q64芯片里这个0x06代表的是写使能
在这里我们使用的是SPI模式0在空闲状态时SS为高电平SCK为低电平MOSI和MISO的默认电平没有严格规定然后SS产生下降沿时序开始在这个下降沿时刻MOSI和MISO就要开始变换数据了MOSl由于指令码最高位仍然是0所以这里保持低电平不变MISO从机现在没有数据发给主机引脚电平没有变换实际上W25Q64不需要回传数据时手册里规定的是MISO仍然是高阻态从机并没有开启输出不过这也没问题反正这个数据我们也不要看那这里因为STM32的MISO是上拉输入所以这里MISO呈现高电平之后SCK第一个上升沿进行数据采样我这里画了一条绿线从机采样输入得到0主机采样输入得到1之后继续第二个时钟主机数据位仍然是0所以波形仍然没有变化然后这样一位一位地发送、接收、发送、接收
到这一位数据才开始变化主机要发送数据1下降沿数据移出主机将1移出到MOSlMOSI变为高电平这里因为是软件模拟的时序所以MOSl的数据变化有些延迟没有紧贴SCK的下降沿不过这也没关系时钟是主机控制的我们只要在下一个SCK上升沿之前完成变化就行了然后SCK上升沿数据采样输入在最后一位呢下降沿数据变化MOSI变为0上升沿数据采样从机接收数据SCK低电平是变化的时期高电平是读取的时期
时序SCK最后一个上升沿结束一个字节就交换完毕了因为写使能是单独的指令不需要跟随数据SPI只需要交换一个字节就完事了所以最后在SCK下降沿之后SS置回高电平结束通信总结一下就是主机用0x06换来了从机的0xFF当然实际上从机并没有输出这个0xFF是默认的高电平不过这个0xFF没有意义我们不用管那整个时序的功能就是发送指令指令码是0x06从机一比对事先定义好的指令集发现0x06是写使能的指令那从机就会控制硬件进行写使能这样一个指令从发送到执行就完成了这就是发送单字节指令的时序 5.2 指定地址写 因为我们这个W25Q64芯片有8M字节的存储空间一个字节的8位地址肯定不够所以这里地址是24位的分3个字节传输 首先SS下降沿开始时序这里MOS|空闲时是高电平所以在下降沿之后SCK第一个时钟之前可以看到MOSI变换数据由高电平变为低电平然后SCK上升沿数据采样输入后面还是一样下降沿变换数据上升沿采样数据8个时钟之后一个字节交换完成我们用0x02换来了0xFF其中发送的0x02是一条指令代表这是一个写数据的时序接收的0xFF不需要看那既然是写数据的时序后面必然还要跟着写的地址和数据了所以在最后一个下降沿时刻因为我们后续还要继续交换字节所以在这个下降沿我们要把下一个字节的最高位放到MOSI上当然下一个字节的最高位仍然是0所以这里数据没有变化之后还是同样的流程交换一个字节第二个字节我们用0x12换来了0xFF根据W25Q64芯片的规定写指令之后的字节定义为地址高位所以这个0x12就表示发送地址的23~16位 之后继续看一下交换1个字节发送的是0x34这个就表示发送地址的15~8位之后还是交换一个字节发送的是0x56这个表示发送地址的7~0位24位地址就发送完毕了从机收到的24位地址是0x123456 那3位地址结束后就要发送写入指定地址的内容了我们继续调用交换一个字节发送数据这里的波形是0x55这就表示我要在0x123456地址下写入0x55这个数据最后如果只想写入一个数据的话就可以SS置高电平结束通信了当然这里也可以继续发送数据SPI里也会有和I2C一样的地址指针每读写一个字节地址指针自动加1如果发送一个字节之后不终止继续发送的字节就会依次写入到后续的存储空间里这样就可以实现从指定地址开始写入多个字了这就是SPI写入的时序
由于SPI没有应答机制所以交换一个字节后就立刻交换下一个字节就行了然后这条指令我们还可以看出由于整个流程我们只需要发送的功能并没有接收的需求所以MISO这条接收的线路就始终处于“挂机”的状态我们并没有用到这就是SPI指定地址写的逻辑当然不同的芯片肯定有不同的规定了我们这个存储器的容量大所以需要连续指定3个字节的地址如果容量小的话可能1个字节的地址就够了或者有的芯片会直接把地址给融合到指令码里去
5.3 指定地址读 所以这里3个字节地址交换完之后我们要把从机的数据搞过来我们还是交换一个数据来个抛砖引玉我们随便给从机一个数据当然一般给FF就行了然后从机此时不传更待何时啊这时从机就会乖乖地把0x123456地址下的数据通过MISO发给主机可以看到这样的波形就表示指定地址下的数据是0x55这样主机就实现了指定地址读一个字节的目的然后如果我们继续抛砖引玉那么从机内部的地址指针自动加1从机就会继续把指定地址下一个位置的数据发过来这样依次进行就可以实现指定地址接收多个字节的目的了然后最后数据传输完毕 SS置回高电平时序结束 当然时序这里也会有一些细节比如由于MISO是硬件控制的波形所以它的数据变化都可以紧贴时钟下降沿另外我们可以看到MISO数据的最高位实际上是在上一个字节最后一个下降沿提前发生的因为这是SPI模式0所以数据变化都要提前半个周期