vivado RS232串口接收

参考bilibili“野火科技”视频改编,作为笔记复习参考

module uart_rec(
//成了
    input clk,
    input reset,
    
    input rx,
    
    
    
    output reg [7:0]Po_data,
    output reg      Po_flag
    );
    
     reg rx1;
     reg rx2;
     reg rx3;
     reg start_flag;
     reg work_en;
     reg [15:0]baud_cnt;
    // reg bit_flag;
     reg [3:0]bit_cnt;
     reg [7:0]rx_data;
     reg rx_flag;
    
    parameter  CLK_FREQ = 100000000;                //系统时钟频率
    parameter  UART_BPS = 115200;                    //串口波特率
    parameter  BAUD_CNT  = CLK_FREQ/UART_BPS;       //为得到指定波特率,
                                                //需要对系统时钟计数BPS_CNT次
    
    always @(posedge clk or negedge reset) begin
        if(!reset) begin
            rx1 <= 1'b1;
            rx2 <= 1'b1;
            rx3 <= 1'b1;
        end    
        else begin
            rx1 <= rx;
            rx2 <= rx1;
            rx3 <= rx2;
            
        end
    end
    
    //获取rx下降沿
    always @(posedge clk or negedge reset) begin
        if(!reset)
            start_flag <= 1'b0;
        else
            start_flag <= rx3 & ~rx2;    
    end  
    
    //什么时候 工作、接受数据完成?
    always @(posedge clk or negedge reset) begin
        if(!reset) begin
            work_en <= 1'b0;
            rx_flag <= 1'b0;
        end   
        else if(start_flag == 1'b1)
                work_en <= 1'b1;
        else if(bit_cnt == 4'd8 && baud_cnt == (BAUD_CNT/2)+1) begin
            work_en <= 0;
            rx_flag <= 1'b1;
        end
        else begin
            work_en <= work_en ;
            rx_flag <= 1'b0;
        end
    end
    
    // 定时
    always @(posedge clk or negedge reset) begin
        if(!reset) begin
            baud_cnt <= 16'd0;
            
        end
        else if(work_en == 1'b1) begin
            if(baud_cnt == BAUD_CNT-1) begin
                baud_cnt <= 16'd0;
                
            end
            else begin
                baud_cnt <= baud_cnt + 16'd1;
                
            end
        end
        else begin
            baud_cnt <= 16'd0;
            
        end
    end
    
    // 抓取的是第几个数据
    always @(posedge clk or negedge reset) begin
        if(!reset) begin
            
            bit_cnt <= 4'd0;
        end
        else if(work_en == 1'b1) begin
            if(baud_cnt == BAUD_CNT-1) begin
                
                bit_cnt <= bit_cnt + 4'd1;
            end
            else begin
                
                bit_cnt <= bit_cnt;
            end
        end
        else begin
            
            bit_cnt <= 4'd0;
        end
    end
    
    //抓取数据
    always @(posedge clk or negedge reset) begin
        if(!reset)
            rx_data <= 8'd0;
        else if(baud_cnt == BAUD_CNT/2) begin
            case(bit_cnt)
                4'd1:rx_data[0] <= rx;
                4'd2:rx_data[1] <= rx;
                4'd3:rx_data[2] <= rx;
                4'd4:rx_data[3] <= rx;
                4'd5:rx_data[4] <= rx;
                4'd6:rx_data[5] <= rx;
                4'd7:rx_data[6] <= rx;
                4'd8:rx_data[7] <= rx;
                default:rx_data <= 8'd0;
            endcase
        end
        else
            rx_data <= rx_data;
    end
    
    //输出数据
    always @(posedge clk or negedge reset) begin
        if(!reset) begin
            Po_data <= 8'd0;
            Po_flag <= 1'b0;
        end
        else if(rx_flag == 1'b1) begin
            Po_data <= rx_data;
            Po_flag <= 1'b1;
        end
        else begin
            Po_data <= 8'd0;
            Po_flag <= 1'b0;
        end
    end
endmodule

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值