FPGA学习之串口发送模块

一、实验目的:实现一个串口输出,通过上位机查看接受到的是否是串口发送的结果。
二、实验环境:FPGA开发板AX301,Quartus ii
三、实验介绍:串口发送使能后,开始发送数据。发送信号默认为高电平,第0位数据发低电平,1~7为要发送的数据,9、10位发高电平。
 
四、系统框架图
 
五、源码

首先是改波特率,例程为9600,改成115200.

115200 bps 传输速度使一位数据的周期是 0.0000086805s 。以 50Mhz 时钟频率
要得到上述的定时需要:
N = 0.0000086805 / ( 1 / 50Mhz ) = 434

 

module tx_module_demo
(
    CLK, RSTn,
     TX_Pin_Out,
);

    input CLK;
     input RSTn;
     output TX_Pin_Out;
     
     /**********************************/
     
     wire TX_En_Sig;
     wire [7:0]TX_Data;
     wire TX_Done_Sig ;
     
     tx_module U1
     (
         .CLK( CLK ),
          .RSTn( RSTn ),
          .TX_Pin_Out( TX_Pin_Out ),   // output to top
          .TX_En_Sig( TX_En_Sig ),   // input from u2
          .TX_Done_Sig( TX_Done_Sig ),  // output to u2
          .TX_Data( TX_Data )           // input from u2
     );
     
     /***********************************/
     
     wire [7:0]Output_Data;
     
     control_module U2
     (
         .CLK( CLK ),
         .RSTn( RSTn ),
          .TX_Done_Sig( TX_Done_Sig ),  // input from u1 
          .TX_Data( TX_Data ),          // output to u1 
          .TX_En_Sig( TX_En_Sig ),      // output to u1
     );
     
     /***********************************/

     
endmodule
module tx_module
(
    CLK, RSTn,
    TX_Pin_Out, TX_En_Sig,
    TX_Data, TX_Done_Sig
);
    
     input CLK;
     input RSTn;
    input TX_En_Sig;
     input [7:0]TX_Data;
    output TX_Pin_Out;
     output TX_Done_Sig;
     
     
 /********************************************************/
 
 wire BPS_CLK;
 
tx_bps_module U1
(
 .CLK(CLK),
 .RSTn(RSTn),
 .Count_Sig(TX_En_Sig),//input from u2
 .BPS_CLK(BPS_CLK)//output to u2

);
 
 tx_control_module U2
(
    .CLK(CLK),
    .RSTn(RSTn),
     .TX_En_Sig(TX_En_Sig),
     .BPS_CLK(BPS_CLK),
    .TX_Pin_Out(TX_Pin_Out), 
    .TX_Data(TX_Data), 
     .TX_Done_Sig(TX_Done_Sig)
);
 
 /***********************************/
 
 endmodule
 
module control_module
(
    CLK, RSTn,
     TX_Done_Sig,
     TX_Data,
     TX_En_Sig,
);

    input CLK;
     input RSTn;
     input TX_Done_Sig;
     output [7:0]TX_Data;
     output TX_En_Sig;
     
     /******************************/
     
     parameter T1S = 26'd49_999_999;//定时1S
     
     /******************************/
     
      reg [25:0]Count1;
     
     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              Count1 <= 26'd0;
          else if( Count1 == T1S )
              Count1 <= 26'd0;
          else
              Count1 <= Count1 + 1'b1;
                
    /***************************************/

     reg [7:0]tData;
     reg isEn;
     
    always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )begin
              tData <= 8'h31;
                isEn <= 1'b0;
                end
          else if( TX_Done_Sig )     
              begin 
                tData <= 8'h31;
                isEn <= 1'b0;
                end
          else if(Count1 == T1S)
              isEn <= 1'b1;//间隔1S,发送使能

    /*********************************/
    
    assign TX_Data = tData;
    assign TX_En_Sig = isEn;
    
    /*********************************/
     
endmodule
module tx_bps_module
(
 CLK, RSTn,Count_Sig, BPS_CLK

);
input CLK;
input RSTn;
input Count_Sig;
output BPS_CLK;

/******************************/

reg [12:0]Count_BPS; 

/******************************/

 always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
          Count_BPS <= 13'd0;
         // else if(Count_BPS == 13'd5207 )// 9600  bps  传输一位数据时间
          else if(Count_BPS == 13'd433 )// 115200  bps  传输一位数据时间
              Count_BPS <= 13'd0;
         else if( Count_Sig )  //计数信号使能
             Count_BPS <= Count_BPS + 1'b1;
         else
             Count_BPS <= 13'd0;//计数信号no使能
        
     /********************************/
   assign BPS_CLK = ( Count_BPS == 12'd217 ) ? 1'b1 : 1'b0;//一个周期的二分之一时间时,产生一个高脉冲

    /*********************************/


endmodule
module tx_control_module
(
    CLK, RSTn,
    TX_Pin_Out, BPS_CLK, TX_En_Sig,
    TX_Data, TX_Done_Sig

);
    
     input CLK;
     input RSTn;
     
     input TX_En_Sig;
     input [7:0]TX_Data;
     input BPS_CLK;
     
     output TX_Pin_Out;
     output TX_Done_Sig;
     
 /********************************************************/
 
    reg [3:0]i;
     reg rTX;
     reg isDone;

         always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin 
                  i <= 4'd0;
                     rTX <= 1'b1;//初始为高电平
                     isDone <= 1'b0;     
                end 
            else if( TX_En_Sig ) //发送使能
              case ( i )
              
                   4'd0 :
                     if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b0; end
                     
                     4'd1 ,4'd2, 4'd3, 4'd4, 4'd5, 4'd6, 4'd7, 4'd8 :
                     if( BPS_CLK ) begin i <= i + 1'b1; rTX <=TX_Data[ i - 1 ]; end
                     
                     4'd9 :
                     if( BPS_CLK ) begin i <= i + 1'b1; rTX <= 1'b1; end
                     
                     4'd10 :
                     if( BPS_CLK ) begin i <= i + 1'b1;rTX <= 1'b1;  end
                     
                     4'd11 :
                     begin i <= i + 1'b1; isDone <= 1'b1; end
                     
                     4'd12 :
                     begin i <= 4'd0; isDone <= 1'b0; end
                 
                endcase
                
 /********************************************************/
 
 assign TX_Pin_Out=rTX;
 assign TX_Done_Sig=isDone;
 
  /********************************************************/
     
endmodule

 六、RTL图

posted @ 2017-05-04 11:03  古月照今尘  阅读(1435)  评论(0编辑  收藏  举报