目录:

一、SPI总线协议

1、什么是SPI

2、技术性能

3、接口定义与硬件连接

4、内部结构

5、传输时序

6、高速SPI

1)硬件电路   2)1MHz SPI传输问题

二、I2C总线协议

1、I2C总线协议

2、程序

三、存储器的分类

附录1、小小串联电阻,大大的作用

-----------------------------------------------------------------------------------------------------------

一、SPI总线协议

1、什么是SPI

SPI是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口。SPI是一种高速的、全双工、同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间、提供方便。正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议。
SPI是一个环形总线结构,由ss(cs)、sck、sdi、sdo构成,其时序其实很简单,主要是在sck的控制下,两个双向移位寄存器进行数据交换。上升沿发送、下降沿接收、高位先发送。

上升沿到来的时候,sdo上的电平将被发送到从设备的寄存器中。
下降沿到来的时候,sdi上的电平将被接收到主设备的寄存器中。

假设主机和从机初始化就绪:并且主机的sbuff=0xaa (10101010),从机的sbuff=0x55 (01010101),下面将分步对spi的8个时钟周期的数据情况演示一遍(假设上升沿发送数据)。

这样就完成了两个寄存器8位的交换,上面的0--1表示上升沿、1--0表示下降沿,sdi、 sdo相对于主机而言的。根据以上分析,一个完整的传送周期是16位,即两个字节,因为,首先主机要发送命令过去,然后从机根据主机的命令准备数据,主机在下一个8位时钟周期才把数据读回来。
SPI总线是Motorola公司推出的三线同步接口,同步串行3线方式进行通信:一条时钟线SCK,一条数据输入线MOSI,一条数据输出线MISO;用于 CPU与各种外围器件进行全双工、同步串行通讯。

SPI主要特点有:可以同时发出和接收串行数据;可以当作主机或从机工作;提供频率可编程时钟;发送结束中断标志;写冲突保护;总线竞争保护等。

SPI总线有四种工作方式(SP0, SP1, SP2, SP3),其中使用的最为广泛的是SPI0和SPI3方式

SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置,时钟极性(CPOL即Clock Polarity的缩写)对传输协议没有重大的影响。如果CPOL=0,串行同步时钟的空闲状态为低电平;如果CPOL=1,串行同步时钟的空闲状态为高电平。时钟相位(CPHA即Clock Phase的缩写)能够配置用于选择两种不同的传输协议之一进行数据传输。如果 CPHA=0,在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样。 SPI主模块和与之通信的外设时钟相位和极性应该一致。

SPI时序图详解-SPI接口在模式0下输出第一位数据的时刻

SPI接口在模式0下输出第一位数据的时刻

SPI接口有四种不同的数据传输时序,取决于CPOL和CPHL这两位的组合。图1中表现了这四种时序,时序与CPOL、CPHL的关系也可以从图中看出。

图1

CPOL是用来决定SCK时钟信号空闲时的电平,CPOL=0,空闲电平为低电平,CPOL=1时,

空闲电平为高电平。CPHA是用来决定采样时刻的,CPHA=0,在每个周期的第一个时钟沿采样,

CPHA=1,在每个周期的第二个时钟沿采样。

由于我使用的器件工作在模式0这种时序(CPOL=0,CPHA=0),所以将图1简化为图2,
只关注模式0的时序。

图2

我们来关注SCK的第一个时钟周期,在时钟的前沿采样数据(上升沿,第一个时钟沿),在时钟的后沿输出数据(下降沿,第二个时钟沿)。首先来看主器件,主器件的输出口(MOSI)输出的数据bit1,在时钟的前沿被从器件采样,那主器件是在何时刻输出bit1的呢?bit1的输出时刻实际上在SCK信号有效以前,比 SCK的上升沿还要早半个时钟周期。bit1的输出时刻与SSEL信号没有关系。再来看从器件,主器件的输入口MISO同样是在时钟的前沿采样从器件输出的bit1的,那从器件又是在何时刻输出bit1的呢。
从器件是在SSEL信号有效后,立即输出bit1,尽管此时SCK信号还没有起效关于上面的主器件
和从器件输出bit1位的时刻,可以从图3、4中得到验证。

