解析常用串行总线——UART协议(上)

01
uart基础知识
通用异步收发传输器 (universal asynchronous receiver/transmitter),通常称作uart。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,uart通常被集成于其他通讯接口的连结上。
具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备。一般是rs-232c规格的,与类似maxim的max232之类的标准信号幅度变换芯片进行搭配,作为连接外部设备的接口。在uart上追加同步方式的序列信号变换电路的产品,被称为usart(universal synchronous asynchronous receiver transmitter)。
1.1 早期串行通讯设备
早期的电报机器使用长度可变的脉冲信号(摩斯电码)进行数据传输,后来出现的电传打印机(teleprinters )使用5、6、7或8个数据位来表示各种字符编码。随着电传打印机的普及,最终发展成为计算机外围设备。
由于历史的发展原因,早期在unix终端是一个名字为asr33的电传打字机,而电传打字机的英文单词为teletype(或teletypewritter),缩写为tty。因此,终端设备也被称为tty设备。这就是tty这个名称的来源。
1.2 早期的芯片级uart
dec(digital equipment corporation)公司的gordon bell 为该公司的pdp系列计算机设计了第一个uart,不过体积庞大,uart的线路占据了整个电路板;后来dec将串行线路单元的设计浓缩为早期的uart单芯片,以方便自己使用。西部数据(western digital)公司在1971年左右将其开发为第一个广泛可用的uart单芯片 wd1402a。这是中型集成电路的早期产品。
dec是美国一家计算机公司;western digital是美国计算机硬盘驱动器制造商和数据存储公司。
1.3 现代串行通讯设备
2000年开始,大多数ibm或者相关的计算机都删除了其外部rs232的com端口,将其替换为带宽性能更加出色的usb端口;对于仍然需要rs-232串行com端口的用户,现在通常使用外部usb转uart转换器,常见的有ch340,silicon labs 210x的驱动程序,现在很多处理器和芯片都内置了uart。
02
uart传输协议
2.1 uart协议
在串口通信中,数据在1位宽的单条线路上进行传输,一个字节的数据要分为8次,由低位到高位按顺序一位一位的进行传送,这个过程称为数据的串行化(serialized)过程。由于串口通信是一种异步通信协议,并没有时钟信号随着数据一起传输,而且空闲状态(没有数据传输的状态)的时候,串行传输线为高电平1,所以发送方发送一个字节数据之前会先发送一个低电平0,接收方收到这个低电平0以后就知道有数据要来了,准备开始接收数据从而实现一次通信。串口通信的时序如下图所示:
串口通信的规范如下:
 1. 空闲状态(没有数据传输的状态)下,串行传输线上为高电平1;
 2. 发送方发送低电平0表示数据传输开始,这个低电平表示传输的起始位;
 3. 8-bit的数据位(1 byte)是从最低位开始发送,最高位最后发送;
 4. 数据位的最高位发送完毕以后的下一位是奇偶校验位,这一位可以省略不要,同时,当不发送奇偶校验位的时候接收方也相应的不接收校验位;
 5. 最后一位是停止位,用高电平1表示停止位。
