串口RS232


一、串口简介

通用异步收发传输器,英文全称Universal Asynchronous Receiver/Transmitter,简称UART
UART是一种通用的数据通信协议,也是异步串行通信口(串口)的总称,它在发送数据时将并行数据转换成串行数据来传输,在接收数据时将接收到的串行数据转换成并行数据。
包括RS232、RS499、RS423、RS422和RS485等接口标准规范和总线标准规范。

二、RS232

1.通信方式

有两个模块,tx(发送模块) 和 rx(接受模块)在这里插入图片描述
RS232的传输距离比较近,传输速率比较慢。

2.RS232接口

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数据接收和发送的数据帧!!!!
在这里插入图片描述
波特率:来波特率指数据信号对载波的调制速率,它用单位时间内载波调制状态改变次数来表示,其单位为波特(Baud),Bps

比特率:比特率是每秒传输的比特数。单位为比特(bps位/秒)

波特率源与比特率的关系为:比特率=波特率 * 单个调制状态对应的二进制位数

串口发或接收1bit数据的一个时间,称之为波特。例如: 波特率为9600Bps的波特率,其对应的1个波特为(1/9600)s 若系统时钟为100MHz,则时钟周期为10ns,那么在9600波特率下,一个波特等于几个时钟周期?
(1x109 ÷ 9600 ÷ 10 ≈ \div 9600 \div 10 \approx ÷9600÷10 10,416

三、代码及仿真

1.RX模块

RX.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/03 12:36:32
// Design Name: 
// Module Name: uart_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module uart_rx
#(
    parameter       UART_BPS       =   'd9600,
    parameter       CLK_FREQ         =   'd100_000_000
)
(
    input   wire                sys_clk     ,
    input   wire                rst_n       ,
    input   wire                rx          ,

    output  reg       [7:0]     Po_data     ,
    output  reg                 Po_flag
);

parameter  BAUD_CNT_MAX     =       CLK_FREQ/UART_BPS;

reg             rx_reg1;        // 同步到系统时钟下
reg             rx_reg2;     
reg             rx_reg3;        // 打两拍,减小亚稳态危害
reg             Start_flag;     // 开始一个数据帧的传输标志信号
reg             Work_en;        // 标识数据采集范围,接收数据工作使能信号
reg     [15:0]  baud_cnt;       // 计数1码元所需要的时钟周期数(在本实验中,1码元=1bit)
reg             Bit_flag;       // 每bit数据稳定点拉高一拍 
reg     [3:0]   Bit_cnt;        // bit计数器
reg     [7:0]   rx_data;
reg             rx_flag;


always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        // reset
        rx_reg1 <= 1'b1;
        rx_reg2 <= 1'b1;
        rx_reg3 <= 1'b1;
    end
    else begin
        rx_reg1 <= rx;
        rx_reg2 <= rx_reg1;
        rx_reg3 <= rx_reg2;
    end
end




