当前位置:首页 > 分类129 > 正文

spi与iic有什么不同

摘要: spi与iic有什么不同最佳答案53678位专家为你答疑解惑单片机常用IIC、SPI、UART接口介绍,下面一起来看看本站小编小...

spi与iic有什么不同

最佳答案 53678位专家为你答疑解惑

单片机常用IIC、SPI、UART接口介绍,下面一起来看看本站小编小阔电子制作给大家精心整理的答案,希望对您有帮助

spi与iic有什么不同1

很多人听到IIC总线、SPI总线、485总线什么的就会晕,其实,数据传输的接线方式,大体上就是两种:一种是并行接口,一种是串行接口。

并行接口是什么?用并行方式来传输数据的接口。假如我想传输几个8位的数据,那好,单片机上用8个IO传送数据,每次就能传送一个。假如想传输几个16位的数据呢?那就要用16个IO!优点是速度快,缺点是占用的IO太多了。

串行接口是什么?是指数据在有限的几个IO上按照顺序,一位一位的进行传输。这类有很多:UART、IIC、SPI、CAN、USB等等,只要是串行传输的接口,都是串口的一种。但是由于早期人们都习惯把UART口称为串口,导致很多人都习惯了说串口的时候特指UART口。

IIC接口

IIC 即Inter-Integrated Circuit(集成电路总线),这种总线类型是由飞利浦半导体公司在八十年代初设计出来的一种简单、双向、二线制、同步串行总线,主要是用来连接整体电路(ICS) ,IIC是一种多向控制总线,也就是说多个芯片可以连接到同一总线结构下,同时每个芯片都可以作为实时数据传输的控制源。主要包括启始、停止、读、写、应答信号。这种方式简化了信号传输总线接口。

IIC总线上可以挂多个器件,而每个器件都有唯一的地址,这样可以标识通信目标。数据的通信的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。

能用于替代标准的并行总线,能连接的各种集成电路和功能模块。I2C是多主控总线,所以任何一个设备都能像

主控器一样工作,并控制总线。总线上每一个设备都有一个独一无二的地址,根据设备它们自己的能力,它们可以作

为发射器或接收器工作。多路微控制器能在同一个I2C总线上共存。

SPI接口

SPI 是英语 Serial Peripheral Interface 的缩写,顾名思义就是串行外围设备接口。SPI 是一种高速的、全双工、同步通信总线,标准的 SPI 也仅仅使用 4 个引脚,常用于单片机和 EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。SPI 通信原理比 I2C要简单,它主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机,标准的 SPI 是 4 根线,分别是 SSEL(片选,也写作 SCS)、SCLK(时钟,也写作 SCK)、MOSI(主机输出从机输入Master Output/Slave Input)和 MISO(主机输入从机输出 Master Input/Slave Output)。

在时序上,SPI 是不是比 I2C要简单的多?没有了起始、停止和应答,UART 和 SPI 在通信的时候,只负责通信,不管是否通信成功,而 I2C却要通过应答信息来获取通信成功失败的信息,所以相对来说,UART 和 SPI 的时序都要比 I2C简单一些。

SPI总线最主要的优点是其简单性和有效性。由于接口直接在组件之上,因此SPII总线占用的空间非常小,减少了

电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺,并且能够以10Kbps的最大传输速率

支持40个组件。SPI总线的另一个优点是,它支持多主控(multimastering),其中任何能够进行发送和接收的设备都

可以成为主总线。一个主控能够控制信号的传输和时钟频率。当然,在任何时间点上只能有一个主控。

UART接口

UART是串行异步通信接口,它包括RS232、RS499、RS423、RS422和RS485等接口规范和 标准规范,即UART是串行异步通信口的总称。

串口通信的概念非常简单,串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式。这种通信方式使用的数据线少,在远距离通信中可以节约通信成本,但其传输速度比并行传输低。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。

通信使用3根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。

UART、SPI、I2C区别

1、UART就是两线,一根发送一根接收,可以全双工通信,线数也比较少。数据是异步传输的,对双方的时序要求比

较严格,通信速度也不是很快。在多机通信上面用的最多。

2、SPI接口和上面UART相比,多了一条同步时钟线,上面UART的缺点也就是它的优点了,对通信双方的时序要求不

严格不同设备之间可以很容易结合,而且通信速度非常快。一般用在产品内部元件之间的高速数据通信上面,如大容

量存储器等。

3、I2C接口也是两线接口,它是两根线之间通过复杂的逻辑关系传输数据的,通信速度不高,程序写起来也比较复

杂。一般单片机系统里主要用来和24C02等小容易存储器连接。

SPI:高速同步串行口。3~4线接口,收发独立、可同步进行

UART:通用异步串行口。按照标准波特率完成双向通讯,速度慢

SPI:一种串行传输方式,三线制,网上可找到其通信协议和用法的3根线实现数据双向传输串行外围接口

(Serial peripheral Interface)

spi与iic有什么不同2

上一章所讲的UART通信属于异步通信,比如计算机发送数据给单片机,计算机只负责把数据通过TXD发送出来,接收数据是单片机自己的事情。而IIC和SPI都属于同步通信,收发双方需要一条时钟线来控制收发双方的通信节奏。

从应用上来讲,UART通信多用于板间通信,比如单片机和计算机,这个设备和另外一个设备之间的通信。而IIC和SPI多用于板内通信,比如使用IIC进行单片机和EEPROM的通信,比如使用SPI进行单片机和FLASH之间的通信。