图3

注意图3中,CS信号有效后(低电平有效,注意CS下降沿后发生的情况),故意用延时程序延时了一段时间,之后再向数据寄存器写入了要发送的数据,来观察主器件输出bit1的情况(MOSI)。
可以看出,bit1(值为1)是在SCK信号有效之前的半个时钟周期的时刻开始输出的(与CS信号无关),到了SCK的第一个时钟周期的上升沿正好被从器件采样。

图4

图4中,注意看CS和MISO信号。我们可以看出,CS信号有效后,从器件立刻输出了bit1(值为1)。

通常我们进行的spi操作都是16位的。图5记录了第一个字节和第二个字节间的相互衔接的过程。
第一个字节的最后一位在SCK的上升沿被采样,随后的SCK下降沿,从器件就输出了第二个字节的第一位。

SPI总线协议介绍(接口定义,传输时序)

-----------------------------------------------------------

2、技术性能
SPI接口是Motorola 首先提出的全双工三线同步串行外围接口,采用主从模式(Master Slave)架构;支持多slave模式应用,一般仅支持单Master。
时钟由Master控制,在时钟移位脉冲下,数据按位传输,高位在前,低位在后(MSB first);SPI接口有2根单向数据线,为全双工通信,目前应用中的数据速率可达几Mbps的水平。
-----------------------------------------------------------

3、接口定义与硬件连接
SPI接口共有4根信号线,分别是:CS设备选择线、SCK时钟线、SDO串行输出数据线、SDI串行输入数据线。

(1)MOSI:主器件数据输出,从器件数据输入
(2)MISO:主器件数据输入,从器件数据输出
(3)SCLK :时钟信号,由主器件产生
(4)/SS:从器件使能信号,由主器件控制

-----------------------------------------------------------
4、内部结构

-----------------------------------------------------------

5、传输时序

SPI接口在内部硬件实际上是两个简单的移位寄存器,传输的数据为8位,在主器件产生的从器件使能信号和移位脉冲下,按位传输,高位在前,低位在后。如下图所示,在SCLK的下降沿上数据改变,上升沿一位数据被存入移位寄存器。

SPI接口没有指定的流控制,没有应答机制确认是否接收到数据。

-----------------------------------------------------------

6、高速SPI

1)硬件电路

高速信号的判定:https://blog.csdn.net/liht_1634/article/details/124471496。

信号线和时钟线串电阻:高速信号一般在电路的终端串接小电阻用于阻抗的匹配,TTL信号阻抗约13,串接33Ω即可,防信号完整性问题。另可参见:附录1、小小串联电阻,大大的作用

---------------------------------

2)1MHz SPI传输问题

蓝色SCK、紫色或黄色MISO,如下图所示。SCK下降沿时,MISO有过冲且振铃。 这是一个强烈的EMI源。

降低传输速率至500KHz,过冲基本消失。初步判断为串扰所致,尝试硬件上去解决,无果。

最终处理方式:固件上在SCK上升沿采样MISO,即可规避过冲的影响。

MISO串联电阻:

关于串扰另可参看:https://blog.csdn.net/liht_1634/article/details/127325345。

-----------------------------------------------------------------------------------------------------------

二、I2C总线协议

1、I2C总线协议

2条双向串行线,一条数据线SDA,一条时钟线SCL。
SDA传输数据是大端传输,每次传输8bit,即一字节。
支持多主控(multimastering),任何时间点只能有一个主控。
总线上每个设备都有自己的一个addr,共7个bit,广播地址全0.
系统中可能有多个同种芯片,为此addr分为固定部分和可编程部份,细节视芯片而定,看datasheet。

