基于FPGA实现UART协议,最终在显示器上实现图片传输

1.原理图,需要用到5个模块。分别是时钟分频模块,ram随机存储模块,uart发送、接收检测模块,vga图像显示模块。  

                                          

2.这次属于模块的顶层例化,比较难想明白的是,如果终端图片发送,写地址清零。而且很多细节问题需要多次调试,第一次实现图片回传与上位机检测,发现上位机可以接收到回传信息。。第一次调试发现图片不能中断传输,原因是我触发条件写错了,只能计数器记到1。第二次图片一直上传不到显示器上,经过观测发现写地址一直处于清零状态,原因是我没给清理标志位清零。

module	ram_ctrl(
		input wire rst_n,
		input wire sclk,
		input wire rd_en, 
		input wire flag_o,
		input wire [7:0]data_o,
		
		output wire [7:0]ram_data
);

reg [15:0] addra_space;
reg	[15:0] addrb_space;
reg [15:0] cnt_clean;

parameter CNT_CLEAN=28888;
blk_mem_39999 blk_mem_39999_inst (
 			 .clka(sclk), // 输入25M的全局时钟 
 			 .wea(flag_o), // input [0 : 0] wea
 			 .addra(addra_space), // input [15 : 0] addra
 			 .dina(data_o), // input [7 : 0] dina
 			 .clkb(sclk), // 输入25M的全局时钟
 			 .addrb(addrb_space), // input [15 : 0] addrb
 			 .doutb(ram_data) // output [7 : 0] doutb
);  

always@(posedge sclk or negedge rst_n)   //ram输入信号清零计数器
		if(!rst_n)
		cnt_clean<=16'd0;
		else if(flag_o==1'b1)			//  少写了清零条件,导致写地址一直处于清零状态
				cnt_clean<=16'd0;		
		else if(cnt_clean==CNT_CLEAN)
					cnt_clean<=16'd0;	// 优先级
		else if(flag_o==1'b0)  		 	//flag_o==1'b1,当时想的就是拉高开始计数,结果发现根本不计数
			cnt_clean<=cnt_clean+1'b1;	//因为标志位拉高只有一个时钟周期,应该记拉低的时钟周期。
			


			
always@(posedge sclk or negedge rst_n)   //为ram输入地址分配空间
		if(!rst_n)
			addra_space<=16'd0;
		else if(cnt_clean==CNT_CLEAN)
				addra_space<=16'd0;
		
		else if(addra_space==39999&&flag_o==1'b1)
				addra_space<=16'd0;
		
				else if(flag_o==1'b1)
					addra_space<=addra_space+1'b1;
					
always@(posedge sclk or negedge rst_n) 	//为ram输出地址分配地址空间
		if(!rst_n)
			addrb_space<=16'd0;
		else if(addrb_space==39999)
			addrb_space<=16'd0;
		else if(rd_en==1'b1)
			addrb_space<=addrb_space+1'b1;

endmodule

     清零控制位需要多次调试,最重要的是要想清楚清零计数器记的是那个位置的始终周期。只要ram IP核控制好,就可以实现这次实践的功能。

3.顶层模块例化主要是uart模块的发送端与接收端与fpga的链接。对于fpga uart的接受端链接的是fpga的发送模块,uart的发送端链接的是fpga的接受端。整个模块fpga为主控芯片。

module	top(

	input 	wire		 sclk_in,
	input 	wire		 rst_n,
	input	wire	     rx_in,
	output 	wire		 h_sync,v_sync,
	output 	wire [7:0]	 rgb_data,
	output  wire         data
);

wire sclk;
wire rd_en;
wire [7:0]ram_data;
wire flag_o;
wire [7:0]data_o;

vga_ctrl vga_ctrl_inst(
			. sclk		(sclk),
			. rst_n		(rst_n),
			.rd_en      (rd_en),
			.ram_data	(ram_data),
			.h_sync		(h_sync),
			.v_sync		(v_sync),
			.rgb_data   (rgb_data)
);

clk_50_25 clk_50_25_inst
   (// Clock in ports
    .CLK_50(sclk_in),      // IN
    // Clock out ports
    .CLK_25(sclk));  

ram_ctrl	ram_ctrl_inst(
		.rst_n		(rst_n),
		.sclk		(sclk),
		.rd_en		(rd_en), 
		.flag_o		(flag_o),
		.data_o		(data_o),
		.ram_data    (ram_data)
);

tx_crtl tx_crtl_inst(

				.sclk		(sclk),
				.rst_n		(rst_n),
				.rx_in		(rx_in),
				
				.flag_o		(flag_o),
				.data_o     (data_o)
);

uart_crtl	uart_crtl_inst(

			.sclk		(sclk),
			.rst_n		(rst_n),
			.data_in	(data_o),
			.flag_in	(flag_o),
			.data_o     (data)

);
endmodule

猜你喜欢

转载自blog.csdn.net/Headogerz/article/details/81865092