1.使用uart_rx模块作为图像接受模块
- 波特率的计算
波特率:每秒钟通过信号传输的码元数称为码元的传输速率
使用时钟频率 除以 波特率 可以得到传输每个码源所占用的时钟周期数
$baud_cnt_max = $
- 为什么要做打两拍操作
消除亚稳态,稳定信号。
在找下降沿时,不能使用\(rx\_reg1\)
和\(rx\_reg2\) 求得,因为\(rx\_reg1\)
信号不稳定,使用其求得的结果也不稳定,因此将 \(rx\_reg2\)再打一拍,使用\(rx\_reg2\) 和 \(rx\_reg3\) 求得。
- 代码中 \(bit\_cnt\) 只计数到8
这是因为没有计数停止位,所以只有0~8 共计数
9位(1位起始位+8位数据位)。
- rs232数据移位方向:
最先传输的比特在低位,最后传输的比特在高位
PC机通过串口调试助手往FPGA发8bit数据时,FPGA通过串口线rx一位一位地接收,从最低位到最高位依次接收,最后在FPGA里面位拼接成8比特数据。
- 代码:
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
| module uart_rx #parameter ( parameter UART_BPS = 'd9600, CLK_FREQ = 'd50_000_000 ) ( input sys_clk,sys_rst_n, input rx,
output reg [7:0] po_data, output reg po_flag );
localparam BAUD_CNT_MAX = CLK_FREQ / UART_BPS;
reg rx_reg1; reg rx_reg2; reg rx_reg3; reg start_nedge; reg work_en; reg [12:0] baud_cnt; reg bit_flag; reg [3:0] bit_cnt; reg [7:0] rx_data; reg rx_flag;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) rx_reg1 <= 1'b0; else rx_reg1 <= rx;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) rx_reg2 <= 1'b0; else rx_reg2 <= rx_reg1;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) rx_reg3 <= 1'b0; else rx_reg3 <= rx_reg2;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) start_nedge <= 1'b0; else if(rx_reg2 == 1'b0 && rx_reg3 == 1'b1) start_nedge <= 1'b1; else start_nedge <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) work_en <= 1'b0; else if(start_nedge == 1'b1) work_en <= 1'b1; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) work_en <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) baud_cnt <= 13'b0; else if(baud_cnt == BAUD_CNT_MAX - 1 && work_en == 1'b1) baud_cnt <= 13'b0; else if(work_en == 1'b1) baud_cnt <= baud_cnt + 1; else baud_cnt <= 13'b0;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) bit_flag <= 1'b0; else if(baud_cnt == BAUD_CNT_MAX / 2 - 1) bit_flag <= 1'b1; else bit_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) bit_cnt <= 4'b0; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) bit_cnt <= 4'd0; else if(bit_flag == 1'b1) bit_cnt <= bit_cnt + 1;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) rx_data <= 8'b0; else if(bit_flag == 1'b1 && bit_cnt >= 4'd1 && bit_cnt <= 4'd8) rx_data = {rx_reg3,rx_data[7:1]};
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) rx_flag <= 1'b0; else if(bit_cnt == 4'd8 && bit_flag == 1'b1) rx_flag <= 1'b1; else rx_flag <= 1'b0;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) po_data <= 8'b0; else if(rx_flag == 1'b1) po_data <= rx_data;
always@(posedge sys_clk or negedge sys_rst_n) if(sys_rst_n == 1'b0) po_flag <= 1'b0; else po_flag <= rx_flag;
endmodule
|