• FPGA 串口多字节发送,串口回环测试


    串口接收

    串口帧

    在这里插入图片描述

    设计文件

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/12 23:11:28
    // Design Name: 
    // Module Name: UART_Byte_Rx
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Byte_Rx
        #(
            parameter BaudRate = 115200,//波特率
            parameter ClockRate = 50_000_000//系统时钟
        )
    (
        Clk,
        Rst_n,
        Rx,
        Rx_Data,
        Rx_Done
    );
        input Clk;
        input Rst_n;
        input Rx;
        output reg [7:0] Rx_Data;
        output Rx_Done;
        
        //设置波特率  将一bit时间分成16份,在每一份的中间进行采样
        localparam Buad_Num = ClockRate/BaudRate/16;
        
        //检测下降沿
        reg [2:0] neg_edge_r;
        wire neg_edge_flag;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                neg_edge_r<=3'b0;
            else
                neg_edge_r<={neg_edge_r[1:0],Rx};
        end
        assign neg_edge_flag=neg_edge_r[2:1]==2'b10;
        
        //接收使能信号
        reg rx_en;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                rx_en<=0;
            else if(neg_edge_flag)
                rx_en<=1'd1;
            else if(Rx_Done)
                rx_en<=1'd0;
            else
                rx_en<=rx_en;
        end
        
        //波特率计数
        reg [12:0] buad_cnt;
        wire add_buad_cnt;
        wire end_buad_cnt;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                buad_cnt<=0;
            else if(add_buad_cnt)begin
                if(end_buad_cnt)
                    buad_cnt<=0;
                else 
                    buad_cnt<=buad_cnt+1'b1;
            end
            else
                buad_cnt<=0;
        end
        assign add_buad_cnt=rx_en;
        assign end_buad_cnt=buad_cnt>=(Buad_Num-1'd1);
        
        //采样点
        wire buad_cnt_middle=buad_cnt==(Buad_Num/2);
        
        //计数采样次数 16*10
        reg [7:0] sampling_cnt;
        wire add_sampling_cnt;
        wire end_sampling_cnt;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                sampling_cnt<=0;
            else if(rx_en)begin
                if(add_sampling_cnt)begin
                    if(end_sampling_cnt)
                        sampling_cnt<=0;
                    else 
                        sampling_cnt<=sampling_cnt+1'b1;
                end    
            end
            else
                sampling_cnt<=0;
        end
        assign add_sampling_cnt=buad_cnt_middle;
        assign end_sampling_cnt=add_sampling_cnt && sampling_cnt>=159;
        
        //设置存储数据的寄存器
        //8个寄存器,每个寄存器的位宽是3(原因是:16次采集,我们选择中间的7次采集,进行相加,结果大于4[100]的,认为是高电平)
        reg [2:0]rx_data_r[7:0];
        reg [2:0]sta_bit;//起始位
        reg [2:0]sto_bit;//停止位
        
        //0 【0】 1 【1】 2 【2】 3 【3】 4 【4】 5 【5】 6 【6】 7 【7】 8 【8】 9 【9】 10 【10】 
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)begin
                rx_data_r[0]<=0;
                rx_data_r[1]<=0;
                rx_data_r[2]<=0;
                rx_data_r[3]<=0;
                rx_data_r[4]<=0;
                rx_data_r[5]<=0;
                rx_data_r[6]<=0;
                rx_data_r[7]<=0;
                sta_bit<=0;
                sto_bit<=0;
            end
            else if(buad_cnt_middle)begin
                case(sampling_cnt)
                    0:begin//清0所有寄存器
                        rx_data_r[0]<=0;
                        rx_data_r[1]<=0;
                        rx_data_r[2]<=0;
                        rx_data_r[3]<=0;
                        rx_data_r[4]<=0;
                        rx_data_r[5]<=0;
                        rx_data_r[6]<=0;
                        rx_data_r[7]<=0;
                        sta_bit<=0;
                        sto_bit<=0;
                    end
                    5,6,7,8,9,10,11: sta_bit <= sta_bit + Rx;
                    21,22,23,24,25,26,27: rx_data_r[0] <= rx_data_r[0] + Rx;
                    37,38,39,40,41,42,43: rx_data_r[1] <= rx_data_r[1] + Rx;
                    53,54,55,56,57,58,59: rx_data_r[2] <= rx_data_r[2] + Rx;
                    69,70,71,72,73,74,75: rx_data_r[3] <= rx_data_r[3] + Rx;
                    85,86,87,88,89,90,91: rx_data_r[4] <= rx_data_r[4] + Rx;
                    101,102,103,104,105,106,107: rx_data_r[5] <= rx_data_r[5] + Rx;
                    117,118,119,120,121,122,123: rx_data_r[6] <= rx_data_r[6] + Rx;
                    133,134,135,136,137,138,139: rx_data_r[7] <= rx_data_r[7] + Rx;
                    149,150,151,152,153,154,155: sto_bit <= sto_bit + Rx;
                    default:;
                endcase
            end
        end
        
        //将读取的数据反馈回来   4=3'b100
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Rx_Data<=0;
            else if(sampling_cnt==159)begin
                Rx_Data[0]<=(rx_data_r[0][2]);
                Rx_Data[1]<=(rx_data_r[1][2]);
                Rx_Data[2]<=(rx_data_r[2][2]);
                Rx_Data[3]<=(rx_data_r[3][2]);
                Rx_Data[4]<=(rx_data_r[4][2]);
                Rx_Data[5]<=(rx_data_r[5][2]);
                Rx_Data[6]<=(rx_data_r[6][2]);
                Rx_Data[7]<=(rx_data_r[7][2]);
            end
        end
        
        assign Rx_Done=end_sampling_cnt;
        
        
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180

    仿真验证

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/12 23:13:05
    // Design Name: 
    // Module Name: UART_Byte_Rx_tb
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Byte_Rx_tb();
    
        reg Clk;
        reg Rst_n;
        reg Rx;
        wire [7:0] Rx_Data;
        wire Rx_Done;
        
        UART_Byte_Rx UART_Byte_Rx
        (
            Clk,
            Rst_n,
            Rx,
            Rx_Data,
            Rx_Done
        );
        
        initial Clk=1;
        always #10 Clk=~Clk;
        
        initial begin
          	Rst_n=0;
          	Rx=1;
            #201
            Rst_n=1;
            #200;
            uart_tx_byte(8'h5a);  
            #9000;
            uart_tx_byte(8'h88);  
            #9000;
            uart_tx_byte(8'h11);
            #9000;
            $stop;
        end
        
        task uart_tx_byte;
            input [7:0]tx_data;
            begin
                Rx=1;
                #20;
                Rx=0;
                #8680;
                Rx=tx_data[0];
                #8680;
                Rx=tx_data[1];
                #8680;
                Rx=tx_data[2];
                #8680;
                Rx=tx_data[3];
                #8680;
                Rx=tx_data[4];
                #8680;
                Rx=tx_data[5];
                #8680;
                Rx=tx_data[6];
                #8680;
                Rx=tx_data[7];
                #8680;
                Rx=1;
                #8680;
            end
        endtask
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    串口发送

    **注意:**电平信号的传输线中有一个参考电平线(一般是GND),然后信号线上的信号值是由信号线电平和参考电平线的电压差决定。所以我们一定要养成模块之间共地的好习惯。

    串口帧

    在这里插入图片描述

    模块设计

    在这里插入图片描述

    设计文件

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/06 11:30:58
    // Design Name: 
    // Module Name: UART_Byte_Tx
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Byte_Tx
        #(
            parameter BaudRate = 115200,//波特率
            parameter ClockRate = 50_000_000//系统时钟
        )
    (
    	Clk,
        Rst_n,
        Send_En,
        data_byte,
        Tx_Data,
        Tx_Done,
        uart_state
    );
        input Clk;
        input Rst_n;
        input Send_En;
        input [7:0] data_byte;
        
        output reg Tx_Data;
        output reg Tx_Done;
        output reg uart_state;
        
        //设置使能
        reg tx_en;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                tx_en<=0;
            else if(Send_En)
                tx_en<=1'd1;
            else if(Tx_Done)
                tx_en<=1'd0;
            else
                tx_en<=tx_en;
        end
        
        //设置波特率
        localparam Buad_Num = ClockRate/BaudRate;
    
        //设置计数器
        reg [12:0] buad_cnt;
        wire add_buad_cnt;
        wire end_buad_cnt;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                buad_cnt<=0;
            else if(add_buad_cnt)begin
                if(end_buad_cnt)
                    buad_cnt<=0;
                else 
                    buad_cnt<=buad_cnt+1'b1;
            end
            else
                buad_cnt<=0;
        end
        assign add_buad_cnt=tx_en;
        assign end_buad_cnt=buad_cnt>=(Buad_Num-1'd1);
        
        //设置发送bit计数
        reg [3:0] bit_cnt;
        wire add_bit_cnt;
        wire end_bit_cnt;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                bit_cnt<=0;
            else if(add_bit_cnt)
                bit_cnt<=bit_cnt+1'd1;
            else if(end_bit_cnt)
                bit_cnt<=0;
            else
                bit_cnt<=bit_cnt;
        end
        assign add_bit_cnt=buad_cnt==1;
        assign end_bit_cnt=(bit_cnt==4'd10 && add_bit_cnt) || !tx_en;
        
        //发送数据
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Tx_Data<=1;
            else begin
                case(bit_cnt)
                    4'd1:Tx_Data<=0;
                    4'd2:Tx_Data<=data_byte[0];
                    4'd3:Tx_Data<=data_byte[1];
                    4'd4:Tx_Data<=data_byte[2];
                    4'd5:Tx_Data<=data_byte[3];
                    4'd6:Tx_Data<=data_byte[4];
                    4'd7:Tx_Data<=data_byte[5];
                    4'd8:Tx_Data<=data_byte[6];
                    4'd9:Tx_Data<=data_byte[7];
                    4'd10:Tx_Data<=1;
                    default:Tx_Data<=1;
                endcase
            end
        end
        
        //发送结束
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Tx_Done<=0;
            else if(bit_cnt==4'd10 && add_bit_cnt)
                Tx_Done<=1;
            else
                Tx_Done<=0;
        end
        
        //发送状态(有效数据)
        wire En_uart_state;
        wire Nen_uart_state;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                uart_state<=0;
            else if(En_uart_state)
                uart_state<=1;
            else if(Nen_uart_state)
                uart_state<=0;
        end
        assign En_uart_state=bit_cnt==4'd1 && add_bit_cnt;
        assign Nen_uart_state=bit_cnt==4'd9 && add_bit_cnt;
        
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    仿真验证

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/06 11:31:09
    // Design Name: 
    // Module Name: UART_Byte_Tx_tb
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Byte_Tx_tb();
    
    
        reg Clk;
        reg Rst_n;
        reg Send_En;
        reg [7:0]data_byte;
        
        wire Tx_Data;
        wire Tx_Done;
        wire uart_state;
        
        initial Clk=1;
        always #10 Clk=~Clk;
        
        initial begin
            Rst_n=0;
            Send_En=0;
            data_byte=0;
            #201;
            Rst_n=1;
            data_byte=8'b1001_0110;
            Send_En=1;
            #20;
            Send_En=0;
            #100000;
            data_byte=8'b0111_0110;
            Send_En=1;
            #20;
            Send_En=0;
            #100000;
            $stop;
        end
        
        
        UART_Byte_Tx UART_Byte_Tx(
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Send_En(Send_En),
            .data_byte(data_byte),
            .Tx_Data(Tx_Data),
            .Tx_Done(Tx_Done),
            .uart_state(uart_state)
        );
        
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    在这里插入图片描述

    串口接收-串口发送

    基于串口的数据收、发模块,使用收、发模块,完成串口数据回环实验。

    RTL视图

    在这里插入图片描述

    设计文件

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/12 23:49:51
    // Design Name: 
    // Module Name: UART_Data_Loopback_top
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Data_Loopback_top(
        Clk,
        Rst_n,
        Rx,
        Tx_Data
        );
        input Clk;
        input Rst_n;
        input Rx;
        
        output Tx_Data;
        
        //串口接收
        wire [7:0] Rx_Data;
        wire Rx_Done;
        UART_Byte_Rx
        #(
            115200,
            50_000_000
        )
        UART_Byte_Rx
        (
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Rx(Rx),
            .Rx_Data(Rx_Data),
            .Rx_Done(Rx_Done)
        );
        
        //串口发送
        wire Tx_Done;
        wire uart_state;
        UART_Byte_Tx
        #(
            115200,
            50_000_000
        )
        UART_Byte_Tx(
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Send_En(Rx_Done),
            .data_byte(Rx_Data),
            .Tx_Data(Tx_Data),
            .Tx_Done(Tx_Done),
            .uart_state(uart_state)
        );
        
        
        
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73

    约束文件

    set_property PACKAGE_PIN Y18 [get_ports Clk]
    set_property PACKAGE_PIN A21 [get_ports Rst_n]
    set_property PACKAGE_PIN M15 [get_ports Tx_Data]
    set_property IOSTANDARD LVCMOS33 [get_ports Clk]
    set_property IOSTANDARD LVCMOS33 [get_ports Rst_n]
    set_property IOSTANDARD LVCMOS33 [get_ports Tx_Data]
    
    set_property PACKAGE_PIN J21 [get_ports Rx]
    set_property IOSTANDARD LVCMOS33 [get_ports Rx]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    板级验证

    在这里插入图片描述

    任意字节发送

    设计文件

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/13 10:16:15
    // Design Name: 
    // Module Name: UART_Bytes_Tx
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Bytes_Tx
        #(
            parameter BaudRate = 115200,//波特率
            parameter ClockRate = 50_000_000,//系统时钟
            parameter BytesNum=5//发送字节个数
        )
    (
    	 Clk,
        Rst_n,
        Trans_Go,
        data_bytes,
        Tx_Data,
        Trans_Done,
        uart_state
    );
        localparam Bit_Wide = BytesNum * 8;
        
        input Clk;
        input Rst_n;
        input Trans_Go;
        input [Bit_Wide-1:0] data_bytes;
        
        output Tx_Data;
        output reg Trans_Done;
        output uart_state;
       
    
        //发送使能
        reg Trans_en;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Trans_en<=0;
            else if(Trans_Go)
                Trans_en<=1;
            else if(Trans_Done)
                Trans_en<=0;
            else
                Trans_en<=Trans_en;
            
        end
        
        //计数已经发送的字节数
        reg [5:0] send_byte_num;//最多可发送63字节,想要发送更多字节,需要调大位宽
        wire add_send_byte_num;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                send_byte_num<=0;
            else if(Trans_en) begin
                if(add_send_byte_num)
                    send_byte_num<=send_byte_num+1'b1;
                else
                    send_byte_num<=send_byte_num;
            end
            else 
                send_byte_num<=0;
        end
        assign add_send_byte_num=Tx_Done;
        
         //将传输的值寄存到寄存器中,每发送一个字节进行移位
        reg [Bit_Wide-1:0] data_bytes_r;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                data_bytes_r<=0;
            else if(Trans_Go)
                data_bytes_r<=data_bytes;
            else if(Tx_Done)
                data_bytes_r<=data_bytes_r>>8;
            else
                data_bytes_r<=data_bytes_r;
        end
      
        //将多字节数据分成一字节发送,使用发送结束标志位来启动下一次发送
        reg [7:0] data_byte_temp;
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                data_byte_temp<=0;
            else 
                data_byte_temp<=data_bytes_r;
        end
        
        //串口单字节发送
        wire Tx_Done;
        wire uart_state;
        reg Send_En;
        
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Send_En<=0;
            else if( ( Trans_Go || Tx_Done ) && !(send_byte_num>=BytesNum-1 && add_send_byte_num) )
                Send_En<=1;
            else 
                Send_En<=0;
        end
        
        UART_Byte_Tx
        #(
            115200,
            50_000_000
        )
        UART_Byte_Tx(
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Send_En(Send_En),
            .data_byte(data_byte_temp),
            .Tx_Data(Tx_Data),
            .Tx_Done(Tx_Done),
            .uart_state(uart_state)
        );
        
        //全部字节发送标志位
        always@(posedge Clk or negedge Rst_n)begin
            if(!Rst_n)
                Trans_Done<=0;
            else if(send_byte_num>=BytesNum-1 && add_send_byte_num)
                Trans_Done<=1;
            else 
                Trans_Done<=0;
        end
        
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143

    仿真验证

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/13 10:24:58
    // Design Name: 
    // Module Name: UART_Bytes_Tx_tb
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Bytes_Tx_tb();
    
        reg Clk;
        reg Rst_n;
        reg Trans_Go;
        reg [39:0]data_bytes;
        
        wire Tx_Data;
        wire Trans_Done;
        wire uart_state;
        
        initial Clk=1;
        always #10 Clk=~Clk;
        
        initial begin
            Rst_n=0;
            Trans_Go=0;
            data_bytes=0;
            #201;
            Rst_n=1;
            data_bytes=40'h123456789a;
            Trans_Go=1;
            #20;
            Trans_Go=0;
            @(posedge Trans_Done);
            #200000
            data_bytes=40'ha987654321;
            Trans_Go=1;
            #20;
            Trans_Go=0;
            @(posedge Trans_Done);
            #200000
            data_bytes=40'habcdef4321;
            Trans_Go=1;
            #20;
            Trans_Go=0;
            @(posedge Trans_Done);
            #200000
            $stop;
        end
        
        
        UART_Bytes_Tx
        #(
         .BytesNum(5)
        )
        UART_Bytes_Tx(
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Trans_Go(Trans_Go),
            .data_bytes(data_bytes),
            .Tx_Data(Tx_Data),
            .Trans_Done(Trans_Done),
            .uart_state(uart_state)
        );
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    在这里插入图片描述

    在这里插入图片描述

    按键发送多字节

    发送AMH\r\n

    RTL视图

    在这里插入图片描述

    设计文件

    `timescale 1ns / 1ps
    //
    // Company: 
    // Engineer: 
    // 
    // Create Date: 2023/01/13 15:09:15
    // Design Name: 
    // Module Name: UART_Bytes_Tx_test
    // Project Name: 
    // Target Devices: 
    // Tool Versions: 
    // Description: 
    // 
    // Dependencies: 
    // 
    // Revision:
    // Revision 0.01 - File Created
    // Additional Comments:
    // 
    //
    
    
    module UART_Bytes_Tx_test(
        Clk,
        Rst_n,
        Key_in,
        Tx_Data
    );
    
    
        input Clk;
        input Rst_n;
        input Key_in;
        output Tx_Data;
        
        //按键输入
        wire Key_flag;
        wire Key_State;
        key_filter key_filter(
             .Clk(Clk),
             .Rst_n(Rst_n),
             .Key_in(Key_in),
             .Key_flag(Key_flag), //按键按下标志位
             .Key_State(Key_State) //高电平,按键按下
        );
        
        //任意字节发送
        wire [39:0] data_bytes;
        assign data_bytes=40'h0A0D484D41;// AMH/r/n
        wire Trans_Done;
        wire uart_state;
        UART_Bytes_Tx
        #(
         .BytesNum(5)
        )
        UART_Bytes_Tx(
            .Clk(Clk),
            .Rst_n(Rst_n),
            .Trans_Go(Key_flag),
            .data_bytes(data_bytes),
            .Tx_Data(Tx_Data),
            .Trans_Done(Trans_Done),
            .uart_state(uart_state)
        );
    
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67

    约束文件

    set_property PACKAGE_PIN Y18 [get_ports Clk]
    set_property PACKAGE_PIN A21 [get_ports Rst_n]
    set_property PACKAGE_PIN M15 [get_ports Tx_Data]
    set_property IOSTANDARD LVCMOS33 [get_ports Clk]
    set_property IOSTANDARD LVCMOS33 [get_ports Rst_n]
    set_property IOSTANDARD LVCMOS33 [get_ports Tx_Data]
    
    set_property PACKAGE_PIN B21 [get_ports Key_in]
    set_property IOSTANDARD LVCMOS33 [get_ports Key_in]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    板级验证

    在这里插入图片描述

  • 相关阅读:
    Redis知识点复习
    【Java】JDK 21中的虚拟线程以及其他新特性
    Python统计labelme标注Json文件的标签数
    IDEA中如何快速定位到第一行或者最后一行
    Linux 常用基本命令
    同一个接口时快时慢。一次慢的,三四次是快的。怎么回事?
    双馈风电机组备用容量控制策略研究
    谈谈WPF和.net的开发模式
    游戏心理学Day28
    PyTorch入门之【tensor】
  • 原文地址:https://blog.csdn.net/m0_55849362/article/details/136549551