UART串口接收代码--------学术不精的小小见解

module receive(
input        sys_clk,
input        rst_n,
input        uart_rxd,
output       uart_done,
output  [7:0]uart_data
);


wire        uart_en;
wire   [7:0]uart_din;
parameter   bps=115200;
parameter   clk_freq=50000000;
localparam   cnt=434;
parameter   sum=4340;
reg          start_flag;
reg          rx_flag;
reg    [15:0]clk_cnt;
reg    [3:0] rx_cnt;//数据计数
reg    [15:0]cnt_sum;//为rx_flag计数
reg          data_done;
reg     [7:0]data;
reg     [7:0]dataout;
wire         signal_down;
reg          signal_delay_down;
//下降沿 start_flag
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n) 
signal_delay_down <= 1'b1; 
else  
signal_delay_down <= uart_rxd; 
end
assign signal_down = (signal_delay_down && ~uart_rxd);
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
start_flag<=1'b0;
else if(clk_cnt<200)
start_flag<=signal_down;
else start_flag<=1'b0;
end
//rx_flag
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
cnt_sum<=15'd0;
else if(start_flag)
cnt_sum<=15'd1;
else if(cnt_sum>15'd0 && cnt_sum<(sum-1))
cnt_sum<=cnt_sum+1'b1;
else cnt_sum<=15'd0;
end
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
rx_flag<=1'b0;
else if(cnt_sum>15'd0 && cnt_sum<(sum-1))
rx_flag<=1'b1;
else if(rx_cnt==4'd9 && clk_cnt==cnt-1)
rx_flag<=1'b0;
else
rx_flag<=rx_flag;
end
//clk_cnt
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
clk_cnt<=16'd0;
else if(rx_flag && clk_cnt<(cnt-1))
clk_cnt<=clk_cnt+1'b1;
else if(clk_cnt==cnt-1)
clk_cnt<=16'd0;
end
//rx_cnt
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
rx_cnt<=4'd0;
else if(rx_flag && clk_cnt==(cnt-1))
rx_cnt<=rx_cnt+1'b1;
else if(rx_cnt==4'd10)
rx_cnt<=4'd0;
end
//uart_done
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
data_done<=1'b0;
else if(rx_cnt==4'd9)
data_done<=1'b1;
else 
data_done<=1'b0;
end
assign  uart_done=data_done;
//输出数据
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
data<=8'd0;
else if(rx_flag)
if(clk_cnt==cnt/2) begin  //判断系统时钟计数器计数到数据位中间
case (rx_cnt)
4'd1 :data[0] <=uart_rxd;   //寄存数据位最低位
4'd2 :data[1] <=uart_rxd;
4'd3 :data[2] <=uart_rxd;
4'd4 :data[3] <=uart_rxd;
4'd5 :data[4] <=uart_rxd;
4'd6 :data[5] <=uart_rxd;
4'd7 :data[6] <=uart_rxd;
4'd8 :data[7] <=uart_rxd;   //寄存数据位最高位
default:;                                    
endcase
end
else 
data<= data;
else
data<= 8'd0;
end
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
dataout<=8'd0;
else if(uart_done)
dataout<=data;
else dataout<=8'd0;
end
assign uart_data=dataout;

endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值