FPGA的串口接收部分的知识点

在串口接收图像,存到RAM,然后读取RAM数据显示在TFT上的实验中

发现发送图片的时候,发现花屏,发现是串口这边的问题。估计当时的串口接收代码没写好,这边重新看一下。

module uart_byte_rx(
    Clk,
    Reset_n,
    uart_rx,
    Rx_Done,
    Rx_Data
);

    input Clk;
    input Reset_n;
    input uart_rx;
    output reg Rx_Done;
    output reg[7:0]Rx_Data;
    
    parameter CLOCK_FREQ = 50_000_000;
    parameter BAUD = 115200;
    parameter MCNT_BAUD = CLOCK_FREQ / BAUD - 1;  //这边计数434 - 1
    // 1/115200然后×10的9次方等于传输一位需要的ns
    // 然后再/20ns 也就是50MHZ的最小时钟,就是计数次数了,正好是434

    reg [7:0]r_Rx_Data;//接收数据
    
    reg [29:0]baud_div_cnt; 
    reg en_baud_cnt;
    reg [3:0]bit_cnt;
    
    wire w_Rx_Done;
    wire nedge_uart_rx;
    
    reg r_uart_rx;
    
    reg dff0_uart_rx,dff1_uart_rx;
//波特率计数器逻辑
   always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        baud_div_cnt <= 0;
    else if(en_baud_cnt)begin
        if(baud_div_cnt == MCNT_BAUD)  //计数传1位数据的最小时间单位
            baud_div_cnt <= 0;
        else
            baud_div_cnt <= baud_div_cnt + 1'd1;
    end
    else
        baud_div_cnt <= 0;
  
        
//UART 信号边沿检测逻辑,打拍。
    always@(posedge Clk)
        dff0_uart_rx <= uart_rx;
        
    always@(posedge Clk)
        dff1_uart_rx <= dff0_uart_rx;     
           
    always@(posedge Clk)
        r_uart_rx <= dff1_uart_rx;
        
//串口接收开始位,一开始是一个下降沿检测start
//打两拍,上一拍是0,这一拍是1,这就是下降沿
    assign nedge_uart_rx = (dff1_uart_rx == 0) && (r_uart_rx == 1);
        
//波特率计数器使能逻辑
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        en_baud_cnt <= 0;
    else if(nedge_uart_rx)   //下降沿开始,计数使能
        en_baud_cnt <= 1;
    else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 0) && (dff1_uart_rx == 1))  //判断毛刺信号
        en_baud_cnt <= 0;
    else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9))
        en_baud_cnt <= 0;


//位计数器逻辑
//串口8位加起始位,判断是哪一位
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)   
        bit_cnt <= 0;
    else if((bit_cnt == 9) && (baud_div_cnt == MCNT_BAUD/2))  
        bit_cnt <= 0;
    else if(baud_div_cnt == MCNT_BAUD)
        bit_cnt <= bit_cnt + 1'd1;

//位接收逻辑

    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        r_Rx_Data <= 8'd0;
    else if(baud_div_cnt == MCNT_BAUD/2)begin
        case(bit_cnt)
            1:r_Rx_Data[0] <= dff1_uart_rx;
            2:r_Rx_Data[1] <= dff1_uart_rx;
            3:r_Rx_Data[2] <= dff1_uart_rx;
            4:r_Rx_Data[3] <= dff1_uart_rx;
            5:r_Rx_Data[4] <= dff1_uart_rx;
            6:r_Rx_Data[5] <= dff1_uart_rx;
            7:r_Rx_Data[6] <= dff1_uart_rx;
            8:r_Rx_Data[7] <= dff1_uart_rx;
            default: r_Rx_Data <= r_Rx_Data;
        endcase     
    end

//接收完成标志信号
    assign w_Rx_Done = (baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9);
    
     always@(posedge Clk)
        Rx_Done <= w_Rx_Done;

//防止电平变化影响数据,提前存储赋值
//uart_rx是异步信号,外部输入的,防止亚稳态
     always@(posedge Clk)
     if(w_Rx_Done)
        Rx_Data <= r_Rx_Data;
        
        
endmodule

assign nedge_uart_rx = (dff1_uart_rx == 0) && (r_uart_rx == 1);

这边找到串口开始位的下降沿,这边看打拍,就知道应该是上一拍0这一拍1,然后就能输出使能。之前写过这个笔记。

 (baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9);

这个计数完成用一半的计数,是因为留一点时间给容错。因为时钟的问题。

posted @ 2024-03-22 18:13  祈愿树下  阅读(11)  评论(0编辑  收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css