1.1 I2C位传输
数据传输:SCL为高电平时,SDA线若保持稳定,那么SDA上是在传输数据bit;
若SDA发生跳变,则用来表示一个会话的开始或结束(后面讲)
数据改变:SCL为低电平时,SDA线才能改变传输的bit

1.2 I2C开始和结束信号
开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据。
结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据。

1.3 I2C应答信号

Master每发送完8bit数据后等待Slave的ACK
即在第9个clock,若从IC发ACK,SDA会被拉低。
若没有ACK,SDA会被置高,这会引起Master发生RESTART或STOP流程,如下所示:

1.4 I2C写流程
写寄存器的标准流程为:
1. Master发起START
2. Master发送I2C addr(7bit)和w操作0(1bit),等待ACK
3. Slave发送ACK
4. Master发送reg addr(8bit),等待ACK
5. Slave发送ACK
6. Master发送data(8bit),即要写入寄存器中的数据,等待ACK
7. Slave发送ACK
8. 第6步和第7步可以重复多次,即顺序写多个寄存器
9. Master发起STOP

写一个寄存器 写多个寄存器 1.5 I2C读流程

读寄存器的标准流程为:
1. Master发送I2C addr(7bit)和w操作1(1bit),等待ACK
2. Slave发送ACK
3. Master发送reg addr(8bit),等待ACK
4. Slave发送ACK
5. Master发起START
6. Master发送I2C addr(7bit)和r操作1(1bit),等待ACK
7. Slave发送ACK
8. Slave发送data(8bit),即寄存器里的值
9. Master发送ACK
10. 第8步和第9步可以重复多次,即顺序读多个寄存器

读一个寄存器 读多个寄存器

-----------------------------------------------------------

2、程序

$include (IicSMasU.inc)
public _IicTxdRxd
public SlvAddr
public SubAddr

BitSegIicSM SEGMENT BIT overlayable
RSEG BitSegIicSM
Retry: dbit 1 ;指明I2C 最后的数据传送失败应该重复操作
BITEA: DBIT 1 ;存中断状态
DataSegIicSM SEGMENT DATA overlayable
RSEG DataSegIicSM
SlvAddr: ds 1 ;被控器地址
SubAddr: ds 1 ;单元地址
TxdByte equ r7 ;要发送数据的字节数(第一传递参数)
RxdByte equ r5 ;要接收数据的字节数(第二传递参数)
WaitXTm macro X ;延时X 个机器周期
if X=0
exitm
endif
if X=1
nop
endif
if X=2
nop
nop
endif
if X=3
nop
nop
nop
endif
if X>255
error "the number of X is too much"
else
mov r6,#X/2
DJNZ r6,$
endif

endm
CodeSegIicSM SEGMENT CODE
RSEG CodeSegIicSM
_IicTxdRxd:
SETB Retry ;设置错误标志位

SendStart:
SETB SDA
SETB SCL
WaitXTm IicDelay
CLR SDA ;产生起始信号
WaitXTm IicDelay
CLR SCL ;结束起动条件

SendSlaAdr:
MOV A,SlvAddr
CJNE TxdByte,#0,SendSlaAdr1
SETB ACC.0 ;TxdByte=0 时进行读操作
SendSlaAdr1:
SETB C ;检测应答位时释放SDA 线
CALL XmByte
JC IicErr ;无应答出错
JB ACC.0,ReceiveData ;SlaAdr.0=1 时进行读操作
;写操作
MOV A,SubAddr
SendData:
SETB C ;检测应答位时释放SDA 线
CALL XmByte
JC IicErr ;无应答出错
MOV A,@R1
INC R1
DJNZ TxdByte,SendData
DEC R1
MOV A,RxdByte
JNZ SendStart ;RxdByte>0 时进行读操作
JMP SendStop

RcvByte:
MOV A,#0FFH ;释放SDA 线允许输入