6.1 IIC总线协议

在硬件上,IIC总线是由时钟总线SCL和数据总线SDA两条线构成,其中SCL为时钟线,SDA为数据线,如图6-1所示。总线上可以同时连接多个器件,所有器件的SCL都连到一起,所有SDA都连到一起。

6-1 IIC总线时序图

起始信号:IIC通信的起始信号的定义是SCL为高电平期间,SDA由高电平变化到低电平产生的一个下降沿,表示一次通信过程的开始,如图6-2中的Start部分所示。

数据传输:IIC通信是高位在前,低位在后。IIC通信要求当SCL在低电平的时候,SDA允许变化,也就是说,发送方必须先保持SCL是低电平,才可以改变数据线SDA,输出要发送的当前数据的一个位;而当SCL在高电平的时候,SDA绝对不可以变化,因为这个时候,接收方要来读取当前SDA的电平信号是0还是1,因此要保证SDA的稳定,如图6-1中的每一位数据的变化,都是在SCL的低电平位置。8位数据位后边跟着的是一位应答位,应答位我们后边还要具体介绍。

停止信号:IIC通信停止信号的定义是SCL为高电平期间,SDA由低电平向高电平变化产生一个上升沿,表示一次通信过程的结束,如图6-1中的Stop部分所示。

6.2 IIC寻址模式

上一节介绍的是IIC每一位信号的时序流程,而IIC通信在字节级的传输中,也有固定的时序要求。IIC通信的起始信号(Start)后,首先要发送一个从机的地址,这个地址一共有7位,紧跟着的第8位是数据方向位(R/W),“0”表示接下来要发送数据(写),“1”表示接下来是请求数据(读)。

Kingst-32F1板子上的EEPROM器件型号是24C02,在24C02的数据手册3.6节中可查到,24C02的7位地址中,其中高4位是固定的0b1010,而低3位的地址取决于具体电路的设计,由芯片上的A2、A1、A0这3个引脚的实际电平决定。IIC总线器件是开漏引脚,因此外部要添加上拉电阻,保证总线空闲时为高电平。来看一下24C02的电路图,如图6-2所示。

从图6-2可以看出来,A2、A1、A0都是接的GND,也就是说都是0,因此24C02的7位地址实际上是二进制的0b1010000,也就是0x50。

IIC通信分为标准模式100kbit/s、快速模式400kbit/s和高速模式3.4Mbit/s。因为所有的IIC器件都支持标准模式,但却未必支持另外两种速度,所以作为通用的IIC程序我们选择100k这个速率来实现,也就是说实际程序产生的时序必须小于等于100k的时序参数,有特殊速度需求的器件再针对性写高速通信程序。

IIC引脚属于开漏并联结构,并且STM32的GPIO端口引脚设置为开漏输出时,可以直接从输入数据寄存器获取I/O电平状态,因此将IIC引脚配置为开漏输出模式。由于IIC总线空闲时默认为高,初始化时还需要设置引脚输出高电平,不过设置引脚输出高电平并不是在初始化之后,而应该放在初始化之前。这是因为STM32在上电复位时I/O口为高阻状态,复位结束后,GPIO端口引脚默认为浮空输入,由于上拉电阻的存在,IIC引脚被拉高;当程序执行到IIC初始化时又被配置为开漏输出模式,由于GPIO端口输出数据寄存器初始值默认全为0,初始化后I/O口输出低电平,如果初始化之后再设置引脚输出高电平,势必会在I/O口上产生一个低电平的毛刺。如果在IIC引脚初始化之前先设置输出数据寄存器相应位为高,初始化IIC引脚后,I/O口会直接输出高电平,避免毛刺信号。

以下是IIC总线的驱动程序:

6.3 初识EEPROM

在实际的应用中,保存在单片机RAM中的数据,掉电后就丢失了,保存在单片机内部FLASH中的数据,又不能随意改变。但是在某些场合,我们需要记录下某些数据,而它们还需要时常改变或更新,并且掉电之后数据还不能丢失,比如我们的家用电表度数,电视机里边的频道记忆,一般都是使用EEPROM来保存数据,特点就是掉电后不丢失。Kingst-32F1板子上使用的这个器件是24C02,是一个容量大小是2Kbits,也就是256个字节的EEPROM。一般情况下,EEPROM拥有30万到100万次的擦除寿命,也就是它可以反复写入30-100万次,而读取次数是无限的。

24C02是一个基于IIC通信协议的器件,因此从现在开始,IIC和EEPROM就要合体了。但要分清楚,IIC是一个通信协议,它拥有严密的通信时序逻辑要求,而EEPROM是掉电后数据不丢失的一种存储器件的统称,24C02就属于EEPROM,只不过24C02采样了IIC协议的接口与单片机相连而已,二者并没有必然的联系,EEPROM可以用其它接口,IIC也可以用在其它很多器件上。

6.4 EEPROM单字节读写操作时序

STM32F103系列单片机本身自带硬件IIC模块,可以类似USART通信那样,通过配置实现数据的收发。本书对IIC协议的介绍针对的是绝大多数的应用场合,实际上IIC的配置过程比较复杂,比如要充分考虑冲突和仲裁等处理方式,但是那些处理方式在绝大多数场合用不到。STM32F103系列自带的IIC协议模块设计的过于复杂,对于实际应用来讲实用性不强,因此实际应用IIC时,还是用IO口直接模拟协议。本书原则就是实际开发采用何种用法,就重点介绍何种用法,下面用实例来实现一下EEPROM读写的基本流程。