always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Start_flag <= 1'b0;
    end
    else if ((rx_reg3 == 1'b1) && (rx_reg2 == 1'b0) && (Work_en == 1'b0)) begin
        Start_flag <= 1'b1;
    end
    else begin
        Start_flag <= 1'b0;
    end
end


always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Work_en <= 1'b0;
    end
    else if (Start_flag == 1'b1) begin
        Work_en <= 1'b1;
    end
    else if ((Bit_cnt == 4'd8) && (Bit_flag == 1'b1)) begin
        Work_en <= 1'b0;
    end
    else begin
        Work_en <=  Work_en;
    end
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        baud_cnt <=  16'd0;
    end
    else if ((baud_cnt == BAUD_CNT_MAX - 1) || (~Work_en)) begin
        baud_cnt <= 16'd0;
    end
    else begin
        baud_cnt <= baud_cnt + 1'b1;
    end
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Bit_flag <=  1'b0;
    end
    else if (baud_cnt == BAUD_CNT_MAX / 2 - 1) begin
        Bit_flag <= 1'b1;
    end
    else begin
        Bit_flag<= 1'b0;
    end
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Bit_cnt <=  1'b0;
    end
    else if ((Bit_flag) && (Bit_cnt == 4'd8)) begin
        Bit_cnt <=  1'b0;
    end
    else if (Bit_flag) begin
        Bit_cnt <= Bit_cnt + 1'b1;
    end
    else begin
        Bit_cnt <=  Bit_cnt;
    end
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        rx_data <=  8'd0;
    end
    else if (((Bit_cnt >= 4'd1) && (Bit_cnt <= 4'd8)) && (Bit_flag == 1'b1))begin
        rx_data <= {rx_reg3,rx_data[7:1]};
    end
    else begin
        rx_data <= rx_data;
    end
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        rx_flag <=  1'b0;
    end
    else if ((Bit_cnt == 4'd8) && (Bit_flag == 1'b1)) begin
        rx_flag <= 1'b1;
    end
    else
        rx_flag <= 1'b0;
end

always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Po_data <=  8'd0;
    end
    else if (rx_flag == 1'b1) begin
        Po_data <= rx_data;
    end
    else begin
        Po_data <= Po_data;
    end
end


always @(posedge sys_clk or negedge rst_n) begin
    if (rst_n == 1'b0) begin
        Po_flag <=  1'd0;
    end
    else begin
        Po_flag <=  rx_flag;
    end
end



endmodule

tb_rx.v

`timescale 1ns / 1ns
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/03 20:53:28
// Design Name: 
// Module Name: tb_rx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_rx();

reg         sys_clk;
reg         rst_n;
reg         rx;

wire   [7:0]     Po_data;
wire             Po_flag;


initial begin
    sys_clk <= 1'b1;
    rst_n   <= 1'b0;
    rx      <= 1;
    #10
    rst_n   <= 1'b1;
end



initial begin
    #100
    rx_bit(8'd0);
    rx_bit(8'd1);
    rx_bit(8'd2);
    rx_bit(8'd3);
    rx_bit(8'd4);
    rx_bit(8'd5);
    rx_bit(8'd6);
    rx_bit(8'd7);
    rx_bit(8'b1010_0111);
end


always #5 sys_clk = ~sys_clk;

task    rx_bit  ;

    input       [7:0]   data;

    integer  i;

    begin
    for(i = 0; i < 10; i = i + 1)begin
        case(i)
            0:rx        <= 1'b0;
            1:rx        <= data[0];
            2:rx        <= data[1];
            3:rx        <= data[2];
            4:rx        <= data[3];
            5:rx        <= data[4];
            6:rx        <= data[5];
            7:rx        <= data[6];
            8:rx        <= data[7];
            9:rx        <= 1'b1;
            default:rx  <= 1'b1;
        endcase
        #(10416*10);
        end
    end
endtask

uart_rx
#(
    .UART_BPS (9600         ),
    .CLK_FREQ (100_000_000  )
)uart_rx_inst
(
    .sys_clk(sys_clk),
    .rst_n  (rst_n),
    .rx     (rx),

    .Po_data(Po_data),
    .Po_flag(Po_flag)
);



endmodule

仿真波形图
在这里插入图片描述

在这里插入图片描述

2.TX模块

tx.v

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/04 19:36:40
// 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
#(
    parameter       UART_BPS         =   'd9600,
    parameter       CLK_FREQ         =   'd100_000_000
)
(
    input  wire          sys_clk         ,
    input  wire          rst_n           ,
    input  wire  [7:0]   Pi_data         ,
    input  wire          Pi_flag         ,

    output reg           tx
);


parameter  BAUD_CNT_MAX     =       CLK_FREQ/UART_BPS;


reg             Work_en     ;
reg    [15:0]   baud_cnt    ;
reg    [3:0]    Bit_cnt    ;
reg             Bit_flag     ;





always @(posedge sys_clk or negedge rst_n)begin
    if (rst_n == 1'b0) begin
        Work_en <= 1'b0;
    end
    else if (Pi_flag == 1'b1) begin
        Work_en <= 1'b1;
    end
    else if ((Bit_cnt == 4'd9) && (Bit_flag == 1'b1)) begin
        Work_en <= 1'b0;
    end
    else begin
        Work_en <= Work_en;
    end
end


always @(posedge sys_clk or negedge rst_n)begin
    if (rst_n == 1'b0) begin
        baud_cnt <= 16'd0;
    end
    else if ((baud_cnt == BAUD_CNT_MAX - 1'b1)  || (~Work_en)) begin
        baud_cnt <= 16'd0;
    end
    else begin
        baud_cnt <= baud_cnt + 1'b1;
    end
end


always @(posedge sys_clk or negedge rst_n)begin
    if (rst_n == 1'b0) begin
        Bit_flag <= 1'b0;
    end
    else if (baud_cnt == 16'd1) begin
        Bit_flag <= 1'b1;
    end
    else begin
        Bit_flag <= 1'b0;
    end
end

always @(posedge sys_clk or negedge rst_n)begin
    if (rst_n == 1'b0) begin
        Bit_cnt <= 1'b0;
    end
    else if ((Bit_cnt == 4'd9) && (Bit_flag == 1'b1)) begin
        Bit_cnt <= 4'd0;
    end
    else if ((Bit_flag == 1'b1) && (Work_en == 1'b1)) begin
        Bit_cnt <= Bit_cnt + 1'b1;
    end
    else begin
        Bit_cnt <= Bit_cnt;
    end
end


always @(posedge sys_clk or negedge rst_n)begin
    if (rst_n == 1'b0) begin
        tx  <= 1'b1;
    end
    else if (Bit_flag == 1'b1) begin
        case(Bit_cnt)
            0   : tx <= 1'b0;
            1   : tx <= Pi_data[0];
            2   : tx <= Pi_data[1];
            3   : tx <= Pi_data[2];
            4   : tx <= Pi_data[3];
            5   : tx <= Pi_data[4];
            6   : tx <= Pi_data[5];
            7   : tx <= Pi_data[6];
            8   : tx <= Pi_data[7];
            9   : tx <= 1'b1;
            default:tx<=1'b1;
        endcase
    end
end

endmodule

tb_tx…v

`timescale 1ns / 1ns
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/04 19:39:56
// Design Name: 
// Module Name: tb_tx
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module tb_tx();

reg             sys_clk;
reg             rst_n;
reg   [7:0]     Pi_data;
reg             Pi_flag;
wire            tx;

initial begin
    sys_clk <= 1'b1;
    rst_n   <= 1'b0;
    #10
    rst_n   <= 1'b1;
end

always #5 sys_clk = ~sys_clk;

initial begin
    Pi_data <= 8'd0;
    Pi_flag <=1'b0;
    #100
    //数据0
    Pi_data <=8'd0;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据1
    Pi_data <=8'd1;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据2
    Pi_data <=8'd2;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据3
    Pi_data <=8'd3;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据4
    Pi_data <=8'd4;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据5
    Pi_data <=8'd5;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据6
    Pi_data <=8'd6;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
    #(10416*10*10)
    //数据7
    Pi_data <=8'd7;
    Pi_flag <=1'b1;
    #10
    Pi_flag <=1'b0;
end

uart_tx
#(
    .UART_BPS (9600         ),
    .CLK_FREQ (100_000_000  )
)uart_tx_inst
(
    .sys_clk(sys_clk),
    .rst_n  (rst_n),
    .Pi_data(Pi_data),
    .Pi_flag(Pi_flag),

    .tx     (tx)
);



endmodule

仿真波形图
在这里插入图片描述

3.顶层模块

`timescale 1ns / 1ns
//
// Company: 
// Engineer: 
// 
// Create Date: 2021/09/04 21:59:02
// Design Name: 
// Module Name: rs232
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module rs232
(
    input   wire                sys_clk     ,
    input   wire                rst_n       ,
    input   wire                rx          ,

    output  wire                tx
);


wire         [7:0]   rx_data;
wire                 rx_flag;




uart_tx
#(
    .UART_BPS (9600         ),
    .CLK_FREQ (100_000_000  )
)uart_tx_inst
(
    .sys_clk(sys_clk),
    .rst_n  (rst_n),
    .Pi_data(rx_data),
    .Pi_flag(rx_flag),

    .tx     (tx)
);

uart_rx
#(
    .UART_BPS (9600         ),
    .CLK_FREQ (100_000_000  )
)uart_rx_inst
(
    .sys_clk(sys_clk),
    .rst_n  (rst_n),
    .rx     (rx),

    .Po_data(rx_data),
    .Po_flag(rx_flag)
);
endmodule

四、下板实验

在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值