写在前面:这是个FPGA串口收发的实验,发送一个字节,发送完返回一个字节(返回字节可以自己设定)。波特率是9600。
在B站的开发视频上改的,看不懂代码的去看一遍视频就可以了,链接是https://www.bilibili.com/video/BV1KE411h7AZ?p=15
这个是接收端,发送端在这个视频同期的上一个视频。
首先是发送端的模块:
/***************************************************
* Module Name : uart_byte_rx
* Engineer : 小梅哥
* Target Device : EP4CE10F17C8
* Tool versions : Quartus II 13.0
* Create Date : 2017-3-31
* Revision : v1.0
* Description : 串口接收模块设计
**************************************************/
module uart_byte_rx(
Clk, //模块时钟50M
Rst_n, //模块复位
baud_set, //波特率设置
Rs232_Rx, //RS232数据输入
data_byte, //并行数据输出
Rx_Done //一次数据接收完成标志
);
input Clk;
input Rst_n;
input [2:0]baud_set;
input Rs232_Rx;
output reg [7:0]data_byte;
output reg Rx_Done;
reg s0_Rs232_Rx,s1_Rs232_Rx;//同步寄存器
reg tmp0_Rs232_Rx,tmp1_Rs232_Rx;//数据寄存器
reg [15:0]bps_DR;//分频计数器计数最大值
reg [15:0]div_cnt;//分频计数器
reg bps_clk;//
reg [7:0]bps_cnt;
reg uart_state;
reg [2:0] r_data_byte [7:0];
//reg [7:0] tmp_data_byte;
reg [2:0] START_BIT,STOP_BIT;
wire nedege;
//////////////////////////////////////
/////////////////////////////////
//同步寄存器,消除亚稳态
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
s0_Rs232_Rx <= 1'b0;
s1_Rs232_Rx <= 1'b0;
end
else begin
s0_Rs232_Rx <= Rs232_Rx;
s1_Rs232_Rx <= s0_Rs232_Rx;
end
//数据寄存器
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
tmp0_Rs232_Rx <= 1'b0;
tmp1_Rs232_Rx <= 1'b0;
end
else begin
tmp0_Rs232_Rx <= s1_Rs232_Rx;
tmp1_Rs232_Rx <= tmp0_Rs232_Rx;
end
assign nedege = !tmp0_Rs232_Rx & tmp1_Rs232_Rx;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_DR <= 16'd324;
else begin
case(baud_set)
0:bps_DR <= 16'd324;
1:bps_DR <= 16'd162;
2:bps_DR <= 16'd80;
3:bps_DR <= 16'd53;
4:bps_DR <= 16'd26;
default:bps_DR <= 16'd324;
endcase
end
//counter
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
div_cnt <= 16'd0;
else if(uart_state)begin
if(div_cnt == bps_DR)
div_cnt <= 16'd0;
else
div_cnt <= div_cnt + 1'b1;
end
else
div_cnt <= 16'd0;
// bps_clk gen
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_clk <= 1'b0;
else if(div_cnt == 16'd1)
bps_clk <= 1'b1;
else
bps_clk <= 1'b0;
//bps counter
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
bps_cnt <= 8'd0;
el