FPGA-UART串口发送数据

学习了使用FPGA-UART串口发送数据,做个小结

串口发送模块的结构图
在这里插入图片描述

module uart_tx (
    input clk,
    input rst_n,

    input [7:0]data_byte,
    input send_en,
    input [2:0]baud_set,
    
    output reg RS232_TX,
    output reg TX_done,
    output reg UART_state
);



reg [15:0]baud_cnt;
reg [15:0]baud_choose;
reg [7:0]r_data_byte;

reg baud_clk;
reg [3:0] baud_count;

localparam  START_bit = 1'b0,
            STOP_bit = 1'b1;

//波特率        波特率周期      50M时钟计数值
// 9600        104167          5208
// 19200       52083           2604
// 38400       26041           1302
// 57600       17361           868
// 115200      8680            434


//根据波特率选择对应的计数值
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        baud_choose <= 15'd5207;
    else
        begin
            case (baud_set)
                0 :  baud_choose <= 16'd5207;
                1 :  baud_choose <= 16'd2603;
                2 :  baud_choose <= 16'd1301;
                3 :  baud_choose <= 16'd867;
                4 :  baud_choose <= 16'd433;
                default: baud_choose <= 5207;
            endcase
        end
end

//波特率计数
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        baud_cnt <= 0;
    else if(UART_state)
        begin
            if(baud_cnt == baud_choose)
                baud_cnt <= 0;
            else
                baud_cnt <= baud_cnt + 1'b1;
        end
    else
        baud_cnt <= 0;
end



//生成波特率时钟
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        baud_clk <= 0;
    else if(baud_cnt == 16'd1)
        baud_clk <= 1;
    else
        baud_clk <= 0;
end



//一次传输需要11个波特率脉冲,计数脉冲个数
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        baud_count <= 0;
    else if(baud_count == 4'd11)
        baud_count <= 0;
    else if(baud_clk)
        baud_count <= baud_count + 1'b1;
    else
        baud_count <= baud_count;
end


//数据传输前对data打一拍寄存,保证数据的稳定性
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        r_data_byte <= 0;
    else if(send_en)
        r_data_byte <= data_byte;
    else
        r_data_byte <= r_data_byte;
end



//数据传输过程,用线性序列机表示
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        RS232_TX <= 1'b1;
    else
        begin
            case (baud_count)
                0: RS232_TX <= 1'b1;
                1: RS232_TX <= START_bit;
                2: RS232_TX <= r_data_byte[0];
                3: RS232_TX <= r_data_byte[1];
                4: RS232_TX <= r_data_byte[2];
                5: RS232_TX <= r_data_byte[3];
                6: RS232_TX <= r_data_byte[4];
                7: RS232_TX <= r_data_byte[5];
                8: RS232_TX <= r_data_byte[6];
                9: RS232_TX <= r_data_byte[7];
                10: RS232_TX <= STOP_bit;
                default: RS232_TX <= 1'b1;
            endcase
        end
end

//一次数据传输完成标志位
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        TX_done <= 0;
    else if(baud_count == 4'd11)
        TX_done <= 1;
    else
        TX_done <= 0;
end

//串口的状态指示,当其正在传输时为高电平
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        UART_state <= 0;
    
    else if(baud_count == 4'd11)
        UART_state <= 0;
    else if(send_en)
        UART_state <= 1;
    else
        UART_state <= UART_state;
end

endmodule


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值