UART、SPI、IIC是经常用到的几个数据传输标准,下面分别总结一下:

UART(Universal Asynchronous Receive Transmitter):也就是我们经常所说的串口,基本都用于调试。

主机和从机至少要接三根线,RX、TX和GND。TX用于发送数据,RX用于接受数据(收发不是一根线,所以是全双工方式)。注意A和B通信A.TX要接B.RX,A.RX要接B.TX(A用TX发B当然要用RX来收了!)

如果A是PC机,B是单片机,A和B之间还要接一块电平转换芯片,用于将TTL/CMOS(单片机电平)转换为RS232(PC机电平)。因为TTL/CMOS电平范围是0~1.8/2.5/3.3/5V(不同单片机范围不同),高电压表示1,低电压表示0。而RS232逻辑电平范围-12V~12V,-5~-12表示高电平,+5~+12V表示低电平(对!你没有听错)。为什么这么设置?这就要追溯到调制解调器出生时代了,有兴趣自己去查资料!

数据协议:以PC机A给单片机B发数据为例(1为高电平,0为低电平):A.TX to B.RX。刚开始B.RX的端口保持1,当A.TX发来一个0作为起始位告诉B我要发数据了!然后就开始发数据,发多少呢?通常一次是5位、6位、7位、8位,这个双方事先要用软件设置好。PC机一般会用串口助手设置,单片机会在uart的驱动中设置。一小帧数据发送完了以后,A.TX给个高电平告诉B.RX我发完了一帧。如果还有数据,就再给个0然后重复上一步。如果双方约定由校验位,还要在发停止位1之前发送个校验位,不过现在一般都不需要校验位了,因为出错的概率太小了,而且一般用于调试。

一般在串口助手上还有个RTS/CTS流控选项,也叫握手,我从来没用过。搬一段我能理解的介绍:RTS(请求发送),CTS(清除发送)。如果要用这两个功能,那就至少要接5根线:RX+TX+GND+RTS+CTS。当A要发送数据时,置RTS有效(可能是置1),告诉B我要发送数据了。当B准备好接受数据后,置CTS有效,告诉A你可以发了。然后他们就实现了两次握手!挺耽误时间是不是?这个RTS还可以当电源使用,如果你不用它的握手功能,且电源电流在50mA以下时,就可以把它置为高电平可以当电源用喔~!

SPI(Serial Peripheral Interface, 同步外设接口)是由摩托罗拉公司开发的全双工同步串行总线,该总线大量用在与EEPROM、ADC、FRAM和显示驱动器之类的慢速外设器件通信。

SPI是一种串行同步通讯协议,由一个主设备和一个或多个从设备组成,主设备启动一个与从设备的同步通讯,从而完成数据的交换。SPI 接口由SDI(串行数据输入),SDO(串行数据输出),SCK(串行移位时钟),CS(从使能信号)四种信号构成,CS 决定了唯一的与主设备通信的从设备,片选信号低电平有效。如没有CS 信号,则只能存在一个从设备,主设备通过产生移位时钟来发起通讯。通讯时,数据由SDO 输出,SDI 输入,数据在时钟的上升或下降沿由SDO 输出,在紧接着的下降或上升沿由SDI 读入,这样经过8/16 次时钟的改变,完成8/16 位数据的传输。

IIC(Inter Integrated Circuit):两根线:一个时钟线SCL和一个数据线SDA。只有一根数据线,所以是半双工通信。接线不难,而且两根线上也可以挂很多设备(每个设备的IIC地址不同),数据协议比较麻烦:

还是假设A给B发数据(这里A.SCL接B.SCL, A.SDA接B.SDA)。起初SDA和SCL上的电平都为高电平。然后A先把SDA拉低,等SDA变为低电平后再把SCL拉低(以上两个动作构成了iic的起始位),此时SDA就可以发送数据了,与此同时,SCL发送一定周期的脉冲(周期和PCLK有关,一般会在IIC的控制寄存器中设置)。SDA发送数据和SCL发送脉冲的要符合的关系是:SDA必须在SCL是高电平是保持有效,在SCL是低电平时发送下一位(SCL会在上升沿对SDA进行采样)。规定一次必须传8位数据,8位数据传输结束后A释放SDA,但SCL再发一个脉冲(这是第九个脉冲),这会触发B通过将SDA置为低电平表示确认(该低电平称为ACK)。最后SCL先变为高电平,SDA再变为高电平(以上两个动作称为结束标志)如果B没有将SDA置为0,则A停止发送下一帧数据。IIC总线(即SDA和SCL)上的每个设备都有唯一地址,数据包传输时先发送地址位,接着才是数据。一个地址字节由7个地址位(可以挂128个设备)和1个指示位组成(7位寻址模式)。指示位是0表示写,1表示读。还有10位寻址模式,使用两个字节来保存地址,第一个字节的最低两位和第二个字节的8位合起来构成10位地址。