XmByte:
MOV R4,#9 ;设置数据格式为8 位+1 位(非)应答位
RXBit:
RLC A ;左移数据
MOV SDA,C ;output data
SETB SCL
MOV C,SDA ;input data
WaitXTm IicDelay
CLR SCL
WaitXTm IicDelay
DJNZ R4,RXBit ;重复操作直到处理完所有数据位
RET
ReceiveData:
MOV A,RxdByte
CJNE A,#2,ReceiveData1 ;RxdByte=1(最后一个字节)时,发送非应答位(C=1)
;否则发送应答位(C=0)
ReceiveData1:
CALL RcvByte
MOV @R1,A
INC R1
DJNZ RxdByte,ReceiveData

SendStop:
CLR Retry ;清除错误标志位
IicErr: ;出错返回
CLR SDA
SETB SCL
WaitXTm IicDelay
SETB SDA
MOV C,Retry ;RETURN ERROR FLAG(C=Retry)
RET
END

C语言声明:
extern bit IicTxdRxd(uchar TxdByte,uchar RxdByte, uchar *IicDataBuf);
//函数定义(程序入口地址)
extern data uchar SlvAddr; //被控器从地址
extern data uchar SubAddr; //单元地址子地址
直接调用即可。

出自:masufang博云天

-----------------------------------------------------------------------------------------------------------

三、存储器的分类

存储产品大概分为E2PROM,NOR,NAND 3类,框架如下:

-----------------------------------------------------------------------------------------------------------

附录1、小小串联电阻,大大的作用

1、SPI信号线

SPI信号上串联电阻,一般是几十欧姆左右,一般有如下几个作用:

1)阻抗匹配。因为信号源的阻抗很低,跟信号线之间阻抗不匹配,串上一个电阻后,可改善匹配情况,以减少反射。

2)SPI的速率较高,串联一个电阻,与线上电容和负载电容构成RC电路,减少信号陡峭,避免过冲,过冲有时候会损坏芯片GPIO,当然对EMI也有好处,尤其是高速电路。

3)调试方便,现在的芯片很多是BGA、QFN封装,串联一个电阻,调试时用示波器抓取波形方便。

-----------------------------------------------------------

2、LDO输入端

当LDO的VIN absolute maximum接近电源电压时,这时候又不想换高规格的LDO,为了节省成本,这时可以串一个小阻值电阻,能吸收一部分电压和电流,当电源端出现更大的浪涌时,电阻会身先士卒,代价更小。

假设LDO击穿,VIN和GND短路,因为串联电阻R的存在,也会避免电源SYS_5V与GND的短路。

-----------------------------------------------------------

3、TVS前后串联电阻

TVS串联电阻一般有两种接法,图A电阻在TVS前,图B电阻在TVS后,两种电路使用场景是不一样的。

1)对图A来说,首先要考虑浪涌大小,如果不大,可以选择一个合适功率的电阻,电阻在TVS前面,会吸收很小一部分的电流,浪涌电流IPP小了之后,对应TVS的Vc(钳位电压)也会变小,对后端负载的保护更好。

2)对图B来说,TVS首先吸收大部分的浪涌电流,部分残压或者残流,会经过电阻R2,进行二次的分压限流,可以更好的保护后端负载。如果后端负载远大于R2,分压限流也就微乎其微了,R2其实也就没啥作用了。

-----------------------------------------------------------------------------------------------------------