1、EEPROM写数据流程

第一步,首先是IIC的起始信号,接着跟上首字节,也就是前边讲的IIC的器件地址,并且在读写方向上选择“写”操作。

第二步,发送数据的存储地址。24C02一共256个字节的存储空间,地址从0x00~0xFF,想把数据存储在哪个位置此刻写的就是哪个地址。

第三步,发送要存储的数据,注意在写数据的过程中,EEPROM每个字节会回应一个“应答位0”,来通知用户写EEPROM数据成功,如果没有回应答位,说明写入不成功。单字节写时序如图6-3所示。

图6-3 IIC Byte Write时序图

2、EEPROM读数据流程

第一步,首先是IIC的起始信号,接着跟上首字节,也就是前边讲的IIC的器件地址,并且在读写方向上选择“写”操作。这个地方可能有读者会诧异,明明是读数据为何方向也要选“写”呢?刚才说过了,24C02一共有256个地址,选择写操作是为了把所要读的数据的存储地址先写进去,告诉EEPROM将要读取哪个地址的数据。这就如同打电话,先拨总机号码(EEPROM器件地址),而后还要继续拨分机号码(数据地址),而拨分机号码这个动作,主机仍然是发送方,方向依然是“写”。

第二步,发送要读取的数据的地址,注意是地址而非存在EEPROM中的数据,通知EEPROM要哪个分机的信息。

第三步,重新发送IIC起始信号和器件地址,并且在方向位选择“读”操作。

这三步当中,每一个字节实际上都是在“写”,所以每一个字节EEPROM都会回应一个“应答位0”。

第四步,读取从器件发回的数据,读一个字节,如果还想继续读下一个字节,就发送一个“应答位ACK(0)”,如果不想读了,告诉EEPROM,不想要数据了,别再发数据了,那就发送一个“非应答位NAK(1)”。

每读一个字节,地址会自动加1,那如果想继续往下读,给EEPROM一个ACK(0)低电平,那再继续给SCL完整的时序,EEPROM会继续往外送数据。如果不想读了,要告诉EEPROM不要数据了,直接发送一个NAK(1)高电平。24C02读数据时序如图6-4所示。

图6-4 IIC Read时序图

利用EEPROM单字节读写功能设计了一个记录开发板复位次数的小程序。由于EEPROM中的数据很容易被擦除或者改写,为了保证记录数据的准确性,需要对读出的数据进行校验。这里向大家介绍一种简单又实用的校验方法:将复位次数保存在EEPROM地址0x00中,并对复位次数按位取反后保存在地址0x01中。开发板每次复位后先去读取地址0x00和0x01中的数据,对其进行异或运算,如果运算结果为0xFF,表明数据正确,将地址0x00中的数据加1后,重新写入到EEPROM中,并通过数码管显示读出的数据;否则记录的数据被改写,从0开始重新记录复位次数。由于板载数码管仅能显示两位数,记录的最大次数为99,超过99重新开始记录。具体代码如下:

6.5 EEPROM多字节读写操作时序

读取EEPROM很简单,EEPROM根据时序直接把数据送出来,但是写EEPROM却没有这么简单了。给EEPROM发送数据后,先保存在EEPROM的缓存,EEPROM必须要把缓存中的数据搬移到“非易失”的区域,才能达到掉电不丢失的效果。而往非易失区域写需要一定的时间,每种器件不完全一样,ATMEL公司的24C02的这个写入时间最长不超过5ms。在往非易失区域写的过程,EEPROM是不会再响应用户访问的,不仅接收不到用户的数据,即使用I2C标准的寻址模式去寻址,EEPROM都不会应答,就如同这个总线上没有这个器件一样。数据写入非易失区域完毕后,EEPROM再次恢复正常,可以正常读写了。

在向EEPROM连续写入多个字节的数据时,如果每写一个字节都要等待几ms的话,整体上的写入效率就太低了。因此EEPROM的厂商就想了一个办法,把EEPROM分页管理。24C01、24C02这两个型号是8个字节一个页,24C04、24C08、24C16是16个字节一页。Kingst-32F1开发板上用的型号是24C02,一共是256个字节,8个字节一页,那么就一共有32页。

分配好页之后,如果在同一个页内连续写入几个字节后,最后再发送停止位的时序。EEPROM检测到这个停止位后,会一次性把这一页的数据写到非易失区域,就不需要写一个字节检测一次了,并且页写入的时间也不会超过5ms。如果写入的数据跨页了,写完一页之后要发送一个停止位,然后等待并且检测EEPROM的空闲模式,一直等到把上一页数据完全写到非易失区域后,再进行下一页的写入,这样就可以在很大程度上提高数据的写入效率,页写时序如图6-5所示。

图6-5 EEPROM页写时序

本节利用EEPROM多字节读写功能设计了一个通过串口发送指令控制EEPROM读写数据的例程。该例程只需要下载一次程序,就能通过串口调试助手实现对EEPROM任意地址的读写操作,避免重复编程控制EEPROM读写数据的方式,具有很高是实用意义。与第五章串口实用例程类似,通过串口调试助手发送控制指令,单片机检测到指令后做出相应动作。

EEPROM读数据指令格式:“e2read 地址 字节长度”,其中地址范围为0~255,e2read、地址、字节长度之间由空格隔开,比如从地址1开始读取5字节数据:e2read 1 5。单片机收到指令后执行多字节读操作,通过串口助手返回读出的数据。

