FPGA之串口收发字符串控制HMI串口屏之(二)——接收模块

今天,对之前写好的UART程序进行了进一步优化,解决了历史遗留问题。

先回顾一下,上一节写到的发送模块,这里作特别说明:本次串口模块主要是用于控制HMI屏幕的(之前也有提到),因为是特定的目标对象,所以也就要具体问题具体对待。比如:之前的串口发送模块的写法与常规的写法有所不同,主要就是:一般地,可以将串口的应用分为两种,一者是接收模块和发送模块一起使用,构成回环的形式(比如FPGA的实验课中,板子收到PC的XXXX数据,板子进行判断是不是特定的数据包,是的话就向PC回发YYYY数据,或者简单一点,就是直接将收到的数据回发给PC,谓之回环)。这种方式看起来好像有点…,但着实让你学着去理解和书写串口代码。

而实际中,我们更多的不是这种一收一发的方式,而是发送独立于接收,更具自主性和灵活性,我写的代码则属于后者,其实这里可能根本用不到串口接收,在HMI串口屏实现中,更多的是让MCU(FPGA)向HMI发送指令数据。故在如何启动BAUD_Generator时,没有采用检测接收模块的start(波特率发生器启动信号)的下降沿(结束信号)作为发送模块的启动信号,而是自定义了一个输入数据请求脉冲信号作为波特率发生器的启动信号。

对偶发送模块,接收模块数据流动方式为串入并出。不同于发送模块的是,接收方需要判断RXD数据线的下降沿,并将其视为一帧新的数据的到来标志,到来后就发起波特率发生器启动信号。

NOTE:下降沿判断时下降沿寄存器(2bit)的初始值应该赋值为2'b00的形式,防止刚进入的数据位0的情况,造成虚假下降沿的误判断。

说到这,实际上还是万变不离其宗,没有张三,一定会有李四出现,你得学着思考,怎么来解决这个问题。

上面说完了发送的遗留问题,继续探讨接收模块,以下绿颜色的字为关键接收流程

实际上发送和接收大同小异,在接收上采用判断输入信号的下降沿作为波特率发生的启动信号。

如下:

/***************波特率启动位置位与清零*******************/
always @ (posedge clk, negedge rst_n)
begin
	if (!rst_n)
		rx_bps_start <= 1'b0;
	else if (nedge_flag && bit_cnt == 0) 	 	 	 	 	 	 //实际上,可以不需要bit_cnt == 0这个条件,
		rx_bps_start <= 1'b1; 	 	 	 	  	 	 	 	  		 //由于是reg型变量,具有保持作用,所以只要满足
	else if (bit_cnt == 4'd10) 	 		 	 	  		 	    //nedge_flag就会一直触发启动知道bit_cnt == 4'd10
		rx_bps_start <= 1'b0;	 	 	 	 	  			 		 //这时就会关闭start,而bit_cnt也就停在0,下一次数据来时
	end                            				   	 	 	    //就重复上述过程,所以不需要bit_cnt == 0这个条件
 
/***************bit_cnt计数*******************/
always @ (posedge clk, negedge rst_n)
begin
	if (!rst_n)
		bit_cnt <= {REC_WID{1'b0}};
	else if (rx_bps_flag)
		bit_cnt <= bit_cnt + 1'b1;
	else if (bit_cnt >= 4'd10)
		bit_cnt <= {REC_WID{1'b0}};
end


always @ (posedge clk, negedge rst_n)
begin
	if (!rst_n)
		n_edge_reg <= 2'b00; 	 	 	 	 	 	 	 	  	 	   //应该写成2'b00的形式,防止刚进入的数据位0的情况
	else
		n_edge_reg <= {n_edge_reg[0] ,RXD};
end

//assign n_edge = n_edge_reg; 	  		 	  	  	 	 	 		//数据流检测出
assign nedge_flag = (n_edge_reg == 2'b10) ? 1'b1 : 1'b0; 	//下降沿到来
/********************END**********************/

此后,在rx_bps_flag信号下快乐将数据串行写进变量中即可,在最后一拍bit_cnt == 4'd10时将数据并行发出即可完成串口的接收模块。哈哈,其实接收的程序好像更容易理解。

注意:发送模块是要自定义10位数据格式的,即起始位为0,停止位为1,而接收模块是将所有bit先接收,最后取出用户数据即可(本程序是dataout_buf[8 : 1])。

 

相关完整代码连接如下:

https://download.csdn.net/download/huigeyu/11162955

如有需要,请自行下载!如有问题,欢迎讨论!

 

 

你可能感兴趣的:(FPGA设计开发)