一、UART简介
UART是一种通用串行数据总线,用于异步通信。该总线双向通信,实现全双工传输和接收。
二、UART的通信协议和传输时序
UART 通信 UART 首先将接收到的并行数据转换成串行数据来传输。消息帧从一个低位起始位开始,后面是 7 个或 8 个数据位,一个可用的奇偶位和一个或几个高位停止位。接收器发现开始位时它就知道数据准备发送,并尝试与发送器时钟频率同步。如果选择了奇偶校验,UART 就在数据位后面加上奇偶位。奇偶位可用来帮助错误校验。在接收过程中,UART 从消息帧中去掉起始位和结束位,对进来的字节进行奇偶校验,并将数据字节从串行转换成并行。
UART 传输时序如下图所示:
起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。
数据位:从最低位开始传送,靠时钟定位。
奇偶校验位:资料位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验资料传送的正确性。
停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。
空闲位:处于逻辑“1”状态,表示当前线路上没有资料传送。
三、Verilog实现
由于 UART 是异步传输,没有传输同步时钟。为了能保证数据传输的正确性,UART 采用16 倍数据波特率的时钟进行采样。每个数据有 16 个时钟采样,取中间的采样值,以保证采样不会滑码或误码。一般 UART 一帧的数据位数为 8,这样即使每个数据有一个时钟的误差,接收端也能正确地采样到数据。
3.1 接收程序
`timescale 1ns / 1ps
module uartrx(clk, rx, dataout, rdsig, dataerror, frameerror);
input clk; //采样时钟
input rx; //UART数据输入
output dataout; //接收数据输出
output rdsig; //接收数据有效,高说明接收到一个字节
output dataerror; //数据出错指示
output frameerror; //帧出错指示
reg[7:0] dataout;
reg rdsig, dataerror;
reg frameerror;
reg [7:0] cnt;
reg rxbuf, rxfall, receive;
parameter paritymode = 1'b0;
reg presult, idle;
always @(posedge clk)
begin
rxbuf <= rx;
rxfall <= rxbuf & (~rx);
end
always @(posedge clk)
begin
if (rxfall && (~idle)) //检测到线路的下降沿并且原先线路为空闲,启动接收数据进程
begin
receive <= 1'b1; //开始接收数据
end
else if(cnt == 8'd168) //接收数据完成
begin
receive <= 1'b0;
end
end
/
//使用176个时钟接收一个数据(起始位、8位数据、奇偶校验位、停止位),每位占用16个时钟//
always @(posedge clk)
begin
if(receive == 1'b1)
begin
case (cnt)
8'd0: //0~15个时钟为接收第一个比特,起始位
begin
idle <= 1'b1;
cnt <= cnt + 8'd1;
rdsig <= 1'b0;
end
8'd24: //16~31个时钟为第1个bit数据,取中间第24个时钟的采样值
begin
idle <= 1'b1;
dataout[0] <= rx;
presult <= paritymode^rx;
cnt <= cnt + 8