EEPROM写数据指令格式:“e2write 地址 数据”,地址范围为0~255,e2write、地址、数据之间同样由空格隔开,比如从地址1开始写入hello:e2write 1 hello。单片机收到指令后执行多字节写操作,写入成功后通过串口助手返回“e2write done.”

如果发送指令格式错误,返回“bad parameter.”,如果发送指令错误,将返回发送的指令。

6.6 使用逻辑分析仪测试UART和IIC信号

在实际开发过程中,大多数情况下程序代码并不是一写出来就可以正常运行,通常需要查找问题,调试功能。在单片机内部运行的变量和寄存器等参数可以通过在线仿真的方法查看,而单片机外部引脚的运行就要使用示波器或逻辑分析仪来查看了。在分析数字信号以及标准协议信号方面,逻辑分析仪的分析功能比示波器更优一些,下面就采用Kingst LA5016逻辑分析仪,针对6.5节的程序,将UART和I2C信号进行抓取分析。

UART数据抓取和解析解码的界面如图6-6所示,从图上可以看出,单个脉冲T1到T2之间的时间差是104us,时间差的倒数就是波特率,也就是9600。当没有信号的时候,通道处于高电平,产生第1个低电平就是起始位,而后是8位数据位,最后是停止位,其中数据位的位置软件都加了白点。最终,软件根据协议设置选项将数据解析出来是0x31,0x32......。

图6-6 Kingst LA5016逻辑分析仪解析UART数据

当串口助手发送读数据指令,读到的数据不正确的时候,首先我们要判断一下是单片机发送错了,还是电脑接收错了,这个时候可以通过分析仪测量一下UART串口通信波形以及解析的数据来判断。如果分析仪抓到的都正确,那就说明发送正确,接收方出现问题。

如果分析仪抓取分析的数据,不是单片机想发送的数据,那说明发送错了。既然发送错了,要么是程序问题,要么是从EEPROM读取的数据错了。这个时候需要抓一下从EEPROM读到的数据。采集分析完从EEPROM读到的数据,如果数据正确,那问题可能就出在了读数据后转成UART发送给电脑的程序过程中;如果数据是错误的,那要么是存入EEPROM本来就是错误的,要么是存入正确,读取EEPROM的程序是错误的,如图6-7所示。

图6-7 Kingst LA5016逻辑分析仪解析IIC数据

在图6-7当中,其中通道0是SCL,通道1是SDA。图中可以看出读写时序图,并且可以将读写的数据解析出来,用来判断出从EEPROM读取的数据是否有错。

6.7 初识SPI总线协议

SPI(Serial Peripheral Interface)是一种高速的、全双工、同步通信总线,常用于单片机和EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。由于其简单实用,数据传输速率较高,被广泛应用于外设控制领域。标准的SPI接口一般使用4条线:串行时钟线(SCK)、主机输入/从机输出数据线(MISO)、主机输出/从机输入数据线(MOSI)和从机选择线(CS,也被称作SSEL或NSS)。SPI总线允许一对一或一对多通信,无论哪种方式,通信线路中只允许有一个主机。一对多通信要求从机共用SCK、MISO、MOSI,通过片选CS(NSS)选择使能从机设备。从微观角度上看主机一次只能与一个从机通信,比如主机先与从机1通信,然后再与从机2通信,如此循环,在宏观角度上看就相当于一个主机与两个从机实现通信,如图6-8所示。

图6-8 SPI接口连接示意图

6.7.1 SPI通信原理

SPI总线与前面讲的IIC总线类似,都属于同步通信,即通信双方时必须使用相同的时钟信号;都属于一主多从结构,即总线上只有一个主机,可以挂载多个从机。不同之处在于,IIC属于单工通信,同一时刻只能收或者发,而SPI可以全双工通信,同一时刻既能收又能发,因此SPI的通信速率远远超过IIC,可以达到几十Mbps。此外IIC通信可以由主从设备的任意一方发起,而SPI通信只能由主机发起,从机不能主动与主机通信,因为从机不产生同步时钟信号。

SPI通信本质上是一个串行移位过程。SPI主从设备构成一个环形总线结构,SPI通信的主机一般是单片机,首先主机拉低CS(NSS)信号使能片选,告诉从机开始通信,然后主机开始输出同步时钟信号SCK,主机的移位寄存器通过MOSI移出1位数据,从机的移位寄存器通过该线移入这1位数据;同时从机的移位寄存器又通过MISO线移出1位数据,主机的移位寄存器通过该线移入这1位数据,因此在1个时钟周期内,主从设备的双向移位寄存器通过MOSI和MISO数据线实现了1 bit数据的交换,即双方都发出并接收到1 bit数据。

6.7.2 SPI通信模式

I2C总线只有一种通信模式,即当SCL在低电平的时候,向SDA输出数据,当SCL在高电平的时候,对SDA上的数据进行采样。与I2C不同的是,SPI总线有四种通信模式,要了解这四种模式,首先我们得学习以下两个名词。

CPOL: Clock Polarity,就是时钟的极性。时钟的极性是什么概念呢?通信的整个过程分为空闲时刻和通信时刻,如果CPOL=1,那么SCLK在数据发送之前和之后的空闲状态是高电平,如果CPOL=0,那么SCK烦人空闲状态就是低电平。

CPHA: Clock Phase,意思是时钟的相位,就是指数据采样发生在第几个时钟边沿, CPHA=0对应着第一个时钟边沿,CPHA=1对应着第二个时钟边沿。

