10通信入门之串口接收

一设计功能

实现FPGA开发板能够收到PC发送的一字节数据,共8比特。串口接收一个是波特率,还有就是接收引脚的下降沿检测,最后就是数据接收的时序逻辑。在开始时,接收引脚是空闲状态,当接收引脚下降沿到来时,先来一个起始位,然后是八位的数据位,每到一个波特率时钟传输一个数据位,接收完八位数据后,八位数据位后就是停止位。接收引脚进入空闲态即高电平。要想稳定得接收数据,得有控制信号,如开始信号,接收完成信号等,这是方便模块的调用。

 

 

 

 

 

 

 

二设计输入

下面是串口接收的时序图,我设计程序就是根据这个照图施工。

 

module uart_rx(
input wire sclk,
input wire s_rst_n,
input wire rx,
output reg[7:0] po_data,
output reg po_flag

);

reg bit_flag;
//三个寄存器打三拍
//negedge detech
reg rx1;
reg rx2;
reg rx2_reg;
//位拼接符实现打三拍好奇妙
always@(posedge sclk or negedge s_rst_n)begin
if(s_rst_n==0)begin
rx1<=1;
rx2<=1;
rx2_reg <= 1;
end
else begin
{rx2_reg,rx2,rx1}<={rx2,rx1,rx};
end
end

//接收引脚的下降沿
reg rx_flag;
always @(posedge sclk or posedge s_rst_n) begin
if (s_rst_n==0) begin
rx_flag<=0;// reset

end
else if (!rx2 & rx2_reg) begin
rx_flag<=1;
end
else if(bit_cnt==4'd8 & bit_flag)
rx_flag<=0;
end
//波特率计数器
//注意if语句的优先级即越特殊范围越小放最前面
//如复位语句,最大值,条件的真子集
parameter cnt_HALF = 12'd2604;
parameter cnt_MAX = 13'd5207;
reg [12:0]cnt_baud;
always@(posedge sclk or negedge s_rst_n)
if(s_rst_n==0)
cnt_baud<='d0;
else if(cnt_baud==cnt_MAX)
cnt_baud<= 13'd0;
else if(bit_cnt==4'd8 & bit_flag)
cnt_baud<=13'd0;
else if(rx_flag)
cnt_baud<=cnt_baud+1'b1;


always@(posedge sclk or negedge s_rst_n)
if(s_rst_n==0)
bit_flag<=0;
else if(cnt_baud==cnt_HALF)
bit_flag<=1;
else
bit_flag<=0;

//if 语句的优先级
//如(bit_cnt==4'd8 & bit_flag)比(bit_flag)
//范围小,则小的放前面
reg [3:0]bit_cnt;
always @(posedge sclk or posedge s_rst_n) begin
if (s_rst_n==0) begin
bit_cnt<=0;// reset

end
else if(bit_cnt==4'd8 & bit_flag)
bit_cnt<=4'd0;
else if (bit_flag) begin
bit_cnt<=bit_cnt+1'b1;
end

end
//注意输出信号的同步赋值
//如bit_cnt 和po_data,po_flag在最后赋值为零
//都是在bit_flag拉高时
//所以要想让这三个个信号同时为低,则条件相同即bit_flag拉高
//如(bit_cnt>4'd1 & bit_cnt<=4'd8)这样会延迟一个时钟
always@(posedge sclk or negedge s_rst_n)
if(s_rst_n==0)
po_data<=8'b0;
else if(bit_cnt>4'd1 & bit_flag)
po_data<={rx1,po_data[7:1]};

//接收完成一个字节的标志信号
//po_flag
always@(posedge sclk or negedge s_rst_n)
if(s_rst_n==0)
po_flag <=0;
else if(bit_cnt==4'd8 & bit_flag)
po_flag<=1'b1;
else begin
po_flag<=0;
end

endmodule

注意点:主要是分频器和输出信号的赋值,分频器主要分成勒分频计数值和分配标志信号。输出则是数据信号和接收完成标志信号。

 

posted @ 2020-05-17 21:01  菜鸟芯片师  阅读(644)  评论(0编辑  收藏  举报