项目名称
UART收发整合
项目要求
上位机将数据发送出去,fpga接收到数据之后发送给上位机
项目说明
这个小项目就是将接收器和发送器进行整合成一个简易的串口模块,下面是模块框图,比较简单。
代码设计
顶层模块
module uart_top(
input clk,
input rst_n,
input rs232_data,
output rs232_tx//发送的数据
);
wire [7:0] data;
wire flag;
uart_rx
#(. bps_cnt_end(5207))
uart_rx
(
. clk(clk),
. rst_n(rst_n),
. rs232_data(rs232_data),
. data(data),
. flag(flag)
);
uart_tx uart_tx(
.clk(clk),
.rst_n(rst_n),
.tx_data(data),//需要发送的数据
.tx_flag_start(flag),//发送标志信号
.rs232_tx(rs232_tx)//发送的数据
);
endmodule
接收模块
module uart_rx
#(parameter bps_cnt_end=5207)
(
input clk,
input rst_n,
input rs232_data,
output reg [7:0]data,
output reg flag
);
//串口数据同步处理
reg rx_data1;
reg rx_data2;
reg rx_data3;
always@(posedge clk or negedge rst_n)
if(!rst_n)begin
rx_data1<=0;
rx_data2<=0;
rx_data3<=0;
end
else begin
rx_data1<=rs232_data;
rx_data2<=rx_data1;
rx_data3<=rx_data2;
end
//下降沿起始位检测
wire nedge= !rx_data2 & rx_data3;
reg data_flag;
reg [12:0]bps_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
bps_cnt<=0;
else if(data_flag)begin
if(bps_cnt<5207)
bps_cnt<=bps_cnt+1;
else
bps_cnt<=0;
end
else
bps_cnt<=0;
reg [3:0] data_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
data_flag<=0;
else if(nedge)
data_flag<=1;
else if(bps_cnt==5205 && data_cnt==10)
data_flag<=0;
reg data_sample;
reg [12:0] bps_cnt_mid=bps_cnt_end/2+1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
data_sample<=0;
else if(data_flag && bps_cnt==bps_cnt_mid)
data_sample<=1;
else
data_sample<=0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
data_cnt<=0;
else if(data_sample)begin
if(data_cnt<10)
data_cnt<=data_cnt+1;
else
data_cnt<=1;
end
else
data_cnt<=data_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
flag<=0;
else if(data_cnt==9 && bps_cnt==bps_cnt_mid+3)
flag<=1;
else
flag<=0;
//接收数据
always@(posedge clk or negedge rst_n)
if(!rst_n)
data<=0;
else if(data_sample && data_cnt>=1 && data_cnt<=8)
data<={rx_data3,data[7:1]};
else
data<=data;
endmodule
发送模块
module uart_tx(
input clk,
input rst_n,
input [7:0] tx_data,//需要发送的数据
input tx_flag_start,//发送标志信号
output reg rs232_tx//发送的数据
);
reg [7:0] tx_data_r;
reg tx_flag;
always@(posedge clk or negedge rst_n)
if(!rst_n)
tx_data_r<=0;
else if(tx_flag_start && tx_flag==0)
tx_data_r<=tx_data;
reg bit_flag;
reg [3:0] data_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
tx_flag<=0;
else if(tx_flag_start && tx_flag==0)
tx_flag<=1;
else if(data_cnt==8 && bit_flag)
tx_flag<=0;
reg [12:0] bps_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
bps_cnt<=0;
else if(bps_cnt==5207)
bps_cnt<=0;
else if(tx_flag)
bps_cnt<=bps_cnt+1;
else
bps_cnt<=0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
bit_flag<=0;
else if(tx_flag && bps_cnt==5207)
bit_flag<=1;
else
bit_flag<=0;
always@(posedge clk or negedge rst_n)
if(!rst_n)
data_cnt<=0;
else if(data_cnt==8 && bit_flag)
data_cnt<=0;
else if(bit_flag && tx_flag)
data_cnt<=data_cnt+1;
else
data_cnt<=data_cnt;
always@(posedge clk or negedge rst_n)
if(!rst_n)
rs232_tx<=1;
else if(tx_flag)
case(data_cnt)
0:rs232_tx<=0;
1:rs232_tx<=tx_data_r[0];
2:rs232_tx<=tx_data_r[1];
3:rs232_tx<=tx_data_r[2];
4:rs232_tx<=tx_data_r[3];
5:rs232_tx<=tx_data_r[4];
6:rs232_tx<=tx_data_r[5];
7:rs232_tx<=tx_data_r[6];
8:rs232_tx<=tx_data_r[7];
default:rs232_tx<=1;
endcase
else
rs232_tx<=1;
endmodule
显示结果
发送16进制数据可以正常接收