FPGA UART发送与接收

背景

最近刚开始接触FPGA,在大概看了基本教材学习了Verilog后就买了一块黑金的开发板,开始正儿八经的撸代码。然后就到了UART通信这一节,基本上例程都是顶层模块例化UART收发模块,作者觉得这样不能很好的理解UART的底层协议,UART发送具体是怎么发送,又怎么接收,也不想直接ctrl+ch和ctrl+v,然后作者在参考正点原子的代码后,通过状态机实现500ms发送一个字节的数据和UART接收,具体请看下文,还有请正点原子支付下广告费。

协议

如下图所示,UART通信需要三根线,一根发送TX,一根接收RX,还有一根地。总线(TX和RX)空闲时处于高电平,发送方发送数据时,先发送起始位(逻辑0),然后以地为在前、高位在后的顺序将一个字节的每一个比特位发送出去(这一字节可以是7位或者8/9位),数据发送完成后,再发送1位校验位和停止位(可以是1位或者2位,逻辑1)。接收方的RX是与发送方的TX连接在一起的,因此,接收方检测RX上是否存在下降沿,是,则准备开始接收,因为UART通信没有时钟,因此只能规定多少时间发送一个比特位来保证数据收发不会出错,这就是比特率(或者说是波特率),单位是比特每秒(bit/s),一般情况下 ,比特率使用9600和115200,。本次作者的UART通信是采用8位数据位,1位停止位,没有奇偶检验位,共10位。
在这里插入图片描述

代码编写

协议清楚后开始撸代码。

UART发送

作者的思路是用状态机进行数据发送,初始化、发送、结束,发送周期是500ms,波特率是9600,系统频率是50MHz,所以需要对时钟脉冲计数50_000_000/9600=5208.33个,取整5208。下面是代码。

`timescale 1ns/1ps

module uart_tx(
			input    		clk,
			input			rst_n,
			
			output	reg		tx_pin);

parameter   	CLK_FREQ		=50000000,
				BPS				=9600,
				BPS_CNT			=CLK_FREQ/BPS;
				
parameter 		IDLE  =4'd0,
				SEND  =4'd1,
				END   =4'd2;
				
reg[7:0]		data_buf;
reg[24:0]		cnt1;//500ms 计数寄存器
reg				tx_start;//计时到了置1,并开始发送
//计时500ms
always@(posedge clk,negedge rst_n)
if(!rst_n)
  begin
    cnt1<=0;  
	tx_start<=0;
  end
else  if(cnt1==25000000)
  begin 
    cnt1<=0;
	tx_start<=~tx_start;
  end
 else
	cnt1<=cnt1+1;
	
	
reg[3:0]	tx_cnt;
reg[24:0]	clk_cnt;
reg[3:0]	state;
always@(posedge clk,negedge rst_n)
if(!rst_n)
  begin
    state<=IDLE;
	data_buf<=8'h5A;
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值