FPGA串口通讯时波特率不稳定导致接受异常

一个FPGA项目中串口模块接收数据时发现经常出现接收异常的情况,上位机通过RS232串口下发相同的字符,FPGA接收却时常出现接收缓存不一致的情况。

不得不重新审核代码。波特率计算采样模块如下:


module uart_trigger(sysclk,rst,trigger,enable);

input		sysclk;	//系统时钟
input		enable;	//使能信号
output	trigger;	//采样沿
input		rst;		//复位信号

reg		[8:0]count;
reg		trigger;

always @(posedge sysclk )begin
	if(!rst | !enable)begin
		count <= 0;
		trigger <= 0;
	end
	else if(count == 9'd337)begin
		trigger <= 1'b1;
		count <= count + 1'b1;
	end
	else if(count == 9'd434)begin
		count <= 1'b0;
	end
	else begin
		count <= count + 1'b1;
		trigger <= 1'b0;
	end
end

endmodule



串口波特率为115200,系统时钟50Mhz

于是有如下计算:

时钟周期 = 20ns

UART接收单个bit时间 = 1000_000_000 ns / 115200  = 8680 ns

UART接收单个bit所耗时钟周期 = UART接收单个bit时间 / 时钟周期  = 8680 ns / 20ns = 434 个时钟周期

即每434个时钟周期采样一次RXD信号是最准确的

因为数据周期正中间的位置数据质量是最好的,因此在434 / 2即217个时钟周期的时候采样数据应该是最佳的选择

在上面的代码中,trigger信号在enable信号使能后217个时钟周期时输出一个时钟周期高电平,以后每隔434个时钟周期输出一个时钟周期高电平。

trigger信号提供接收模块最精准的采样时机。如此看来代码本身并没有BUG。

那到底是什么导致经常性采样值不准确?

经过SignalTab实时波形,发现计算机的输出串口时常出现不符合逻辑的情况,在串口发送数据相同的情况下(0x55),多次实时采样图如下:

FPGA串口通讯时波特率不稳定导致接受异常_第1张图片FPGA串口通讯时波特率不稳定导致接受异常_第2张图片FPGA串口通讯时波特率不稳定导致接受异常_第3张图片

可以看到RXD信号并不像理论上那样所想的,“在波特率的正中间采样,效果最好”

经过观察,发现在采样沿之后约120个时钟周期数据是最为稳定的,因此将代码

	else if(count == 9'd217)begin
		trigger <= 1'b1;
		count <= count + 1'b1;
	end
改为

	else if(count == 9'd337)begin
		trigger <= 1'b1;
		count <= count + 1'b1;
	end

经测试,串口接收缓存终于保持稳定。


目前的测试环境是Dtech的USB转RS232数据线,上述解决方法可能并不适用于其他串口。

改天多搞一些不同厂商的USB转串口线试一试吧,也许这只是个例呢。

所以说实践是检验真理的唯一标准,而理论只能作为参考依据。“理论上能工作“这样的话在电子的世界里就是废话一句。

不说了,该睡觉了。这是我第一篇博客,以后尽量把工作学习中遇到的问题写下来,让知识真正成为经验。欢迎各位看官常来看看。

你可能感兴趣的:(FPGA)