FPGA基础篇3-2:串口(UART)发送(2)

本文将进入程序设计部分:
第一:时序设计
在进行具体的串口设计之前,先了解通信协议。通常由以下四部分组成,起始位+数据位+校验位+结束位,但是在空闲状态线路上是1,当检测到是0来时就表示数据开始传输了。

在这里插入图片描述
话不多说(不懂时序的可以看一下其它博客),直接开始上程序:
下面就是波特率的设置,由于UART是异步串行通信,双方需要约定好时序才可以进行通信。(SPI是同步串行通信,所以在传输的时候会穿CLK)

parameter   Start_bit = 1'b0, Stop_bit = 1'b1;
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		bps_DR <= 16'd5207;//9600
	else begin
		case(baud_set)
			0:bps_DR <= 16'd5207;
			1:bps_DR <= 16'd2603;
			2:bps_DR <= 16'd1301;
			3:bps_DR <= 16'd867;
			4:bps_DR <= 16'd433;
			default:bps_DR <= 16'd5207;			
		endcase
	end	
//Uart波特率的控制,由上面波特率控制计数器决定,整个控制状态都是在传输状态的时候实现(Uart_State= 1 )
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Uart_cnt <= 4'd0;
		else if(Uart_State)begin
			if(Uart_cnt == bps_DR)
				Uart_cnt <= 16'd0;
			else
				Uart_cnt <= Uart_cnt + 1'b1;
		end
		else
			Uart_cnt <= 16'd0;
//下面就是波特率时钟脉冲的产生,因为只能产生一个系统时钟周期的高脉冲,所以可以下面那样写			
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Uart_clk <= 1'b0;
		else if(Uart_cnt == 1'b1)
			Uart_clk <= 1'b1;
		else
			Uart_clk <= 1'b0;
//下面就是在进行数据传输的计数,即在有数据传输的时候就会进行计数		
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Uart_bps_cnt <= 4'd0;
		else if(Uart_bps_cnt == 4'd11)
			Uart_bps_cnt <= 4'd0;
		else if(Uart_clk)
			Uart_bps_cnt <= Uart_bps_cnt + 1'b1;
		else 
			Uart_bps_cnt <= Uart_bps_cnt;
//下面通过计数,就可以选定该传什么值了			
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Tx_data <= 1'b1;
		else begin
			case(Uart_bps_cnt)
				0:Tx_data <= 1'b1;
				1:Tx_data <= Start_bit;
				2:Tx_data <= data_byte[0];
				3:Tx_data <= data_byte[1];
				4:Tx_data <= data_byte[2];
				5:Tx_data <= data_byte[3];
				6:Tx_data <= data_byte[4];
				7:Tx_data <= data_byte[5];
				8:Tx_data <= data_byte[6];
				9:Tx_data <= data_byte[7];
				10:Tx_data <= Stop_bit;
				default:Tx_data <= 1'b1;
			endcase
		end
	
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Tx_done <= 1'b0;
		else if(Uart_bps_cnt == 4'd11)
			Tx_done <= 1'b1;
		else
			Tx_done <= 1'b0;
	
	always @(posedge clk or negedge rst_n)
		if(!rst_n)
			Uart_State <= 1'b0;
		else if(Start_en)
			Uart_State <= 1'b1;
		else if(Uart_bps_cnt == 4'd11)
			Uart_State <= 1'b0; 
		else
			Uart_State <= Uart_State;

整个数据数据的传输(TX)主要可分为以下几个步骤实现:、
1.产生双方约定的波特率时钟的计数值(首先要计算好例如;时钟是50MHz 需要的时钟是9.6KHz 这些即计数:50000/9.6 = 5208 )
2.有了波特率计数值后就是产生这个计数值的计数器(但是一定要注意计数的条件是在数据传输的过程中进行)
3.有了计数就可以在计数的过程中,等于某个值的时候来表示生产波特率脉冲时钟(但是一定要在下一轮计数也是这个值)
3.有了计数脉冲,就可以根据这个脉冲进行计数,因为一共就传10个数(本例中:起始位(1个) + 数据位(8个)+停止位(1个))但是计数要计到11因为初始状态是要的
4.有了脉冲计数就可以根据计数值进行选择,传什么数出去了。
5.当计数值到11后就可以关掉计数的波特率计数器等等一些辅助操作了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值