UART
参考与引用:UART-WIKI
UART串口协议详解
通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART)是一种异步收发传输器,是电脑硬件的一部分,将数据透过串列通信进行传输。UART通常用在与其他通信接口(如EIA RS-232)的连接上。
具体实物表现为独立的模块化芯片,或是微处理器中的内部周边设备(peripheral)。一般和RS-232C规格的,类似Maxim的MAX232之类的标准信号幅度变换芯片进行搭配,作为连接外部设备的接口。在UART上追加同步方式的串行信号变换电路的产品,被称为USART(Universal Synchronous Asynchronous Receiver Transmitter)。
通信可以是单工、全双工或半双工。
UART帧结构
无奇偶校验位:
空闲状态总线拉高置一
开始传输拉低总线,检测到下降沿进入起始状态,此为起始位
接下来发送一个字节的数据
发送完成后,拉高总线,上升沿为停止位
如果要加上奇偶校验位需要在bit7后面添加1bit的奇偶校验位
具体实现细节
根据波特率需求的不同,设置不同的读bit时长
例如:115200 baudrate在50MHZ时钟频率下,一个时钟周期为20ns
所需的读bit时长就为50_000_000/115200
约等于434个时钟周期
I²C
I²C(Inter-Integrated Circuit)字面上的意思是集成电路之间,它其实是I²C Bus简称,所以中文应该叫集成电路总线,它是一种串行通信总线,使用多主从架构.
其被称为IC沟通的桥梁,速度一般为100K/S,也有400K/S的。最新数据更有1M/S甚至3.4M/S的。因为其小巧的特性,常用在例如 Serial EEPROM/ Tuner/ Demodulator/ MCU/ ADC 等小型IC上
I²C总线上的设备分为Master(主机)和Salve(从机),SCL线只能由主机配置,由主机产生时钟脉冲.
并有最高16位的寻址空间,其参考设计使用7位的寻址空间
传输过程
I²C只使用两条双向漏极开路(Open Drain)线,其中一条线为传输数据的串行资料线(SDA),另一条线是启动或停止传输以及发送时钟序列的串行时脉(SCL)线,这两条线上都有上拉电阻。
了解I²C是怎么传输的,就要从这两条线开始.
基础传输
如下图(此图片来自于24LC04B EEPROM手册)所示:
- 空闲状态:SCL、SDA均拉高
- 开始条件:SCL拉高的情况下,检测到SDA下降沿,之后进入数据传输状态
- 数据传输状态:必须在开始条件之后,此时Master控制SCL产生时钟脉冲,并且在时钟脉冲的高电平期间,对SDA进行采样,这期间SDA必须保持稳定,如果产生了上升沿或者下降沿,就会导致STOP提前,或者再次Start,造成数据传输失真
- 停止条件:当数据传输完成后,SCL上拉,SDA线出现上升沿,即为停止条件,回归空闲状态
以上就是一次简单的传输过程,还是比较简单的
有ACK/NACK的传输
上例只是最简单的一次传输
在实际应用中,这样的传输是不可靠的,因为作为发送方,你是无法得知接收方是否接收到了数据
为了使数据传输更加可靠,就需要引入ACK/NACK来作为应答信号
例如:我们现在要对总线上的一块IC进行寻址,其数据帧格式如下
其中,
S也就是Start Bit,也就是起始条件后的第一个比特
Control Code,这一段是此示例EEPROM手册规定的,为’1010’
Select Bits,这是该EEPROM块选的数据位,前两位无任何意义,可随意设置,最后一位通过设0/1选择不同的存储块
Read/Write Bit,选择接下来的操作是读或者写
最后就是ACK位了,根据规定ACK=0,此位由接收方发出,发送方接收收到接收方的ACK回应后,也就表示数据传输无误
那么可能就有人想问了,如果收到的ACK=1,那怎么办?
在I²C通讯协议中规定,NACK=1,收到该信号,发送方就会进入STOP状态结束发送,或者重新进入Start重新发送.
I²C的读/写操作
好了,现在我们已经了解了基础传输流程以及加上ACK后的传输。现在可以看看读写操作了。
写操作
如下图示例:
单个字节的写入,从开始条件开始,先发送一个Control Byte
之后紧跟着的是一个Byte的字地址,也就是你要写入的Data在EEPROM中的地址,
最后就是Data,一个字节的Data传输完成后进入结束条件终止写入
但是这样一个个写太慢了,所有就引入了页写操作
页写操作和单个写类似,不过里面可以放多个Data,理论上,在一组Start和Stop之间,可以传输无数个比特的数据。
EEPROM会将页写中传输过来的Data放置在一个片上页缓冲器(on-chip page buffer)中
此缓冲器带有一个地址指针(address pointer),根据内置程序,每写入一个字节数据,地址指针自动加1,但是此页缓冲器最多只能存储16个字节的数据,故我们能看到下图最多只能到Data(n+15)。
如果传输的数据过多,例如传输了17个字节的data,那4位的地址指针就会因为溢出重新指向第一个数据所在的地址,造成第1个数据被第17个所覆盖
读操作
读当前地址
因为此示例EEPROM有一个内置的地址计数器,此地址计数器保存着上一次操作接触过的最后一个地址无论上一个操作是读或者写。
这个地址计数器是内置自增的,故,如果当前address是n,欲读下一个地址的值,其对应的地址就应当是n+1。
当EEPROM收到
随机读取
随机读取可以使我们读到任意一个地址的数据
为了实现随机读取数据,需要设置一个地址,主机先发送一个写命令的Control Byte(B0=0),紧接着是字地址
在从机EEPROM返回ACK后,主机紧接着就发送一个读命令的Control Byte(B0=1),以作为接收上一个命令,之后EEPROM就会返回对应地址的data,收到该data后,主机返回一个NACK,结束接收
顺序读取
顺序读取,顺序读取的步骤和随机读取完全一样,唯一的区别就是随机读取在第一个data之后主机应答一个NACK,而顺序读取应答一个ACK,直至读至欲读的最后一个数才应答一个NACK,结束读取