xilinxFPGA-串口发送和接收模块实例详解(基于verilog)

xilinxFPGA-串口发送和接收模块实例详解(基于verilog)

串口原理

首先我们得直到串口是怎样进行通信的。
在这里插入图片描述
我们可以看到,串口通讯的数据格式是由一位起始位、七个数据位(其中最后一位数据位可以作为检验位来使用。)、一位停止位,在空闲时刻为高电平,当我们使用串口发送时,就可以按照这种时序进行发送,接收时也要按照这种时序进行接收。

波特率计算

什么是波特率?

每秒钟发送的数据个数。

概念很简单,我们需要怎样去计算呢?常见的波特率有 9600192003840057600115200

波特率计算:
9600:1_000_000_000 / 9600;
19200:1_000_000_000 / 19200;
38400:1_000_000_000 / 38400;
57600:1_000_000_000 / 57600;
115200:1_000_000_000 / 115200;

这儿的 1_000_000_000 是代表 1s 因为我的开发板是以 ns 为时间单位的,所以我的波特率计算也是以 ns 为时间单位。

串口发送

发送思路原理:我们可以通过定义一个计数器,来记录每次发送所需要的的时间,然后用一个状态机来记录发送的状态。
module uart_tx_bottom(
	input Clk,	//定义输入时钟信号。
	input Reset_n,	//定义复位信号。
	input [7:0]Data,	//定义需要发送的八位数据。
	input Send_en,	//定义发送使能信号,此信号为1时才可以发送数据。	
	output reg uart_tx,	//定义发送信号,reg型是因为需要在always块中给它赋值。
	output reg Tx_done	//定义发送完成标志信号,以便下次发送数据。
);
	parameter Band_Set = 433;	//这儿是利用时钟计数发送一位的时间,1_000_000_000 / 115200 / 20 - 1// 其中 / 20 是因为我的开发板时钟周期为20ns, - 1 是因为计数器从0开始计数,原本算出需要计数434次,只需要加到433时就是434次了。
	reg [3:0]bps_cnt;	//数据发送状态,因为发送有起始位,数据位,结束位,用这个来记录数据发送到哪个位置了。
	reg [17:0]div_cnt;	//一位数据位发送时间计数器,记录发送数据的时间,用于更新下一段数据。
	wire bps_clk;	//每一位发送数据前后的标志位,具体作用后面会讲到。
	
	always @(posedge Clk or negedge Reset_n)	begin	//定义一个计数器的always块。
		if (!Reset_n)
			div_cnt <= 0;	//若复位将计数器归0.
		else if (Send_en)	begin	//如果有使能才可以进行自加。
			if (Band_Set <= div_cnt)	//当中间<=写法错误时,这种写法会让编辑器自动报错,可以减少因为没注意而引发的功能错误,而且使用<=可以对未知的情况进行判断,增加程序的健壮性。
				div_cnt <= 0;	//当计数器记满时,计数器归0.
			else
				div_cnt <= div_cnt + 1'b1;	//计数器未记满,每个时钟上升沿自加1.
		end
		else
			div_cnt <= 0;	//没有使能信号,使计数器归0
	end
		
	assign bps_clk = (div_cnt == 1);	//当每次计数器记到 1 的时候就让数据开始发送,因为如果div_cnt == Band_Set,在每次发送时还需要等待一个数据位的时间数据才会发送,而这样定义后只需要等待1个时钟周期数据就会发送了。因为bps_clk是wire类型的,所以用assign语句赋值,而不是用always语句赋值。
	
	always @(posedge Clk or negedge Reset_n)	begin	//定义发送状态块,记录发送的状态。
		if (!Reset_n)
			bps_cnt <= 0;	//	若是复位,状态为0else if (Send_en)	begin	//发送使能,状态才会改变。
			if (bps_clk)	begin	//当有发送的标志时,状态才自增一次。
				if (bps_cnt == 11)
					bps_cnt <= 0;	//当状态计数到第11个状态,状态归0else
					bps_cnt <= bps_cnt + 1'b1;	//状态自增1。
			end
		end
		else
			bps_cnt <= 0;	//发送不使能,状态归0end
	
	always @(posedge Clk or negedge Reset_n)	begin	//串口发送块。
		if (!Reset_n)
			uart_tx <= 1;	//当复位时,数据线发
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值