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);
这个计数完成用一半的计数,是因为留一点时间给容错。因为时钟的问题。
本文来自博客园,作者:祈愿树下,转载请注明原文链接:https://www.cnblogs.com/cjl520/p/18090186