主机和从机要交换数据,就牵涉到一个问题,即主机在什么时刻输出数据到MOSI上而从机在什么时刻采样这个数据,或者从机在什么时刻输出数据到MISO上而主机什么时刻采样这个数据。同步通信的一个特点就是所有数据的变化和采样都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近输出或被采样。而一个时钟周期必定包含了一个上升沿和一个下降沿,这是周期的定义所决定的,只是这两个沿的先后并无规定。又因为数据从产生的时刻到其稳定是需要一定时间的,那么,如果主机在上升沿输出数据到MOSI上,从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据,那么另一方就必须在上升沿采样这个数据。

CPHA=0,就表示数据的采样是在一个时钟周期的第一个沿上,至于这个沿是上升沿还是下降沿,这要视CPOL的值而定,CPOL=1那就是下降沿,反之就是上升沿。那么数据的采样自然就是在第二个沿上了。

CPHA=1,就表示数据的采样是在一个时钟周期的第二个沿上,同样它是什么沿由CPOL决定。CPOL=1那就是上升沿,反之就是下降沿。

以CPOL=1/CPHA=1,高位在前为例,把时序图画出来给大家看一下,如图6-9所示。

图6-9 SPI通信时序图(一)

如图6-10所示,当数据未发送时以及发送完毕后,由于CPOL=1,因此SCK都是高电平。可以看出,在SCK第一个沿的时候,MOSI和MISO会发生变化,同时SCK第二个沿的时候,数据是稳定的,此刻采样数据是合适的,即一个时钟周期的后沿锁存并读取数据,即CPHA=1。注意最后最隐蔽的SSEL片选,这个引脚通常用来决定主机是和哪个从机进行通信。剩余的三种模式,直接把图画出来,简化起见把MOSI和MISO合在一起了,可以通过仔细对比加深对SPI通信的理解,SPI剩余三种模式时序如图6-8所示。

需要解释一下CPHA=0时的两种模式时序图,图中数据采样发生在数据输出之前,可能会存在疑问,主机和从机还未输出数据就进行采样?图中所示的数据输出指的是输出第二位数据,即图中所示bit 6 位的数据。那么被采样的数据位是什么时候输出的?其实早在SCK信号由空闲状态转变为有效状态之前,即在SCK的第一个时钟边沿还要早半个时钟周期时,SPI主机就已经开始输出数据了,但是SPI从机却是在片选SSEL置低后开始输出数据,总之SPI设备输出数据要早于SCK,这也是为什么SPI通信时要先使能片选。

图6-10 SPI通信时序图(二)

6.8 配置STM32的SPI外设

STM32单片机的SPI接口允许芯片与外部设备以半/全双工、同步、串行方式通信。此接口可以被配置成主模式或从模式,当被配置为主模式时,可以为外部从设备提供通信时钟信号(SCK)。SPI接口拥有8个主模式波特率预分频系数(最大为fPCLK/2,fPCLK为挂载SPI外设的APBx的时钟频率)。需要说明的一点,由于APB1的最高频率是36Mhz,APB2的最高频率是72Mhz,SPI波特率预分频系数为2时,位于APB2上的SPI外设理论上最大速率是36MHz,但是实际上由于STM32F103的硬件限制,SPI的最大速率只能达到18Mhz(选型手册也有介绍)。此外,SPI接口还支持硬件的CRC校验,保证通信的可靠性。

6.8.1 SPI引脚

在配置STM32的SPI模块为主机模式时,MOSI引脚是数据输出,而MISO引脚是数据输入。当被配置为从机模式时 MOSI引脚则是数据输入,MISO引脚是数据输出。因此通信时主从设备的MOSI两两相连,MISO两两相连,此外还需要连接SCK和CS(NSS)引脚。

注意:SPI3模块部分引脚与 JTAG引脚共用,这些引脚不受IO控制器控制,它们(复位后)被默认保留为JTAG用途。如果想把引脚配置给SPI3,必须在初始化引脚时关闭JTAG并切换SWD接口,代码为:

GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

// JTAG-DP 失能 + SW-DP 使能指令。

NSS:从设备选择。作为“片选引脚”,这是一个可选的引脚,使得主设备可以单独地与特定从设备通讯,避免数据线上的冲突。从设备的NSS引脚可以由主设备的一个标准I/O引脚来驱动,不一定非要SPI外设的NSS引脚,采用普通IO口作为NSS引脚时需要设置NSS引脚模式为软件NSS模式。Kingst-32F1开发板SPI2接口与多路设备通信,其从机的NSS引脚就是STM32的几个普通I/O口,后续用到再详细介绍。

6.8.2 SPI初始化配置

首先看一下SPI外设的初始化结构体成员及其描述。

1、SPI_Dirention 设置了SPI是单向通信还是双向的通信数据模式,设置参数如表6-3所示。

2、SPI_Mode设置了SPI 设备是工作在主机模式还是从机模式,设置参数如表6-4所示。

3、SPI_DataSize设置了SPI通信时数据帧是8位还是16位,没有特殊要求,通常配置为8位模式,设置参数如表6-5所示。

4、SPI_CPOL设置了SPI串行时钟SCK的时钟极性,选择该参数时需要确保SPI通信双方保持一致,一般根据SPI从设备支持的模式设定,设置参数如表6-6所示

