#学习记录#
1 UART协议介绍
UART全称是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter),它是一种异步收发传输器,是设备之间进行异步通信的关键模块。UART负责处理数据总线和串行口之间的串/并、并/串转换,并规定了帧格式,通信双方只要采用相同的帧格式和波特率,就能在未共享时钟信号的情况下,仅用两根信号线(rx和tx)就可以完成通信过程,因此也称作异步串行通信。
1.1 UART数据传输的格式
UART数据传输帧格式如图1所示。
图1 UART传输帧格式
其中各位的含义如下:
- 起始位:发送1位逻辑0(低电平)开始传输数据。
- 数据位:可以是5~8位的数据,先发低位,再发高位。
- 校验位:奇偶校验,1的位数为偶数(偶校验),1的位数为奇数(奇校验)。
- 停止位:停止位是数据传输结束的标志,1位逻辑1(高电平)。
- 空闲位:空闲时数据线为高电平。
UART通信包括数据位、起始位和停止位。波特率是UART通信中数据传输速率的度量,通常以比特每秒(bps)表示。波特率可以通过设置分频器的值来调整,分频器的值等于系统时钟频率除以期望的波特率。例如,如果系统的时钟是50MHZ,要设置波特率为9600bps,分频器的值应设置为50MHZ/9600bps=5208.333,实际应用中取接近的整数,即5209。
2 UART发送端的verilog描述
2.1 代码
`timescale 1ns / 1ps
//
// Company:
// Engineer:mr-pn-junction
//
// Create Date: 2024/04/21 20:52:15
// Design Name:
// Module Name: uart_tx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module uart_tx(
input clk,
input rst_n,
input start,
input [7:0] data,
output reg rs232_tx,
output reg done
);
reg [7:0] r_data;
reg state;
reg [12:0] baud_cnt;
reg bit_flag;
reg [3:0] bit_cnt;
//=======================r_data=================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
r_data<=8'b0;
else if(start)
r_data<=data;
else
r_data<=r_data;
end
//=====================state==================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
state<=1'b0;
else if(start)
state<=1'b1;
else if(done)
state<=1'b0;
else
state<=state;
end
//======================baud_cnt===================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
baud_cnt<=13'd0;
else if(state)begin
if(baud_cnt==13'd28)
baud_cnt<=13'd0;
else
baud_cnt<=baud_cnt+13'd1;
end
else
baud_cnt<=13'd0;
end
//================bit_flag===========================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_flag<=1'b0;
else if(baud_cnt == 'd1)
bit_flag<=1'b1;
else
bit_flag<=1'b0;
end
//======================bit_cnt===================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
bit_cnt<=4'b0;
else if(bit_flag)
bit_cnt<=bit_cnt+4'd1;
else if(bit_cnt ==4'd10)
bit_cnt<= 4'b0;
else
bit_cnt<=bit_cnt;
end
//============================rs232_tx========================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
rs232_tx<=1'b1;
else if(state)begin
if(bit_flag)begin
case(bit_cnt)
4'd0: rs232_tx<=1'b0;
4'd1: rs232_tx<=r_data[0];
4'd2: rs232_tx<=r_data[1];
4'd3: rs232_tx<=r_data[2];
4'd4: rs232_tx<=r_data[3];
4'd5: rs232_tx<=r_data[4];
4'd6: rs232_tx<=r_data[5];
4'd7: rs232_tx<=r_data[6];
4'd8: rs232_tx<=r_data[7];
4'd9: rs232_tx<=1'b1;
default rs232_tx<=1'b1;
endcase
end
else
rs232_tx<=rs232_tx;
end
else
rs232_tx<=1'b1;
end
//================================done================//
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
done<=1'b0;
else if(bit_flag &&(bit_cnt == 4'd9))
done<=1'b1;
else
done<=1'b0;
end
endmodule
2.2 testbench
`timescale 1ns / 1ps
//
// Company:
// Engineer:mr-pn-junction
//
// Create Date: 2024/04/26 10:45:26
// Design Name:
// Module Name: tb_uart_tx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module tb_uart_tx( );
reg clk;
reg rst_n;
reg start;
reg [7:0] data;
wire rs232_tx;
wire done;
initial clk=1'b0;
always #10 clk=~clk;
initial begin
rst_n=1'b0;
start=1'b0;
data='d0;
#100
rst_n=1'b1;
#200
data='h55;
start=1'b1;
#20
start=1'b0;
#20000
data='h58;
start=1'b1;
#20
start=1'b0;
#20000
$stop;
end
uart_tx u_uart(
.clk(clk),
.rst_n(rst_n),
.start(start),
.data(data),
.rs232_tx(rs232_tx),
.done(done)
);
endmodule
3 仿真结果
图2 仿真结果
参考文献
[1] UART协议讲解-CSDN博客