连续发送多个数据(uart串口RS232协议/verilog详细代码+仿真)

写在前言

以下内容详细源文件,已经上传个人主页资源,需要自取~

目录

          写在前言

需求分析

UART简介

整体架构流程

小结

需求分析

        使用串口(rs232协议)间隔1s连续发送16byte的数据。

由于每次发送的数据只有8bit,16byte=128bit,所以要发送16帧。

UART简介

这里实验所使用的参数有:rs232通信协议+9600bps+quartus18.0+modelsim2020

  • 异步通信:UART 是一种异步通信方式,这意味着发送和接收设备不需要共享同一个时钟信号。数据是以字符为单位进行传输的,每个字符通常包含起始位、数据位、奇偶校验位(可选)和停止位。
  • 数据格式:常见的数据位可以是 5 - 8 位,起始位为低电平,用于通知接收方数据传输开始;停止位通常是 1 - 2 位高电平,用于表示一个字符传输的结束;奇偶校验位用于简单的错误检测。

  • 波特率:UART 的传输速率由波特率决定,它表示每秒钟传输的符号数。常见的波特率有 9600bps、19200bps、38400bps、115200bps 等。(这里实验使用9600波特率)

整体架构流程

连续发送多个数据(uart串口RS232协议/verilog详细代码+仿真)_第1张图片

模块分析:

send_data模块:控制所要发送的数据;

uart_tx模块:串口发送模块

技术细节

本实验时序图

连续发送多个数据(uart串口RS232协议/verilog详细代码+仿真)_第2张图片

代码实现:

module send_data(
	
	input wire sys_clk,
	input wire sys_rst_n,
	input wire finish,		//当前8bit发送完成
	
	output reg pi_flag,			//发送标志信号
	output reg [7:0] pi_data	//发送数据
	
);
	
	//发送的8Byte数据存在数组里
	wire [7:0] data_mem [0:7];
	
	assign data_mem[0] = 8'h11;
	assign data_mem[1] = 8'h22;
	assign data_mem[2] = 8'h33;
	assign data_mem[3] = 8'h44;
	assign data_mem[4] = 8'h55;
	assign data_mem[5] = 8'h66;
	assign data_mem[6] = 8'h77;
	assign data_mem[7] = 8'h88;
	
	reg [31:0] delay_cnt;		//用于计数1s
	reg [3:0] send_byte_num;	//发送字节个数计数
	
	parameter IDLE = 2'd0;
	parameter S0 = 2'd1;
	parameter S1 = 2'd2;
	parameter S2 = 2'd3;
	
	parameter TIME_1S = 32'd49_999_999;
	
	reg [1:0] state;
	
	//一段式状态机
	always @ (posedge sys_clk or negedge sys_rst_n)
		begin
			if(~sys_rst_n)
				begin
					state <= IDLE;
					delay_cnt <= 32'd0;
					send_byte_num <= 4'd0;
					pi_flag <= 1'd0;
					pi_data <= 8'h00;
				end
			else case(state)
				IDLE:	//等待1s
					begin
						send_byte_num <= 4'd0;
						pi_flag <= 1'd0;
						pi_data <= 8'h00;
					
						if(delay_cnt == TIME_1S)
							begin
								state <= S0;
								delay_cnt <= 32'd0;
							end
						else
							begin
								delay_cnt <= delay_cnt + 1'd1;
							end
					end
				S0:		//开始发送1帧(8bit)数据
					begin
						pi_flag <= 1'd1;
						pi_data <= data_mem[send_byte_num];
						state <= S1;
					end
				S1:		//等待当前帧发送完成
					begin
						pi_flag <= 1'd0;
						
						if(finish)
							begin
								state <= S2;
								send_byte_num <= send_byte_num + 1'd1;
							end
					endsh
				S2:		//判断是否发送8次
					begin
						if(send_byte_num < 4'd8)
							begin
								state <= S0;
							end
						else
							begin
								state <= IDLE;
								send_byte_num <= 4'd0;
							end
					end
				default:
					begin
						state <= IDLE;
						delay_cnt <= 32'd0;
						send_byte_num <= 4'd0;
						pi_flag <= 1'd0;
						pi_data <= 8'h00;
					end
				endcase		
		end

endmodule

小结

下期预告:用scfifo作为数据缓存,再将数据读出发送回来

本实验可能遇到的问题:

1.为什么要设置finish信号?

        一帧结束之后,下一帧发送需要一个标志信号,来指示下一帧的发送,设定帧发送完成标志信号能更好的保证数据连续发送

2.在发送模块,数据出现错误怎么办?

        一般来说,数据出错主要有一下几点原因:1、标志信号设置有误,没有到达指定区间就让标志信号拉高;2、发送模块逻辑错误,没有严格按照rs232数据格式进行传输等等

你可能感兴趣的:(fpga开发,嵌入式硬件,matlab,智能硬件)