-  明白串口传输的收发过程之后,就可以通过代码实现了。首先,接收和发送可以划分成独立的两个模块。其次,串口波特率有9600bps、19200bps、38400bps、57600bps、115200bps等不同的波特率。那么,还要加一个波特率控制模块。 
-  先讲一下波特率控制模块,这个模块本质上是对系统时钟做分频处理。通过计数,将25MHz的系统时钟分频成9600Hz、19200Hz等的周期信号。部分代码如下: 
	always @(posedge CLK_25M or negedge rst_n)
		if (!rst_n)
			cnt <= 12'd0;
		else if(cnt == Baud)
			cnt <= 12'd0;
		else cnt = cnt + 1'd1;
 
	always @(posedge CLK_25M or negedge rst_n)
		if (!rst_n)
			BPS_CLK_r <= 1'd0;
		else if (cnt <= Baud >> 1) //相当于Baud/2
			BPS_CLK_r <= 1'd0;	//作为接收数据时的中间采样点,或发送数据时的位分界点
		else
			BPS_CLK_r <= 1'd1;	
	always@(posedge BPS_CLK or negedge rst_n)
		if(!rst_n)
			begin
				j <= 4'd0;
				data_in <= 8'd0;
				data_inr <= 40'd0;
				receive_data <= 40'd0;
			end
		else case(j)
			4'd0:                                //判断起始标志
				begin
					if(!RX)           
						begin
							data_in <= 8'd0;
							j <= j+ 1'd1;
							end
					else j <= j;
				end
			4'd1,4'd2,4'd3,4'd4,4'd5,4'd6,4'd7,4'd8:	//接收数据
				begin
					j <= j + 1'd1;
					data_in <= {RX,data_in[7:1]};
				end
			4'd9:                     //接收校验位
				begin
					receive_data <= {receive_data[31:0],data_in};
					j <= j + 1'd1;
				end
			4'd10: 				//接收停止位
				begin
					j <= 1'd0;
					if(receive_data[7:0] == 8'b00001010)
						begin
						    data_inr <= receive_data;
						end
				end
			default: j <= 4'd0;
		endcase	
	always @(posedge BPS_CLK or negedge rst_n)
		if (!rst_n)
		    begin
			i <= 14'd0;
			TX_r <= 1'd1;				//空闲状态为1
			cnt <= 4'd0;
			data_out <= 8'd0;
			GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
		    end
		else 			//开始发送DATA
		    case(i)
			14'd0: begin			//先发送起始位0
				i <= i + 1'd1;
				{data_out,GINGKO[63:8]} <= GINGKO;
				TX_r <= 1'd0;									
			       end
			14'd1,14'd2,14'd3,14'd4,14'd5,14'd6,14'd7,14'd8:	 //TX_r将DATA数据发送出去
			       begin
				i <= i + 1'd1;
				{data_out[6:0],TX_r} <= data_out; //串口发送时,低位在先
			       end								
			14'd9: begin		 //1位奇偶校验位和1位停止位
				i <= i + 1'd1;
				TX_r <= 1'd1;                                      
				end
			14'd10: begin		//1位停止位
				if(cnt == 4'd7)
				    begin
					i <= i + 1'd1;
					cnt <= 4'd0;
				    end
				else 
				    begin
					i <= 14'd0;
					cnt <= cnt + 1'd1;
				    end
				end
				14'd9600: begin	//定时约为1s				
					i <= 14'd0;
					GINGKO <= {8'd71,8'd73,8'd78,8'd71,8'd75,8'd79,8'd13,8'd10};
					end
				default: i <= i + 1'd1;  //i为其他无效数值时,直接转到退出TXD模块状态
			endcase