5、SPI_CPHA设置了SPI采样时发生在SCK的哪个边沿,该参数同样需要确保通信双方保持一致,一般也是根据从设备支持的模式设定,设置参数如表6-7所示

6、SPI_NSS设置了NSS片选引脚是由选择硬件模式,还是由软件模式。采用硬件管理时,片选信号由SPI硬件自动产生,不需要手动设置,而软件模式需要手动设置片选引脚电平。实际开发中通常设置为软件模式,即使用普通IO口作为片选引脚。设置参数如表6-8所示

7、SPI_BaudRatePrescaler设置了SPI波特率预分频系数,分频后的时钟就是SCK信号线的时钟频率。注意SPI正在通信时不能更改波特率预分频系数,具体设置参数如表6-9所示

8、SPI_FirstBit设置了数据传输是高位在前(MSB先行)还是低位在前(LSB先行),没有特殊要求一般设置为高位在前(MSB先行)设置参数如表6-10所示。

9、SPI_CRCPolynomial设置是否使用CRC校验。使用时根据需求设置CRC多项式,不使用时设置其值为7(复位值为0x0007,默认不使用)。无特殊要求通常不设置CRC校验。

SPI配置流程:

1、使能SPI外设时钟及SPI接口引脚时钟

2、初始化SPI引脚——初始化NSS、SCK、MISO、MOSI引脚。

3、初始化SPI外设——根据需求设置SPI初始化结构体成员参数

4、使能SPI外设——SPI使能库函数为:SPI_Cmd(SPIx, ENABLE);其中SPIx,x为1、

2、3,用来选择SPI外设。

5、编写SPI数据发送和接收函数

6.8.3 SPI数据发送和接收

SPI数据发送和接收过程与USART类似,由数据缓冲区和一个8位的双向移位寄存器构成。SPI的数据缓冲区叫做数据寄存器(SPI_DR),虽然是一个寄存器,但是实质上包含两个缓冲区:发送缓冲和接收缓冲,分别用于进行写操作和读操作。与USART两个单独的移位寄存器不同,SPI只有一个移位寄存器且是双向的,同一时刻既向MOSI上移出要发送的数据,又将MISO上的数据向内移入,这个过程是同步的,SPI传输结构如图6-11所示。

图6-11 SPI数据传输结构图

SPI发送数据时只需要将数据写入到SPI_DR,SPI会自动将其分配到发送缓冲区,然后再将数据从发送缓冲区并行传送到移位寄存器中,同时设置一个发送缓冲区为空(TXE)的标志位,最后数据按照设定的数据格式(MSB或LSB)被串行的从MOSI引脚移出。与此同时MISO引脚也会接收到数据,接收到的数据同样按照相应的格式被串行的移入到移位寄存器,当接收完一帧数据后,移位寄存器将接收到的数据传送到接收缓冲区中,同时会设置一个接收缓冲区非空(RXNE)的标志位。使用SPI发送和接收数据时并不需要关心数据是怎么发送或者接收到的,只需要检测相应标志位后向数据寄存器(SPI_DR)写入要发送的数据或者读出接收到的数据即可。

TXE标志位被置位仅表示发送缓冲区为空,可以继续向SPI_DR写入数据,但并不代表数据发送完成,这一点一定要搞清楚。向发送缓冲区写入数据会清除TXE标志位,如果TXE=0即发生缓冲区非空时,向SPI_DR中写入数据会覆盖发送缓冲区中的数据,但不会影响移位寄存器中的数据。RXNE=1表示接收缓冲区非空,即已经接收到一帧数据。读SPI_DR寄存器硬件会自动清除RXNE标志位,并返回接收到的数据。当SPI接收到一帧数据时,意味着SPI肯定已经发送完一帧数据,因此判断一帧数据是否发送完成,可以通过检测RXNE标志位。如果设置了SPI_CR1寄存器中的TXEIE位或者SPI_CR2寄存器中的RXNEIE位,将产生对应的中断。本文主要是以查询方式介绍SPI如何收发数据。

使用查询方式检测TXE和RXNE标志位时需要用到SPI标志位检测函数,如下所示:

SPI_I2S_GetFlagStatus(SPI_TypeDef* SPIx, uint16_t SPI_I2S_FLAG);其中SPIx中x为1、2、3,用来选择SPI外设;SPI_I2S_FLAG为被检测的标志位,如表6-11所示。

同时库函数中也有对应的SPI数据发送和接收函数,分别为:(固件库手册中所示的发送和接收函数有误,实际以本文为准)

SPI_I2S_SendData(SPI_TypeDef* SPIx, uint16_t Data);//SPI发送函数

SPI_I2S_ReceiveData(SPI_TypeDef* SPIx);//SPI接收函数

SPI使用查询方式发送和接收数据时,在发送和接收数据之前需要检测相应标志位,然后再调用库函数发送或者接收数据,这样操作虽然方便,但是由于函数相互调用会占用时间,当传输数据量较大时会降低SPI整体传输效率。为了提高SPI的整体传输效率,本文采用寄存器方式操作。另外SPI在接收从机数据时,由于从机自身不产生时钟信号(SCK),通信时需要主机提供SCK以启动数据传输,因此主机需要通过发送的数据来提供SCK并接收从机的数据,发送的数据并不生效。

以下是配置SPI2为主模式,8位数据格式,CPOL=1,CPHA=1,波特率2分频,MSB先行,不使用CRC校验,使用时可根据具体要求进行修改。由于SPI外设挂载了多个从机设备,为了方便移植,初始化SPI时并未设置片选引脚,而是选择将片选引脚与SPI从设备放在一起配置,具体代码如下:

