基于Verilog的串口发送程序

2023-02-18,,,

一、模块框图及基本思路

tx_bps_module:波特率时钟产生模块

tx_control_module:串口发送的核心控制模块

tx_module:前两个模块的组合

control_module:发送控制模块,每秒触发一次发送

tx_top_module:tx_module+control_module

二、软件部分

tx_bps_module:

 module tx_bps_module #(parameter Baud=)(
CLK,RSTn,
Count_Sig,
BPS_CLK
);
input CLK;
input RSTn;
input Count_Sig;
output BPS_CLK; /***************************/
localparam Baud_Div=50_000_000/Baud-;
localparam Baud_Div2=Baud_Div/; reg[:] Count_BPS;
/*************************/
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn)
Count_BPS<='d0;
else if(Count_BPS==Baud_Div)
Count_BPS<='d0;
else if(Count_Sig)
Count_BPS<=Count_BPS+;
else Count_BPS<='d0;
end
/************************/
assign BPS_CLK=(Count_BPS==Baud_Div2)?'b1:1'b0;
endmodule

tx_control_module:

 module tx_control_module(
CLK,RSTn,
TX_En_Sig,TX_Data,BPS_CLK,
TX_Done_Sig,TX_Pin_Out
);
input CLK,RSTn;
input TX_En_Sig,BPS_CLK;
input [:]TX_Data;
output TX_Done_Sig,TX_Pin_Out;
/***************************************/
reg rTX;
reg isDone;
reg[:] i;
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn)
begin
rTX<='b1;
isDone<='b0;
i<='d0;
end
else if(TX_En_Sig)
begin
case(i)
'd0:if(BPS_CLK) begin rTX<=0;i<=i+1'b1; end
'd1,4'd2,'d3,4'd4,'d5,4'd6,'d7,4'd8:
if(BPS_CLK) begin rTX<=TX_Data[i-];i<=i+'b1; end
'd9:if(BPS_CLK) begin rTX<=1;i<=i+1'b1; end
'd10:if(BPS_CLK) begin rTX<=1;i<=i+1'b1; end
'd11:if(BPS_CLK) begin isDone<=1;i<=i+1'b1; end
'd12: begin isDone<=0;i<=1'b0; end
endcase
end
end
/***************************************/
assign TX_Pin_Out=rTX;
assign TX_Done_Sig=isDone;
endmodule

tx_module:

 module tx_module(
CLK,RSTn,
TX_En_Sig,TX_Data,TX_Pin_Out,TX_Done_Sig
);
input CLK;
input RSTn;
input TX_En_Sig;
input [:] TX_Data;
output TX_Pin_Out;
output TX_Done_Sig; wire BPS_CLK; tx_bps_module U0(.CLK(CLK),.RSTn(RSTn),.Count_Sig(TX_En_Sig),.BPS_CLK(BPS_CLK));
tx_control_module U1(.CLK(CLK),.RSTn(RSTn),.TX_En_Sig(TX_En_Sig),
.BPS_CLK(BPS_CLK),.TX_Data(TX_Data),.TX_Done_Sig(TX_Done_Sig),
.TX_Pin_Out(TX_Pin_Out));
endmodule

control_module:

 module control_module(
CLK, RSTn,
TX_Done_Sig,
TX_En_Sig, TX_Data
);
input CLK;
input RSTn;
input TX_Done_Sig;
output TX_En_Sig;
output [:]TX_Data; /***********************************************/
localparam T1S='d49_999_99;
reg [:] Count_Sec;
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn)
Count_Sec<='d0;
else if(Count_Sec==T1S) Count_Sec<='d0;
else Count_Sec<=Count_Sec+'b1;
end
/************************************************/ reg[:] rData;
reg isEn;
always @(posedge CLK or negedge RSTn)
begin
if(!RSTn)
begin
rData<='h31;
isEn<='b0;
end
else if(TX_Done_Sig)
begin
rData<='h31;
isEn<='b0;
end
else if(Count_Sec==T1S) isEn<='b1;
end /*************************************************/
assign TX_Data=rData;
assign TX_En_Sig=isEn; /*************************************************/
endmodule

tx_top_module:

 module tx_top_module(
CLK,RSTn,
TX_Pin_Out
);
input CLK;
input RSTn;
output TX_Pin_Out; wire TX_Done_Sig;
wire TX_En_Sig;
wire [:]TX_Data;
control_module U0(
.CLK(CLK), .RSTn(RSTn),
.TX_Done_Sig(TX_Done_Sig),
.TX_En_Sig(TX_En_Sig), .TX_Data(TX_Data)); tx_module U1(
.CLK(CLK),.RSTn(RSTn),
.TX_En_Sig(TX_En_Sig),.TX_Data(TX_Data),.TX_Pin_Out(TX_Pin_Out),.TX_Done_Sig(TX_Done_Sig)
);
endmodule

三、硬件部分

黑金SPARTAN开发板

 NET "CLK" LOC = T8;
NET "RSTn" LOC = L3;
NET "TX_Pin_Out" LOC = D12;

基于Verilog的串口发送程序的相关教程结束。

《基于Verilog的串口发送程序.doc》

下载本文的Word格式文档,以方便收藏与打印。