UART串口通信协议

1.发送

module uart_tx(clk,rst,receive_ack,data_o,txd);
 input clk;
 input rst;
 input receive_ack;//发送数据命令,高电平有效
 input [7:0] data_o;//8个数据位
 output txd;//发送数据
 
 reg txd;
 reg [3:0] count;
 reg presult;//偶校验位
 //assign presult = CHECK_EVEN^data_o[0]^data_o[1]^data_o[2]^data_o[3]^data_o[4]^data_o[5]^data_o[6]^data_o[7];
 //parameter CHECK_EVEN = 1'b0;//偶校验
 
 //定义状态机的5个状态:等待、发送起始位、发送数据位、发送奇偶校验位、发送结束位
 parameter IDLE=5'b00001,SEND_START=5'b00010,SEND_DATA=5'b00100,SEND_CHECK=5'b01000,SEND_END=5'b10000;
 parameter IDLE_POS=3'd0,SEND_START_POS=3'd1,SEND_DATA_POS=3'd2,SEND_CHECK_POS=3'd3,SEND_END_POS=3'd4;
 reg [4:0] cs,ns;
 //状态转换
 always @(posedge clk)
  begin
    if(rst)
	   cs <= IDLE;
	else
	   cs <= ns;
  end
 //下一个状态
 always @(*)
  begin
    if(rst)
	  ns = IDLE;
	else
	  begin
	    ns = cs;//赋初值
		case(1'b1)
		  cs[IDLE_POS]: if(receive_ack) ns = SEND_START;//收到高电平,表示接收到发送命令,同时将线路拉低一个时钟周期
		  cs[SEND_START_POS]: ns = SEND_DATA;
		  cs[SEND_DATA_POS]: if(count == 7) ns = SEND_CHECK;//数据位发送完毕,开始发送校验位
		  cs[SEND_CHECK_POS]: ns = SEND_END;
		  cs[SEND_END_POS]: if(receive_ack) ns = SEND_START;
		  default: ns = IDLE;
		endcase
	  end
  end
  //计数
 always @(posedge clk)
  begin
     if(rst)
	   begin
	      presult <= 1'b0;//初值为0,为偶校验
	      count <= 4'd0;
	   end
	 else if(cs == SEND_DATA)
	   begin
	      if(count == 7)
		     count <= 4'd0;
		  else
		     count <= count + 1'b1;
	   end
	 else
	   count <= 4'd0;
  end
 //寄存器移位
 reg [7:0] data_o_temp;
 always @(posedge clk)
  begin
     if(rst)
	   data_o_temp <= 8'd0;
	 else if(cs == SEND_START)
	   data_o_temp <= data_o;
	 else if (cs == SEND_DATA)
	   data_o_temp [6:0] <= data_o_temp [7:1];//右移
	 else
	   data_o_temp <= 8'd0;
  end
 //发送数据
 always @(posedge clk)
   begin
       if(rst)
	     txd <= 1'b1;//空闲状态处于高电平
	   else if(cs == SEND_START)
	     txd <= 1'b0;//起始位为低电平
	   else if(cs == SEND_DATA)
	     begin
		      txd <= data_o_temp[0];
			  presult <= presult ^ data_o_temp[0];
	     end
	   else if(cs == SEND_CHECK)//发送奇偶校验位、发送结束位
	     txd <= presult;
	   else if(cs == SEND_END)//发送停止位
	     txd <= 1'b1;
	   else
	     txd <= 1'b1;
   end
endmodule

2.接收

module uart_rx(rxd,clk,rst,data_i,receive_ack,data_error);
 input rxd;//接收的bit
 input clk;
 input rst;
 output [7:0] data_i;
 output receive_ack;
 output data_error;//奇偶校验位比较结果输出位
 
 reg [7:0] data_i;
 reg [3:0] count;
 reg data_error;
 //定义状态机的4个状态:空闲、接收数据、接收奇偶校验位、停止
 parameter IDLE=4'b0001,RECEIVE_DATA=4'b0010,RECEIVE_CHECK=4'b0100,RCEIVE_END=4'b1000;
 parameter IDLE_POS=2'd0,RECEIVE_DATA_POS=2'd1,RECEIVE_CHECK_POS=2'd2,RCEIVE_END_POS=2'd3;
 reg [3:0] cs,ns;
 //状态转换
 always @(posedge clk)
  begin
       if(rst)
	      cs <= IDLE;
	   else
	      cs <= ns;
  end
  //下一个状态
 always @(*)
   begin
      if(rst)
	    ns = IDLE;
	  else
	    begin
		   ns = cs;//赋初值
		   case(1'b1)
		      cs[IDLE_POS]:if(~rxd) ns = RECEIVE_DATA;
			  cs[RECEIVE_DATA_POS]:if(count == 7) ns = RECEIVE_CHECK;
			  cs[RECEIVE_CHECK_POS]: ns = RCEIVE_END;
			  cs[RCEIVE_END_POS]: begin
						             if(~rxd) ns = RECEIVE_DATA;
									 else ns = IDLE;
                                  end
			  default: ns = IDLE;
           endcase								  
		end
   end
 //计数
 reg presult;//偶校验位
 always @(posedge clk)
  begin
     if(rst)
	   begin
	     count <= 4'd0;
		 presult <= 1'b0;
		 data_error <= 1'b0;
	   end
	 else if(cs == RECEIVE_DATA)
	   begin
	      if(count == 7)
		     count <= 4'd0;
		  else
		     count <= count + 1'b1;
	   end
	 else
	   count <= 4'd0;
  end
  //接收数据,先接收最低位
  always @(posedge clk)
    begin
	    if(rst)
		  data_i <= 8'd0;
        else if(cs == RECEIVE_DATA)
          begin
		       data_i[7] <= rxd;
			   data_i[6:0] <= data_i[7:1];
			   presult <= presult ^ rxd;
          end
        else if(cs == RECEIVE_CHECK)
          begin
		       if(presult == rxd)
			      data_error <= 1'b0;
			   else
			      data_error <= 1'b1;
          end
        else
          data_i <= 8'd0;		
	end
 assign receive_ack = (cs == RECEIVE_CHECK)? 1'b1:1'b0;
endmodule

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值