6.9 SPI读写Flash存储芯片——W25Q128

6.9.1 W25Q128简介

Flash是一种掉电不丢数据的非易失存储设备,生活中常见的闪存存储设备包块固态硬盘、U盘、SD卡以及单片机内部的存储设备等。Flash具有存储空间更大,读取速率快、可靠性高等特点。本节所要介绍的W25Q128就是Flash的一种,只不过它是以芯片的形式存在。 W25Q128是华邦公司推出的一款SPI接口的NOR Flash芯片,其存储空间为128Mbit,相当于16M字节。W25Q128可以支持SPI的模式0和模式3,也就是CPOL=0/CPHA=0和CPOL=1/CPHA=1这两种模式。

往Flash写入数据时,需要注意以下两个重要问题:

1、Flash写入数据时和EEPROM类似,不能跨页写入,一次最多写入一页,W25Q128的一页是256字节。写入数据一旦跨页,必须在写满上一页的时候,等待Flash将数据从缓存搬移到非易失区,重新再次往里写。

2、Flash有一个特点,就是可以将1写成0,但是不能将0写成1,要想将0写成1,必须进行擦除操作。因此通常要改写某部分空间的数据,必须首先进行一定物理存储空间擦除,最小的擦除空间,通常称之为扇区,扇区擦除就是将这整个扇区每个字节全部变成0xFF。每款Flash的扇区大小不一定相同,W25Q128的一个扇区是4096字节。为了提高擦除效率,使用不同的擦除指令还可以一次性进行32K(8个扇区)、64K(16个扇区)以及整片擦除。

Kingst-32F1开发板中W25Q128对应的管脚连接关系如图6-10所示。

6.9.2 W25Q128读写操作

W25Q128内部有一个“SPI Command & Control Logic”,可以通过SPI接口向其发送指令,从而执行相应操作。指令的长度是不定的,有单字节的,也有多字节的,W25Qxx一共具有34个操作指令,在此只列举常用的12个,具体如表6-13所示。

下面将对W25Q128的常用操作方式进行介绍。

1、只发送指令——写使能、写失能

写使能是指状态寄存器中的WEL位置1(发送写使能指令后硬件自动设置),失能就是清零操作。在发送页写,扇区擦除,块擦除,片擦除,写状态寄存器,擦写安全寄存器指令之前,必须先等待WEL 位置1 ,这些操作完成后,WEL会自动硬件清零。写失能是将状态寄存器中的WEL软件清零,写失能这个操作很少用到,大多数情况都是硬件自动完成。

根据SPI的操作时序,将指令(06h或04h)通过DI(MOSI)发送给W25Q128,期间DO(MISO)处于高阻状态,时序图如图6-11和图6-12所示。

图6-13 写使能时序

图6-14 写失能时序

2、发送指令,返回数据——读状态寄存器

读状态寄存器指令允许读8位状态寄存器位。读状态寄存指令在任何时间都可使用,可以用05H/35H/15H分别读取W25Q128的三个状态寄存器。实际上用的最多的只有05H读取状态寄存器1的第0位(BUSY位),用来查看相应指令周期是否结束,芯片是否可以接收新的指令。

根据SPI的操作时序,将指令05H通过DI发送,而后通过DO读回状态寄存器的值,时序图如图6-15所示。注意通常我们只读一个字节,时序图后续字节为芯片备用扩展的。

图6-15 读状态寄存器时序图

3、发送指令+数据——写状态寄存器

写状态寄存器的作用主要实现对Flash某些区域的数据或者状态保护,一旦写入保护状态,在状态解除之前,这块区域是禁止写入和擦除的。这部分在本教程中没有应用,有兴趣的读者可以根据时序图和手册资料了解一下,时序图如图6-16所示。

图6-16 写状态寄存器时序图

4、读数据

读数据指令允许从存储器读一个字节和连续多个字节。

首先要确认BUSY位为0,然后根据SPI的操作时序,首先写入指令代码03H,而后紧跟3个字节的地址。当W25Q128收到地址后,会将相应地址处的数据根据SPI时序输出来;如果连续读多个字节,那每经过8个时钟周期地址自动加1,并且输出相应数据,一直到CS拉高,时序图如图6-17所示。

图6-17 读数据时序图

5、写入数据(页编程)

W25Q128一次写入的数据只能小于等于256字节,并且不能一次性跨页写入。当遇到跨页时,应先写满一页,等待BUSY位为0,再次往下一页写。(如果写满一页继续往下写则会跳到缓存区的页首位置开始写,之前数据会被覆盖)

在写入数据之前,该页必须被擦除过,然后根据写入地址和写入的字节数计算是否跨页以及页数。根据SPI的操作时序,首先通过写使能将WEL置1,然后写入指令代码02H,而后紧跟着3个字节的地址,而后接着发送要存储的数据,时序图如图6-18所示。

图6-18 页编程时序图

写入数据完毕后,W25Q128将数据从缓存搬移到非易失区所消耗的时间要了解一下,在手册的84页有介绍,大概是(30+(x-1)*2.5)us ~ (50+(x-1)*12) us之间(x为写入的字节),搬移完成后,WEL位会自动清零,BUSY自动清零。

6、扇区擦除、块擦除