在I2C总线的应用中应注意的事项总结为以下几点 : 
1) 严格按照时序图的要求进行操作, 
2) 若与口线上带内部上拉电阻的单片机接口连接,可以不外加上拉电阻。 
3) 程序中为配合相应的传输速率,在对口线操作的指令后可用NOP指令加一定的延时。 
4) 为了减少意外的干扰信号将EEPROM内的数据改写可用外部写保护引脚(如果有),或者在EEPROM内部没有用的空间写入标志字,每次上电时或复位时做一次检测,判断EEPROM是否被意外改写。

关于IIC总线的操作注意事项

1、对IIC总线的一次操作完之后,需要等待一段时间才能进行第二次操作。否则是启动不了总线的:)
2、在时钟线(SCL)为高电平的时候,一定不能动数据线(SDA)状态,除非是启动或者结束总线

2、UART, SPI, IIC的区别与联系:

第一个区别当然是名字:

UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)
SPI(Serial Peripheral Interface:串行外设接口);
I2C(INTER IC BUS)

第二,区别在电气信号线上:

SPI总线由三条信号线组成:串行时钟(SCLK)、串行数据输出(SDO)、串行数据输入(SDI)。SPI总线可以实现 多个SPI设备互相连接。提供SPI串行时钟的SPI设备为SPI主机或主设备(Master),其他设备为SPI从机或从设备(Slave)。主从设备间可以实现全双工通信,当有多个从设备时,还可以增加一条从设备选择线。
如果用通用IO口模拟SPI总线,必须要有一个输出口(SDO),一个输入口(SDI),另一个口则视实现的设备类型而定,如果要实现主从设备,则需输入输出口,若只实现主设备,则需输出口即可,若只实现从设备,则只需输入口即可。

I2C总线是双向、两线(SCL、SDA)、串行、多主控(multi-master)接口标准,具有总线仲裁机制,非常适合在器件之间进行近距离、非经常性的数据通信。在它的协议体系中,传输数据时都会带上目的设备的设备地址,因此可以实现设备组网。
如果用通用IO口模拟I2C总线,并实现双向传输,则需一个输入输出口(SDA),另外还需一个输出口(SCL)。(注:I2C资料了解得比较少,这里的描述可能很不完备)

UART总线是异步串口,因此一般比前两种同步串口的结构要复杂很多,一般由波特率产生器(产生的波特率等于传输波特率的16倍)、UART接收器、UART发送器组成,硬件上由两根线,一根用于发送,一根用于接收。
显然,如果用通用IO口模拟UART总线,则需一个输入口,一个输出口。

第三,从第二点明显可以看出,SPI和UART可以实现全双工,但I2C不行;

第四,看看牛人们的意见吧!

wudanyu:I2C线更少,我觉得比UART、SPI更为强大,但是技术上也更加麻烦些,因为I2C需要有双向IO的支持,而且使用上拉电阻,我觉得抗干扰能力较弱,一般用于同一板卡上芯片之间的通信,较少用于远距离通信。SPI实现要简单一些,UART需要固定的波特率,就是说两位数据的间隔要相等,而SPI则无所谓,因为它是有时钟的协议。
quickmouse:I2C的速度比SPI慢一点,协议比SPI复杂一点,但是连线也比标准的SPI要少。

UART一帧可以传5/6/7/8位,IIC必须是8位。IIC和SPI都从最高位开始传。

SPI用片选信号选择从机,IIC用地址选择从机。

速率与传输距离

SPI 速率与芯片有关,有的400K,有的到几兆;
rs232速率一般最大115200;
iic一般应用400K,CAN最高可到1M;
spi和iic一般应用在芯片之间通讯,RS232可应用与设备与设备之间短距离通讯,最大15米,CAN适用设备间通讯,抗干扰能力强,理论上通讯距离可到10KM