SPI与I2C总线协议相关推荐

  1. [I2C]I2C总线协议图解

    转自:http://blog.csdn.net/w89436838/article/details/38660631 1  I2C总线物理拓扑结构       I2C 总线在物理连接上非常简单,分别由 ...

  2. ADXL345经验总结,采用SPI和I2C总线操作

    一. ADXL345简介       ADXL345是ADI公司推出的三轴(x,y,z)iMEMS数字加速度计(digital accelerometer),具有在16G下高分辨率(13Bit)测量能 ...

  3. 总线全称_一篇文章讲透I2C总线协议

    最近一段时间工作上比较忙,一直没有抽出空来写文章与大家分享,这两天腾出些时间静下心来沉淀一番.看标题大家已经知道了是来总结I2C总线,我相信大家或多或少的都接触过I2C总线,这篇文章我们就由浅入深的仔 ...

  4. TM1637芯片使用(I2C总线协议学习),含完整程序

    目录 1.TM1637芯片(大自然的搬运工) 芯片介绍 引脚图 时序图 其他关键 管脚功能 命令格式 封装 2. 51单片机程序编写 I2C_START(): I2C_WR(): I2C_ACK(): ...

  5. i2c总线协议的工作原理详解

    一.概述 1.I2C总线只有两根双向信号线.一根是数据线SDA,另一根是时钟线SCL. SCL:上升沿将数据输入到每个EEPROM器件中:下降沿驱动EEPROM器件输出数据.(边沿触发) SDA:双向 ...

  6. I2C总线协议和控制器解析

    I2C总线协议 1.1 I2C总线知识 1.1.1  I2C总线物理拓扑结构       I2C 总线在物理连接上非常简单,分别由SDA(串行数据线)和SCL(串行时钟线)及上拉电阻组成.通信原理是通 ...

  7. I2C总线协议的verilog实现

    最近一直在学习各种接口,今天要讲的是I2C 总线.I2C是是一种简单的同步串行总线. 它只需要两根线即可在连接于总线上的器件之间传送信息. 主器件用于启动总线传送数据,并产生时钟以开放传送的器件,此时 ...

  8. 浅谈 IIC I2C 总线协议

    简介 IIC(也称I2C或I2C)总线是Philips公司开发的一种简单.双向二线制同步串行总线,是Inter-Integrated Circuit的缩写. IIC只用两条双向线,一条SDA(Seri ...

  9. 对I2C总线协议的一些理解

    1.无论读与写,都是在时钟线为低时把数据送到数据总线上,在高时采样数据,把数据锁存到内部,所以读之前先把时钟线拉低,做好准备(数据线为高表示释放数据线),为接下来读数据做好准备.也就是时钟信号为低时, ...

最新文章

  1. 2018年Github最受欢迎机器学习语言Python稳坐冠军,numpy、scipy是最受欢迎软件包...
  2. 自动驾驶中高精地图的大规模生产:视觉惯导技术在高德的应用
  3. mongodb 查询效率_2020年9个好用的MongoDB 图形化界面工具
  4. 【树链剖分】旅游(luogu 3976)
  5. 云虚拟主机和传统虚拟主机的区别?
  6. python猜词游戏源代码_Python趣味小游戏编写教学
  7. OPPO K3将登陆印度市场 高性价比能否占据一席之地
  8. [220221] Majority Element
  9. java成神之——集合框架之ArrayList,Lists,Sets
  10. 第1节 kafka消息队列:5、javaAPI操作
  11. 图像处理系列——直方图之直方图规定化(Histogram Specification)
  12. 利用dialogArguments进行网页页面传值
  13. VS配置GLAD+GLFW
  14. Serval Project——Android
  15. mac卸载Sophos[即使没有服务端管理员密码]-完整有效彻底
  16. 【DSP】离散系统的因果性判断
  17. Designing an Encoder for StyleGAN Image Manipulation论文解读
  18. 〖ChatGPT实践指南 - 零基础扫盲篇⑤〗- OpenAI API 演示 Demo 之宠物名字生成器
  19. 空调主板电路设计特点
  20. 常用的http状态码 状态码大全 常见的状态码

热门文章

  1. ACM入门及STL简介(转)
  2. 化合物纯度、溶剂溶解度检测
  3. oracle报错1034,oracle数据库登陆报错ora-1034
  4. 支付宝事件溯源:2005年“雅巴“交易再回首
  5. Ubuntu18.04 常用软件推荐
  6. Unity—Mecanim动画系统
  7. 手把手教您JbuliderX+Tomcat5.0的配置
  8. 计算机社团感恩节免费维修周策划书,社团感恩节活动策划书范文 .docx
  9. python读取word内容复制粘贴,Python读取word文本操作详解
  10. Vista和DirectX 10(转载)