一、实验目的:实现一个串口输出,通过上位机查看接受到的是否是串口发送的结果。
二、实验环境: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图