下面以发送字节0x55为例来说明整个的发送过程:
先把0x55转化成二进制为:01010101。显然0x55的最低位bit 0是1,次低位bit 1是0,……..,最高位bit 7是0,由于串口是从最低位开始发送一个字节,所以0x55各个位的发送顺序是1-0-1-0-1-0-1-0,波形如下图所示:
下面在给出一个波形,根据上面的规则也可以很容易判断这是发送字节0x13的波形:
2.1.1 起始位
uart数据传输时在不传输数据时保持在高电平,当开始传输数据时,先发出1bit位宽的低电平,表示数据开始传输,即为起始位。
2.1.2 数据位
数据位包含正在传输的实际数据,位宽可以为4bit到10bit,大多数情况下,数据首先从低有效位发送。
2.1.3 校验位
串口通信中的一种交错方式,通常有偶校验、奇校验、高校验和低校验四种检错方式,没有校验位也是可以的。
偶校验:数据位加上校验位后,“1”的位数应为偶数;
奇校验:数据位加上校验位后,“1”的位数应为奇数;
2.1.4 停止位
在数据发送结束后发送一位高电平用于停止标识。
由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容错性越好,但是数据传输率同时也越慢。
3.1.5 波特率
串口数据的传输速度用波特率(bit/s)进行衡量,常见的波特率有:9600、19200、38400、57600、115200。假设uart配置为1bit起始位,8bit数据位,没有校验位,1bit停止位,那么9600bit/s的波特率可得出每一位数据的时间宽度为:t=1/9600*10=1.04ms,即每个字节(10bit数据)传输需要1.04ms。同理可得各个波特率下数据位传输时间宽度。
2.2 uart传输过程
发送端数据总线将数据包并行传输给发送端uart;发送端uart将起始位、奇偶校验位和停止位添加到数据包中;接收端uart解析数据包数据;接收端uart将所解析的数据传输给接收端数据总线。03
uart代码实现
3.1 uart目标实现功能
设计一个uart发送模块和接收模块,具体要求如下:
设计一个uart发送模块,该模块接收一个8位输入数据并采用uart协议发送,uart 采用10位传输协议,即一位起始位,8位数据位,一位终止位。发送数据时先发低位数据,最后发高位数据。要求波特率为1k。模块的定义如下:module uart_tx (
clk_40k, //clock signal, 40khz
rst_n, //reset signal, active low
din, //the input data which will be sent by the uart module, 8 bit width
send_start,//the start enable signal, active high, the width is one clock period
bit_out //the serial output data
);
设计一个uart接收模块,模块的定义如下:module uart_rx (
clk_40k, //clock signal, 40khz
rst_n, //reset signal, active low
bit_in, //the input serial bit,
dout_vld,//the output valid signal, active high,the dout is valid when this signal is high.
dout //received data, 8 bit width
);
设计一个testbench,对发送模块和接收模块进行测试,测试过程如下,testbench产生一个随机数,然后启动uart_tx模块发送至uart_rx模块,当uart_rx模块接收到有效数据后,自动判断接收的数据是否正确。3.2 verilog代码
1. 发送模块 (uart_tx):
module uart_tx (
clk_40k,//clock signal, 40khz
rst_n, //reset signal, active low
din,//the input data which will be sent by the uart module, 8 bit width
send_start,//the start enable signal, active high, the width is one clock period
bit_out//the serial output data
);
input [7:0] din;
input clk_40k;
input rst_n;
input send_start;
output bit_out;
reg flag;
reg tx_flag;
reg [6:0] cnt;
reg [5:0] tx_cnt;
reg [9:0] din_temp;
//flag: 发送过程flag始终拉高
always @ (posedge clk_40k)
begin
if(~rst_n)
flag <= 1'b0;else if(send_start == 1'b1)
flag <= 1'b1;else if(tx_flag == 1'b1)
flag <= 1'b0;end
//tx_flag: 发送结束tx_flag拉高
always @ (posedge clk_40k)
begin
if(~rst_n)
tx_flag <= 1'b0;else if(flag == 1'b1 && din_temp[0] == 1'b0)
tx_flag <= 1'b1;else if(tx_cnt == 7'd10)
tx_flag <= 1'b0;end
//cnt: 发送数据计数,clk_40k分频至1k波特率对传输数据进行计数
always @ (posedge clk_40k)
begin
if(~rst_n)
cnt <= 7'b0;else if(tx_flag == 1'b1 && cnt != 7'd39)
cnt <= cnt + 1'b1;else
cnt <= 7'b0;end
always @ (posedge clk_40k)
begin
if(~rst_n)
tx_cnt <= 6'b0;else if(tx_flag == 1'b1 && cnt == 7'd39)
tx_cnt <= tx_cnt + 1'b1;else if(tx_flag == 1'b0)
tx_cnt <= 6'b0;end
//din_temp: 8bit数据移位操作,串行输出
always @ (posedge clk_40k)
begin
if(~rst_n)
din_temp <= 10'b1111111111;else if(flag == 1'b1 || send_start == 1'b1)
din_temp <= {1'b1,din,1'b0};else if(tx_flag == 1'b1 && cnt == 7'd39)
din_temp <= {1'b1,din_temp[9:1]};end
assign bit_out = din_temp[0];
endmodule

如何计算共射极放大电路的各个参数
中国半导体行业迎来危机,该如何破解
什么情况下选用工业主板
解读低噪声放大器的指标参数
Linux驱动proc新接口介绍
解析常用串行总线——UART协议(上)
光电耦合器的原理及分类
瑞能股份进一步开拓欧洲市场,最先进的国际储能技术与理念
通过工业互联网平台实现设备综合效率监测及远程维护上下载
物联网设备扩散会有怎样的后果
【电源维修】恒压恒流电源保险丝爆炸后维修流程简述
魅族科技开工领红包长龙: 绕大楼3圈
Graviti获千万美元级Pre-A轮融资 致力于人工智能数据服务平台业务
谷歌Pixel3XL曝光 或在10月9日发布
2018电阻开始全面涨价
vivo发布新款5G手机,曲面钻孔屏+骁龙765G+菱形四摄
DDR仿真和测试完美对应的经典案例
山东首富,居然是做传感器的!
基于OMAP5912处理器实现语音采集系统的设计
ARM微处理器在较新的体系结构中支持哪两种指令集?