重温FPGA开发14

使用串口发送5个字节(40位)数据到电脑

  1. ADC采样的结果是12位的,怎么使用串口发送
  2. 16位数据,怎么通过串口发生
  3. 有多个字节的数据通过串口发送

UART就是规定了,发送的数据位 只能有6,7,8

12位的数据,就是4位+8位,比如想发生12位的数据
在这里插入图片描述

uart_tx_data.v

module uart_tx_data (
	clk,
	reset,
	data40,
	trans_go,
	uart_tx,
	trans_done
	);
	
	input clk;
	input reset;
	input [39:0]data40;
	input trans_go;
	ouput uart_tx;


	uart_byte_tx_uart_byte_tx(
	.clk(clk),
	.reset(reset),
	.data(data),
	.send_en(send_go),
	.baud_set(baud_set),
	.uart_tx(uart_tx),
	.tx_done(tx_done)
	);

两种情况:

  1. 没有开始发送(上一次的发送以及完成,新的40位数据的发送的请求没有出现)
  2. 来了发送40位数据的请求信号
  3. 依次发送数据的状态

**第一个状态:**第一种情况的时候,我们干什么事情呢?等待传输请求(trans_go)的到来,
data40[7:0] 给到 uart_byte_tx 的data,并同时产生 send_go 信号,启动第一个字节的发送

接着应该等待,等待tx_done 信号的到来
1. 40位的数据是否发完了?发完了?回到第一个状态继续等待 trans_go ,没发完,启动下一个8位数据的发送

状态机的概念:

module uart_tx_data (
	clk,
	reset,
	data40,
	trans_go,
	uart_tx,
	trans_done
	);
	
	input clk;
	input reset;
	input [39:0]data40;
	input trans_go;
	ouput uart_tx;
	ouput reg c;

	reg [7:0]data;
	reg send_go;
	wire tx_done;


	uart_byte_tx_uart_byte_tx(
	.clk(clk),
	.reset(reset),
	.data(data),
	.send_en(send_go),
	.baud_set(baud_set),
	.uart_tx(uart_tx),
	.tx_done(tx_done)
	);

	reg [2:0]state;
	always@(posedge clk or negedge reset)
	if(!reset) begin
		state <= 0;
		data <= 0;
		send_go <= 0;
		trans_done <= 0;
	end	
	else if (state == 0) begin
		trans_done <= 0;
		if(trans_go) begin
			data <= data40[7:0];
			send_go <= 1;
			state <= 1;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 0;
		end
	end
	
	else if(state == 1)begin
		// data <= data;
		if(tx_done)  // 一位数据发送完成
			 data <= data40[15:8];
			 send_go <= 1;
			 state <= 2;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 1;
		end
	end

	else if(state == 2)begin
		// data <= data;
		if(tx_done)  // 一位数据发送完成
			 data <= data40[23:16];
			 send_go <= 1;
			 state <= 3;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 2;
		end
	end

	else if(state == 3)begin
		// data <= data;
		if(tx_done)  // 一位数据发送完成
			 data <= data40[31:24];
			 send_go <= 1;
			 state <= 2;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 2;
		end
	end

	else if(state == 4)begin
		// data <= data;
		if(tx_done)  // 一位数据发送完成
			 data <= data40[39:32];
			 send_go <= 1;
			 state <= 5;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 4;
		end
	end
	
	else if(state == 5)begin
		// data <= data;
		if(tx_done)  // 一位数据发送完成
			 send_go <= 0;
			 trans_down <= 1;
			 state <=0 ;
		end
		else begin
			data <= data;
			send_go <= 0;
			state <= 5;
		end
	end


endmoudle

tb 文件

`timescale 1ns/1ns
module uart_tx_data_tb()
	reg clk;
	reg reset;
	reg [39:0]data40;
	reg trans_go;
	wire uart_tx;

uart_tx_data uart_tx_data(
	clk,
	reset,
	data40,
	trans_go,
	uart_tx
);


	initial clk = 1;
	always #10 clk = ~clk;

	initial begin
		reset = 0;
		data40 = 0;
		trans_go = 0;
		#201
		reset =1;
		#200;
		data40 = 40'h123456789a;
		trans_go = 1;
		#20;
		trans_go = 0;
	
		@(posedge trans_done);
		#200000;

		data40 = 40'ha987654321;
		trans_go = 1;
		#20;
		trans_go = 0;
		
		@(posedge trans_done);
		#200000;	
		$stop
		

endmodule

换一种写法:

module uart_tx_data (
	clk,
	reset,
	data40,
	trans_go,
	uart_tx,
	trans_done
	);
	
	input clk;
	input reset;
	input [39:0]data40;
	input trans_go;
	ouput uart_tx;
	ouput reg c;

	reg [7:0]data;
	reg send_go;
	wire tx_done;


	uart_byte_tx_uart_byte_tx(
	.clk(clk),
	.reset(reset),
	.data(data),
	.send_en(send_go),
	.baud_set(baud_set),
	.uart_tx(uart_tx),
	.tx_done(tx_done)
	);

	reg [2:0]state;
	always@(posedge clk or negedge reset)
	if(!reset) begin
		state <= 0;
		data <= 0;
		send_go <= 0;
		trans_done <= 0;
	end	

	else begin
		case(state)
			0:
			     begin
					trans_done <= 0;
					if(trans_go) begin
						data <= data40[7:0];
						send_go <= 1;
						state <= 1;
					end
					else begin
						data <= data;
						send_go <= 0;
						state <= 0;
					end
				end
		  1:	
				begin
					// data <= data;
					if(tx_done)  // 一位数据发送完成
						 data <= data40[15:8];
						 send_go <= 1;
						 state <= 2;
					end
					else begin
						data <= data;
						send_go <= 0;
						state <= 1;
					end
				end
			2:	
					begin
						// data <= data;
						if(tx_done)  // 一位数据发送完成
							 data <= data40[23:16];
							 send_go <= 1;
							 state <= 3;
						end
						else begin
							data <= data;
							send_go <= 0;
							state <= 2;
						end
					end
	
			 3:
						begin
							// data <= data;
							if(tx_done)  // 一位数据发送完成
								 data <= data40[31:24];
								 send_go <= 1;
								 state <= 2;
							end
							else begin
								data <= data;
								send_go <= 0;
								state <= 2;
							end
						end

			4:
						begin
							// data <= data;
							if(tx_done)  // 一位数据发送完成
								 data <= data40[39:32];
								 send_go <= 1;
								 state <= 5;
							end
							else begin
								data <= data;
								send_go <= 0;
								state <= 4;
							end
						end
	
			5:
					begin
						// data <= data;
						if(tx_done)  // 一位数据发送完成
							 send_go <= 0;
							 trans_down <= 1;
							 state <=0 ;
						end
						else begin
							data <= data;
							send_go <= 0;
							state <= 5;
						end
					end


endmoudle

小结:通过这个实验 实现了状态机的设计(优化 可否通过3个状态实现发送的功能,并且有易于修改为发送任意个字节的数据)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值