可以使用20H、52H和D8H分别对扇区擦除、32K块擦除和64K块擦除。根据SPI的操作时序,在写入擦除指令之前首先通过写使能将WEL置1,然后写入指令代码20H/52H/D8H中的一个,而后紧跟着3个字节的擦除首地址。

地址发送完毕后,必须将CS拉高,擦除指令才开始执行,并且需要一定的擦除时间,在这个时间内,只能读状态寄存器,其他操作均不能进行。扇区、32K块和64K的擦除典型时间分别是100ms、120ms和150ms,最大时间分别是400ms、1.6s、2s。当擦除完成,WEL和BUSY位自动清零,就可以再次接收新的操作指令,时序图如图6-19所示。

图6-19 扇区和块擦除时序图

7、全片擦除

可以使用C7H/60H指令对整片进行擦除操作。根据SPI的操作时序,在写入擦除指令之前首先通过写使能将WEL置1,然后写入指令代码C7H或者60H,发送完毕拉高CS后,擦除指令开始执行。

整片擦除过程中,只能读状态寄存器,其他操作均不能进行。整片擦除的典型时间是40秒,最大时间是200秒。当擦除完成后,WEL和BUSY位自动清零,就可以再次接收新的操作指令,时序图如图6-20所示。

图6-20 全片擦除时序图

接下来根据W25Q128的时序编写驱动程序,该驱动文件可以驱动W25Qxx系列的Flash存储芯片,不同型号的ID不同,W25Qxx初始化时会通过判断芯片ID来识别是否通信成功。

6.9.3 串口控制Flash读写实验

由于Flash与EEPROM实现的功能类似,本节通过改写串口发送指令控制EEPROM读写数据的例程,设计了串口发送指令控制Flash读写。帮助大家更好的体会串口实用例程以及Flash读写流程。

Flash读数据指令格式:“f-read 地址 字节长度”,其中地址范围为0~16*1024*1024,e2read、地址、字节长度之间由空格隔开,比如从地址1开始读取5字节数据:f-read 1 5。单片机收到指令后执行多字节读操作,通过串口助手返回读出的数据。

Flash写数据指令格式:“f-write 地址 数据”,地址范围为0~16*1024*1024,f-write、地址、数据之间同样由空格隔开,比如从地址1开始写入hello:f-write 1 hello。单片机收到指令后执行多字节写操作,写入成功后通过串口助手返回“f-write done.”

如果发送指令格式错误,返回“bad parameter.”,如果发送指令错误,将返回发送的数据。由于程序中设定的串口接收和发送缓冲区最大为256字节,因此该实验单次读取或者写入的字节数应小于256字节。

6.10 使用逻辑分析仪测试SPI信号

当进行SPI通信出现异常时,可以通过逻辑分析仪进行通信时序上的问题查找,如图6-18所示。从图上可以看出SCK空闲时是高电平,即CPOL=1;从CLK的跳沿箭头上可以看出,是后沿读取数据,即CPHA=1。数据分析可以通过MISO和MOSI解析后的数据判断出。通过分析仪的数据解析功能,可以直观看到STM32与Flash之间的通信数据,从而进一步确定问题所在。

图6-21 Kingst LA5016逻辑分析仪解析SPI数据

长按识别关注

知识共享|助力梦想

spi与iic有什么不同3

IIC总线协议:

I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。

SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出.需通过上拉电阻接电源VCC.当总线空闲时.两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路.在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接有一定的等效电容.而线路中电容会影响总线传输速度.当电容过大时,有可能造成传输错误.所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。

主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件.在总线上主和从、发和收的关系不是恒定的,而取决于此时数据传送方向。如果主机要发送数据给从器件,则主机首先寻址从器件,然后主动发送数据至从器件,最后由主机终止数据传送;如果主机要接收从器件的数据,首先由主器件寻址从器件.然后主机接收从器件发送的数据,最后由主机终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。

SPI总线协议:

SPI是串行外设接口(Serial Peripheral Interface)的缩写。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,正是出于这种简单易用的特性,如今越来越多的芯片集成了这种通信协议,比如AT91RM9200。

?232通信协议:

RS-232是串行数据接口标准,最初都是由电子工业协会(EIA)制订并发布的,RS-232在1962年发布,命名为EIA-232-E,作为工业标准,以保证不同厂家产品之间的兼容。RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也可以接工业仪器仪表。用于驱动和连线的改进,实际应用中RS-232的传输长度或者速度常常超过标准的值。RS-232只限于PC串口和设备间点对点的通信。RS-232串口通信最远距离是50英尺。

422通信协议:

RS-422标准全称是“平衡电压数字接口电路的电气特性”,它定义了接口电路的特性。实际上还有一根信号地线,共5根线。由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。接收器输入阻抗为4k,故发端最大负载能力是10×4k+100Ω(终接电阻)。

485通信协议:

RS-485(EIA-485标准)是RS-422的改进,因为它增加了设备的个数,从10个增加到32个,同时定义了在最大设备个数情况下的电气特性,以保证足够的信号电压。有了多个设备的能力,你可以使用一个单个RS-485口建立设备网络。出色抗噪和多设备能力,在工业应用中建立连向PC机的分布式设备网络、其他数据收集控制器、HMI或者其他操作时,串行连接会选择RS-485。RS-485是RS-422的超集,因此所有的RS-422设备可以被RS-485控制。RS-485可以用超过4000英尺的线进行串行通行。

TCP/IP协议:

TCP/IP是一个协议族,是因为TCP/IP协议包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等许多协议,这些协议一起称为TCP/IP协议。

发表评论