FPGA实现串口通信

1.原理介绍:FPGA实现串口通信,将8bit的数据按照从地位到高位的串口发送。将原理图P上来。

2.通过与按键消抖模块利用top_down,让按键按一次,实现自加1,加到1111_1111。

    按键产生数据程序:

module gen_data(
		
		input wire sclk,
		input wire rst_n,
		input wire key_out_in,
		
		output reg[7:0]  gen_data_out,
		output reg  flag
);

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			gen_data_out<=8'd0;
		else if(key_out_in==1'b1)
			gen_data_out<=gen_data_out+1'b1;
			
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			flag<=1'b0;
		else if(key_out_in==1'b1)
					flag<=1'b1;  //修改后的条件
				else flag<=1'b0;


endmodule

       串口通信协议模块:

module uart_crtl(

			input wire sclk,
			input wire rst_n,
			input wire [7:0] data_in,
			input wire flag_in,
			
			output reg data_o

);

reg	[12:0]	cnt;
reg	[3:0]   bit_cnt;
reg			tx_en;
parameter  CNT=5207;
parameter  BIT_CNT=9;

//tx_en
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			tx_en<=1'b0;
			else if(flag_in==1'b1)
				tx_en<=1'b1;
				else if(bit_cnt==BIT_CNT&&cnt==CNT)
			tx_en<=1'b0;
//cnt 波特率计数
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)		
			cnt<=13'd0;
		else if(cnt==CNT)	
			cnt<=13'd0;
			else if(tx_en==1'b1)	  //条件没写对
					cnt<=cnt+1'b1;
				
//bit_cnt 字节统计
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)	
			bit_cnt<=4'd0;
		else if(tx_en==1'b0)
				bit_cnt<=4'd0;
		else if(bit_cnt==BIT_CNT&cnt==CNT)
				bit_cnt<=4'd0;
			else if(cnt==CNT)
				bit_cnt<=bit_cnt+1'b1;
				
//输出数据控制
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)	
		data_o<=1'b1;
		else if(tx_en==1'b1&&bit_cnt==10'd0)  //flag_in==1'b1
			data_o<=1'b0;
			else if(bit_cnt==10'd1)
				data_o<=data_in[0];
				else if (bit_cnt==10'd2)
					data_o<=data_in[1];
					else if(bit_cnt==10'd3)
						data_o<=data_in[2];
						else if(bit_cnt==10'd4)
							data_o<=data_in[3];
							  else if(bit_cnt==10'd5)	
		  							data_o<=data_in[4];
		  							else if(bit_cnt==10'd6)
		  									data_o<=data_in[5];
										else if(bit_cnt==10'd7)
					 						data_o<=data_in[6];
									 		else if(bit_cnt==10'd8)
									 				data_o<=data_in[7];
													else if(bit_cnt==BIT_CNT)
															data_o<=1'b1;
															else data_o<=1'b1;
					
endmodule

     说明 if_else模块也可以用case语句实现,下边的代码就是利用case语句实现数据传输:

always@(posedge sclk or negedge rst_n)  //输入输出数据串并转换
		if(!rst_n)	
			data_o<=1'b1;
			else if(tx_en==1'b1&&cnt_bit==4'd0)
				data_o<=1'b0;	
				else case(cnt_bit)
						4'd1:	data_o<=data_in[0];
						4'd2:	data_o<=data_in[1];	
						4'd3:	data_o<=data_in[2];
						4'd4:	data_o<=data_in[3];	
						4'd5:	data_o<=data_in[4];	
						4'd6:	data_o<=data_in[5];
						4'd7:	data_o<=data_in[6];	
						4'd8:	data_o<=data_in[7];	
						4'd9:	data_o<=1'b1;
					default:	data_o<=1'b1;
					endcase

top_down 将各个模块连接在一起;

module	top_down(

		input wire sclk,
		input wire rst_n,
		input wire key_in,
		
		output wire data
);


wire key_o_1;
wire  [7:0] gen_data_1;  ///
wire flag_1;
key_rock key_rock_inst(
				.sclk		(sclk),
				.rst_n		(rst_n),
				.key_in		(key_in),
				
				.key_o      (key_o_1)
);

gen_data	gen_data_inst(
		
			.sclk				(sclk),
			.rst_n				(rst_n),
			.key_out_in			(key_o_1),
			
			. gen_data_out		(gen_data_1),
			. flag              (flag_1)
);

uart_crtl	uart_crtl_inst(

					.sclk		(sclk),
					.rst_n		(rst_n),
					.data_in	(gen_data_1),
					.flag_in	(flag_1),
					           
					.data_o     (data)

);
endmodule

3.对模块进行仿真,主要是对通信模块进行仿真。仿真信号必须与预设的一致,不允许有半点偏差,否则实现不了按键发送数据传输。

4.实现后,利用友善数据串口,可以看到按键实现加1功能。

猜你喜欢

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