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

电子说

1.3w人已加入

描述

2. 接收模块 (uart_rx):

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

);

input bit_in;

input clk_40k;

input rst_n;

output reg dout_vld;

output reg [7:0] dout;

reg rx_flag;

reg [6:0] cnt;

reg [5:0] rx_cnt;

reg [7:0] dout_temp;

//rx_flag: 接收过程rx_flag始终拉高

always @ (posedge clk_40k)

begin

if(~rst_n)

rx_flag <= 1'b0;

else if(bit_in == 1'b0)

rx_flag <= 1'b1;

else if(rx_cnt == 6'd9)

rx_flag <= 1'b0;

end

//cnt: 接收数据计数,clk_40k分频至1k波特率对接收数据进行计数

always @ (posedge clk_40k)

begin

if(~rst_n)

cnt <= 7'b0;

else if(rx_flag == 1'b1 && cnt != 7'd39)

cnt <= cnt + 1'b1;

else if(rx_flag == 1'b0 || cnt == 7'd39)

cnt <= 7'b0;

end

always @ (posedge clk_40k)

begin

if(~rst_n)

rx_cnt <= 6'b0;

else if(rx_flag == 1'b1 && cnt == 7'd39)

rx_cnt <= rx_cnt + 1'b1;

else if(rx_flag == 1'b0)

rx_cnt <= 6'b0;

end

//dout_temp: 将串行接收数据转换还原为8bit数据

always @ (posedge clk_40k)

begin

if(~rst_n)

dout_temp <= 8'b0;

else if(rx_flag == 1'b1 && cnt == 7'd39)

begin

dout_temp[7] <= bit_in;

dout_temp[6:0] <= dout_temp[7:1];

end

end

//dout_vld: 传输完成标识,8bit数据传输结束拉高

always @ (posedge clk_40k)

begin

if(~rst_n)

dout_vld <= 1'b0;

else if(rx_cnt == 6'd9 && cnt == 7'b0)

begin

dout <= dout_temp;

dout_vld <= 1'b1;

end

else

dout_vld <= 1'b0;

end

endmodule

3. Testbench(tb):

`timescale 1us/1us

module tb();

reg clk_40k;

reg rst_n;

reg [7:0] din;

reg send_start;

wire bit_out;

wire bit_in;

wire dout_vld;

wire [7:0] dout;

assign bit_in = bit_out;

uart_tx i_uart_tx(

.clk_40k (clk_40k ),

.rst_n (rst_n ),

.din (din ),

.send_start (send_start),

.bit_out (bit_out )

);

uart_rx i_uart_rx(

.clk_40k (clk_40k ),

.rst_n (rst_n ),

.bit_in (bit_in ),

.dout_vld (dout_vld ),

.dout (dout )

);

initial

begin

rst_n = 1'b0;

#10

rst_n = 1'b1;

end

initial

begin

clk_40k = 1'b0;

forever

#1

clk_40k = ~clk_40k;

end

initial

begin

send_start = 1'b0;

din = 8'd0;

forever

begin

    #1000

    din = $random()%256;

    send_start = 1'b1;

    #2

    send_start = 1'b0;

end

end

endmodule

4. 仿真结果 :

按照testbench对UART收发端进行仿真,仿真结果如图:

串行

  1. 系统时钟和传输速率通常不一致,clk_40k为高频系统时钟,利用计数器分频实现1k波特率;
  2. 复位信号rst_n低电平有效,正常传输时始终处于高电平。
  3. 开始传输时send_start信号拉高,传输结束时dout_vld信号拉高;
  4. 输入数据din在传输结束后在输出数据dout体现出来,传输时延为1个数据长度。

04

UART的优缺点

4.1 UART协议优点

  1. 通信只需要两条数据线;
  2. 无需时钟信号;
  3. 有奇偶校验位,方便通信的差错检查;
  4. 只需要接收端和发送端设置好数据包结构,即可稳定通信。

4.2 UART协议缺点

  1. 数据帧最大支持9位数据;
  2. 不支持多主机或多从机的主从系统。
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分