uart通信例程分析

主题包含三个模块uart_top.c,test_uart.c,uart_trans.c

module uart_top( 
                clk,
                rst,
                txd
               );
	
input   clk, rst;
output  txd;

wire clk_i;
	
clock clock (
	.inclk0( clk ),
	.c0(clk_i    )
	);
//该clk是一个ip,作用为分频
//由于uart是异步收发模块,不需要时钟线驱动,因此需要配置波特率,即bit per second,bps	

reg		rst_r;
reg		rst_i;
always @(posedge clk_i or negedge rst)
	if (~rst)
		rst_r <= 1'b1;
	else
		rst_r <= #1 1'b0;

always @(posedge clk_i)
	rst_i <= #1 rst_r;	   


wire[7:0] dat;  
wire      signal;
wire      busy;      
test_uart  test_uart( 
   .clk   ( clk_i ),
   .rst   ( rst_i ),
   .dat   ( dat   ),
   .signal( signal),
   .busy  ( busy  )
  );
uart_trans uart_trans(
   .clk      ( clk_i ), 
   .TxD_start( signal), 
   .TxD_data ( dat   ), 
   .TxD      ( txd   ), 
   .TxD_busy ( busy  )
   );

endmodule	
module test_uart( 
                clk,
                rst,
                dat,
                signal,
                busy
             );
	
input        clk, rst;
output[7:0]  dat;
output       signal; 
input        busy;
  

parameter idle    = 0;
parameter load    = 1;
parameter start   = 2;
parameter sending = 3;
parameter loop    = 4;
parameter nop     = 5;
parameter next    = 6;

reg[3 : 0]  state;

reg[7 : 0]  rom_dat;
reg[7 : 0]  tmp_dat;
reg    	    signal;

reg[4 : 0]  cnt;
reg[4 : 0] 	char_cnt;
always@(posedge clk or posedge rst) 
begin
  if(rst)
  begin
    cnt          <= 5'd0;
  	char_cnt     <= 5'd0;
    tmp_dat      <= 8'd0;
    signal       <= 1'b0;   
  	state        <= nop;
  end			
 else
   case(state)
	nop :
      begin 
		  char_cnt     <= 5'd0;
		  cnt          <= 5'd0;
	      state        <= idle;
  	  end
	idle :
      begin 
  	    if(busy == 1'b0)
  	    begin
	      tmp_dat      <= rom_dat;
          signal       <= 1'b0;   
	      state        <= load;
	    end
  	  end
	load :
	  begin
	      signal       <= 1'b1;  
	      state        <= start;
	  end
	start :
	  begin
          signal       <= 1'b0;  
          state  <= sending; 
	  end
	sending :
		if( busy == 1'b0 ) state  <= next;
        else               state  <= sending;
	next :
	  begin 
  		   if(cnt == 5'h10 )
	  	    begin	
	  	      state    <= nop;
	        end      
	       else
	        begin
	          state    <= idle;
	          char_cnt <= char_cnt + 1'b1;
	          cnt      <= cnt + 1'b1;
	        end 		
	  end 	 
	  
	default :
     		state <= nop;
	endcase
end

assign dat = rom_dat;

always @(char_cnt[4:0])
begin
  rom_dat = 8'hxx;
 case(char_cnt[4:0])
  5'h0   : rom_dat =  "1";
  5'h1   : rom_dat =  "2";
  5'h2   : rom_dat =  "3";
  5'h3   : rom_dat =  "5";
  5'h4   : rom_dat =  "5";
  5'h5   : rom_dat =  "6";
  5'h6   : rom_dat =  "7";
  5'h7   : rom_dat =  "8";
  5'h8   : rom_dat =  "9";
  5'h9   : rom_dat =  "a";
  5'ha   : rom_dat =  "b";
  5'hb   : rom_dat =  "c";
  5'hc   : rom_dat =  "d";
  5'hd   : rom_dat =  "e";
  5'he   : rom_dat =  "f";
  5'hf   : rom_dat =  8'h0a; 
  5'h10  : rom_dat =  8'h0d; 
  endcase
end

endmodule
module uart_trans(clk, TxD_start, TxD_data, TxD, TxD_busy);
input clk, TxD_start;
input [7:0] TxD_data;
output TxD, TxD_busy;

parameter ClkFrequency = 25000000;
parameter Baud = 115200;
parameter RegisterInputData = 1;

// Baud generator
parameter BaudGeneratorAccWidth = 16;
reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);

wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth];
wire TxD_busy;
always @(posedge clk) if(TxD_busy) BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;

// Transmitter state machine
reg [3:0] state;
wire TxD_ready = (state==0);
assign TxD_busy = ~TxD_ready;

reg [7:0] TxD_dataReg;
always @(posedge clk) if(TxD_ready & TxD_start) TxD_dataReg <= TxD_data;
wire [7:0] TxD_dataD = RegisterInputData ? TxD_dataReg : TxD_data;

always @(posedge clk)
case(state)
	4'b0000: if(TxD_start) state <= 4'b0001;
	4'b0001: if(BaudTick) state <= 4'b0100;
	4'b0100: if(BaudTick) state <= 4'b1000;  // start
	4'b1000: if(BaudTick) state <= 4'b1001;  // bit 0
	4'b1001: if(BaudTick) state <= 4'b1010;  // bit 1
	4'b1010: if(BaudTick) state <= 4'b1011;  // bit 2
	4'b1011: if(BaudTick) state <= 4'b1100;  // bit 3
	4'b1100: if(BaudTick) state <= 4'b1101;  // bit 4
	4'b1101: if(BaudTick) state <= 4'b1110;  // bit 5
	4'b1110: if(BaudTick) state <= 4'b1111;  // bit 6
	4'b1111: if(BaudTick) state <= 4'b0010;  // bit 7
	4'b0010: if(BaudTick) state <= 4'b0011;  // stop1
	4'b0011: if(BaudTick) state <= 4'b0000;  // stop2
	default: if(BaudTick) state <= 4'b0000;
endcase
reg muxbit;
always @( * )
case(state[2:0])
	3'd0: muxbit <= TxD_dataD[0];
	3'd1: muxbit <= TxD_dataD[1];
	3'd2: muxbit <= TxD_dataD[2];
	3'd3: muxbit <= TxD_dataD[3];
	3'd4: muxbit <= TxD_dataD[4];
	3'd5: muxbit <= TxD_dataD[5];
	3'd6: muxbit <= TxD_dataD[6];
	3'd7: muxbit <= TxD_dataD[7];
endcase
reg TxD;
always @(posedge clk) TxD <= (state<4) | (state[3] & muxbit);

endmodule
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值