UART, SPI, IIC的详解及三者的区别和联系的更多相关文章

  1. 第十六章 IIC协议详解+UART串口读写EEPROM

    十六.IIC协议详解+Uart串口读写EEPROM 本文由杭电网友曾凯峰根据小梅哥FPGA IIC协议基本概念公开课内容整理并最终编写Verilog代码实现使用串口读写EEPROM的功能. 以下为原文 ...

  2. SPI总线协议及SPI时序图详解

    SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚 ...

  3. SPI总线协议及SPI时序图详解【转】

    转自:https://www.cnblogs.com/adylee/p/5399742.html SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接 ...

  4. Java SPI机制实战详解及源码分析

    背景介绍 提起SPI机制,可能很多人不太熟悉,它是由JDK直接提供的,全称为:Service Provider Interface.而在平时的使用过程中也很少遇到,但如果你阅读一些框架的源码时,会发现 ...

  5. IIC通信协议详解

    IIC通信详解 IIC概述 IIC:两线式串行总线,它是由数据线SDA和时钟线SCL构成的串行总线,可发送和接收数据. 在CPU与被控IC之间.IC与IC之间进行双向传送,高速IIC总线一般可达400 ...

  6. [转帖]详解shell脚本括号区别--$()、$「 」、$「 」 、$(()) 、「 」 、「[ 」]

    详解shell脚本括号区别--$().$「 」.$「 」 .$(()) .「 」 .「[ 」] 原创 波波说运维 2019-07-31 00:01:00 https://www.toutiao.com ...

  7. 详解JDBC与Hibernate区别

    详解JDBC与Hibernate区别 引用地址:http://www.cnblogs.com/JemBai/archive/2011/04/13/2014940.html 刚开始学习JAVA时,认为H ...

  8. UART、SPI和I2C详解

    做单片机开发时UART,SPI和I2C都是我们最经常使用到的硬件接口,我收集了相关的具体材料对这三种接口进行了详细的解释. UART UART是一种通用串行数据总线,用于异步通信.该总线双向通信,可以 ...

  9. String详解, String和CharSequence区别, StringBuilder和StringBuffer的区别 (String系列之1)

    本章主要介绍String和CharSequence的区别,以及它们的API详细使用方法. 转载请注明出处:http://www.cnblogs.com/skywang12345/p/string01. ...

随机推荐

  1. Spring Security(二)

    Spring Security(二) 注:凡是源码部分,我已经把英文注释去掉了,有兴趣的同学可以在自己项目里进去看看.:-) 定义用户认证逻辑 用户登录成功后,用户的信息会被 Security 封装在 ...

  2. spring中获取ApplicationContext对象的技巧,含源码说明

    第一步,实现接口ApplicationContextAware,重写setApplicationContext方法,下方代码标红的地方,绿色部分 可以通过声明来进行存储到本类中. @Component ...

  3. django项目一 分页器(前端分页和后端分页区别)

    1. 客户信息展示 1. 母版和继承 {% extends 'layout'%} {% load static%} {% static '文件路径' %} block css js content 2 ...

  4. python学习之老男孩python全栈第九期_day009知识点总结

    '''# len# 计算字符串的长度# s = '金老板小护士'# len(s)# 不能用 len 怎么办#low一点的方法# count = 0# for i in s:# count += 1# ...

  5. IIS8发布Asp.net MVC程序后出现404错误,处理程序staticFile

    新部署的虚拟机,运行Asp.net MVC程序,出现如下图错误: 解决方法: 添加功能和角色->添加角色->Web服务器IIS->应用程序开发->Asp.net3.5 /Asp ...

  6. T-SQL的timestamp类型实际应用

    目录 0x00 适用场景 0x01 问题描述 0x02 字节数组 0x03 Base64编码 0x04 其实没那么麻烦 0x05 回顾 0x00 适用场景 1. 前端: JavaScript 2. 后 ...

  7. Visual Studio 2012 Update 1 离线升级包(相当于VS2012 SP1离线补丁包)

    Visual Studio 2012 Update 1 发布也有一段时间了,吾乐吧尝试了好几次在线升级,但是网络不给力啊,结果都失败了.于是一直都想找到官方提供的VS2012 SP1完整离线升级包,不 ...

  8. Python之生成器(generator)和迭代器(Iterator)

    generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用y ...

  9. 反射式DLL注入--方法

    使用RWX权限打开目标进程,并为该DLL分配足够大的内存. 将DLL复制到分配的内存空间. 计算DLL中用于执行反射加载的导出的内存偏移量. 调用CreateRemoteThread(或类似的未公开的 ...

  10. Nginx服务器报 "Too Many Open Files"

    近日服务器上的运行的一个站点经常性出现500错误.查了下服务器负载,负载正常.而后查询了下nginx记录的站点运行错误日志,发现提示Too many open files.因为站点静态文件居多,而且h ...