最近在做低频数字式相位测量仪,很多人都是卡在stm32和fpga串口通信上,还有相位差的测量,下面讲讲通信的解决办法!fpga部分用了某位大神的串口通信模块进行参考(module tx_module,module tx_control_module,module tx_bps_module,module uartsent),然后自己写了stm32f1精英版的串口接收程序。
*************************************************************************************************************************************************特别注意Do_sig 和start_sig,Done_sig。Do_sig是 发送信号,每当监测到时钟上升沿时开始发送数据;start_sig是开始进行测量信号,由stm32f1引脚提供(低电平有效)无此信号fpga不进行测量;Done_sig是计数完成信号,不需要也没事。
*************************************************************************************************************************************************
1、fpga部分
module uartsent
(
input CLK_25M, //PLL CLK 25M
input RSTn, //系统复位低电平有效 SYS Reset
input Do_sig, //开始发送信号
input [31:0] fxCnt, //输入信号计数寄存器
input [31:0] fBaseCnt,
input [31:0] DutyCnt,
input [31:0] o_data, //相位差测量数据
output TX_Pin_Out // 连接STM32串口;
);
wire isDone; //tx_module发出了信号
reg rEN = 1'b0; //发送使能
reg [7:0] Data[15:0]; //发送数据缓冲区
reg [5:0] i=6'd0; //Send state声明
reg [7:0] data; //发送给txmodule的数据
tx_module U0_tx
(
.CLK_25M (CLK_25M ),
.RSTn (RSTn ),
.TX_Data (data ),
.TX_En_Sig (rEN ),
.TX_Done_Sig (isDone ),
.TX_Pin_Out (TX_Pin_Out )
);
// 调用txmodule发送测量数据
always@(posedge CLK_25M or posedge Do_sig) //只要25M时钟或者开始发送信号上升沿时
begin
if(Do_sig) //Do_sig等于1时开始执行
begin //将数据全部转移数据到临时表
Data[15] <= DutyCnt [31:24]; //转移数据到临时表
Data[14] <= DutyCnt [23:16]; //Data[15:12] 占空比数据
Data[13] <= DutyCnt [15:8 ];
Data[12] <= DutyCnt [7 :0 ];
Data[11] <= o_data [31:24]; //Data[11: 8]delay data时间间隔数据
Data[10] <= o_data [23:16];
Data[9] <= o_data [15:8 ];
Data[8] <= o_data [7 :0 ];
Data[7] <= fxCnt [31:24]; //Data[7:4]
Data[6] <= fxCnt [23:16];
Data[5] <= fxCnt [15:8 ];
Data[4] <= fxCnt [7 :0 ];
Data[3] <= fBaseCnt [31:24]; //Data[7:4]
Data[2] <= fBaseCnt [23:16];
Data[1] <= fBaseCnt [15:8 ];
Data[0] <= fBaseCnt [7 :0 ]; //8位2进制数
i <= 1'b1; //状态更改发送状态 ,转移完,i=1
end
else
begin
if(rEN == 1'b0 && i>= 1'b1) //当不使能时且i=1时 即将数据全部转移数据到临时表完成后
begin
case(i)//:txmodule启动信号 状态是发送状态
6'd 1 : begin data <= Data[15]; rEN <= 1'b1; i <= i +1'b1; end //
6'd 2 : begin data <= Data[14]; rEN <= 1'b1; i <= i +1'b1; end
6'd 3 : begin data <= Data[13]; rEN <= 1'b1; i <= i +1'b1; end
6'd 4 : begin data <= Data[12]; rEN <= 1'b1; i <= i +1'b1; end
6'd 5 : begin data <= Data[11]; rEN <= 1'b1; i <= i +1'b1; end
6'd 6 : begin data <= Data[10]; rEN <= 1'b1; i <= i +1'b1; end
6'd 7 : begin data <= Data[9 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd 8 : begin data <= Data[8 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd 9 : begin data <= Data[7 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd10 : begin data <= Data[6 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd11 : begin data <= Data[5 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd12 : begin data <= Data[4 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd13 : begin data <= Data[3 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd14 : begin data <= Data[2 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd15 : begin data <= Data[1 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd16 : begin data <= Data[0 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd17 : begin data <= 8'hf ; rEN <= 1'b1; i <= i +1'b1; end
//发送模式验证码,等于测试freq,MCU(stm32)
6'd18 : begin data <= 8'hd ; rEN <= 1'b1; i <= i +1'b1; end
6'd19 : begin data <= 8'ha ; rEN <= 1'b1; i <= i +1'b1; end
6'd20 : i <= 1'b0; //发送完i=0
endcase
end
if(isDone == 1'b1)
begin
rEN <=1'b0; //:确定txmodule启动信号只有一个clk脉冲
end
end
end
endmodule
//Found from the internet, verify OK
module tx_module
(
CLK_25M,
RSTn,
TX_Data,
TX_En_Sig,
TX_Done_Sig,
TX_Pin_Out
);
input CLK_25M;
input RSTn;
input [7:0]TX_Data;//来自top_uartsent
input TX_En_Sig;
output TX_Done_Sig;
output TX_Pin_Out;
/********************************/
wire BPS_CLK;
tx_bps_module U1
(
.CLK_25M( CLK_25M ),
.RSTn( RSTn ),
.Count_Sig( TX_En_Sig ), // input - from U2
.BPS_CLK( BPS_CLK ) // output - to U2
);
/*********************************/
tx_control_module U2
(
.CLK_25M( CLK_25M ),
.RSTn( RSTn ),
.TX_En_Sig( TX_En_Sig ), // input - from top
.TX_Data( TX_Data ), // input - from top
.BPS_CLK( BPS_CLK ), // input - from U2
.TX_Done_Sig( TX_Done_Sig ), // output - to top
.TX_Pin_Out( TX_Pin_Out ) // output - to top
);
/***********************************/
endmodule
//Found from the internet, verify OK
module tx_control_module
(
CLK_25M,
RSTn,
TX_En_Sig, //发送使能信号
TX_Data,
BPS_CLK,
TX_Done_Sig,
TX_Pin_Out
);
input CLK_25M;
input RSTn;
input TX_En_Sig; //发送使能信号
input [7:0]TX_Data;
input BPS_CLK; //时钟 bps-每秒传送位数(bits per second);字节/秒(bytes per second)
output TX_Done_Sig; //发送完成信号
output TX_Pin_Out; //发送引脚
/********************************************************/
reg [3:0]i;
reg rTX;
reg isDone;
always @ ( posedge CLK_25M or negedge RSTn )
begin
if( !RSTn )
begin
i <= 4'd0; //0000
rTX <= 1'b1; //1
isDone <= 1'b0;//0
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 :
if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end
4'd12 :
begin i <= 1'b0; isDone <= 1'b0; end
endcase
end
/********************************************************/
assign TX_Pin_Out = rTX;
assign TX_Done_Sig = isDone;
/*********************************************************/
endmodule
最近在做低频数字式相位测量仪,很多人都是卡在stm32和fpga串口通信上,还有相位差的测量,下面讲讲通信的解决办法!fpga部分用了某位大神的串口通信模块进行参考(module tx_module,module tx_control_module,module tx_bps_module,module uartsent),然后自己写了stm32f1精英版的串口接收程序。
*************************************************************************************************************************************************特别注意Do_sig 和start_sig,Done_sig。Do_sig是 发送信号,每当监测到时钟上升沿时开始发送数据;start_sig是开始进行测量信号,由stm32f1引脚提供(低电平有效)无此信号fpga不进行测量;Done_sig是计数完成信号,不需要也没事。
*************************************************************************************************************************************************
1、fpga部分
module uartsent
(
input CLK_25M, //PLL CLK 25M
input RSTn, //系统复位低电平有效 SYS Reset
input Do_sig, //开始发送信号
input [31:0] fxCnt, //输入信号计数寄存器
input [31:0] fBaseCnt,
input [31:0] DutyCnt,
input [31:0] o_data, //相位差测量数据
output TX_Pin_Out // 连接STM32串口;
);
wire isDone; //tx_module发出了信号
reg rEN = 1'b0; //发送使能
reg [7:0] Data[15:0]; //发送数据缓冲区
reg [5:0] i=6'd0; //Send state声明
reg [7:0] data; //发送给txmodule的数据
tx_module U0_tx
(
.CLK_25M (CLK_25M ),
.RSTn (RSTn ),
.TX_Data (data ),
.TX_En_Sig (rEN ),
.TX_Done_Sig (isDone ),
.TX_Pin_Out (TX_Pin_Out )
);
// 调用txmodule发送测量数据
always@(posedge CLK_25M or posedge Do_sig) //只要25M时钟或者开始发送信号上升沿时
begin
if(Do_sig) //Do_sig等于1时开始执行
begin //将数据全部转移数据到临时表
Data[15] <= DutyCnt [31:24]; //转移数据到临时表
Data[14] <= DutyCnt [23:16]; //Data[15:12] 占空比数据
Data[13] <= DutyCnt [15:8 ];
Data[12] <= DutyCnt [7 :0 ];
Data[11] <= o_data [31:24]; //Data[11: 8]delay data时间间隔数据
Data[10] <= o_data [23:16];
Data[9] <= o_data [15:8 ];
Data[8] <= o_data [7 :0 ];
Data[7] <= fxCnt [31:24]; //Data[7:4]
Data[6] <= fxCnt [23:16];
Data[5] <= fxCnt [15:8 ];
Data[4] <= fxCnt [7 :0 ];
Data[3] <= fBaseCnt [31:24]; //Data[7:4]
Data[2] <= fBaseCnt [23:16];
Data[1] <= fBaseCnt [15:8 ];
Data[0] <= fBaseCnt [7 :0 ]; //8位2进制数
i <= 1'b1; //状态更改发送状态 ,转移完,i=1
end
else
begin
if(rEN == 1'b0 && i>= 1'b1) //当不使能时且i=1时 即将数据全部转移数据到临时表完成后
begin
case(i)//:txmodule启动信号 状态是发送状态
6'd 1 : begin data <= Data[15]; rEN <= 1'b1; i <= i +1'b1; end //
6'd 2 : begin data <= Data[14]; rEN <= 1'b1; i <= i +1'b1; end
6'd 3 : begin data <= Data[13]; rEN <= 1'b1; i <= i +1'b1; end
6'd 4 : begin data <= Data[12]; rEN <= 1'b1; i <= i +1'b1; end
6'd 5 : begin data <= Data[11]; rEN <= 1'b1; i <= i +1'b1; end
6'd 6 : begin data <= Data[10]; rEN <= 1'b1; i <= i +1'b1; end
6'd 7 : begin data <= Data[9 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd 8 : begin data <= Data[8 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd 9 : begin data <= Data[7 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd10 : begin data <= Data[6 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd11 : begin data <= Data[5 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd12 : begin data <= Data[4 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd13 : begin data <= Data[3 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd14 : begin data <= Data[2 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd15 : begin data <= Data[1 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd16 : begin data <= Data[0 ]; rEN <= 1'b1; i <= i +1'b1; end
6'd17 : begin data <= 8'hf ; rEN <= 1'b1; i <= i +1'b1; end
//发送模式验证码,等于测试freq,MCU(stm32)
6'd18 : begin data <= 8'hd ; rEN <= 1'b1; i <= i +1'b1; end
6'd19 : begin data <= 8'ha ; rEN <= 1'b1; i <= i +1'b1; end
6'd20 : i <= 1'b0; //发送完i=0
endcase
end
if(isDone == 1'b1)
begin
rEN <=1'b0; //:确定txmodule启动信号只有一个clk脉冲
end
end
end
endmodule
//Found from the internet, verify OK
module tx_module
(
CLK_25M,
RSTn,
TX_Data,
TX_En_Sig,
TX_Done_Sig,
TX_Pin_Out
);
input CLK_25M;
input RSTn;
input [7:0]TX_Data;//来自top_uartsent
input TX_En_Sig;
output TX_Done_Sig;
output TX_Pin_Out;
/********************************/
wire BPS_CLK;
tx_bps_module U1
(
.CLK_25M( CLK_25M ),
.RSTn( RSTn ),
.Count_Sig( TX_En_Sig ), // input - from U2
.BPS_CLK( BPS_CLK ) // output - to U2
);
/*********************************/
tx_control_module U2
(
.CLK_25M( CLK_25M ),
.RSTn( RSTn ),
.TX_En_Sig( TX_En_Sig ), // input - from top
.TX_Data( TX_Data ), // input - from top
.BPS_CLK( BPS_CLK ), // input - from U2
.TX_Done_Sig( TX_Done_Sig ), // output - to top
.TX_Pin_Out( TX_Pin_Out ) // output - to top
);
/***********************************/
endmodule
//Found from the internet, verify OK
module tx_control_module
(
CLK_25M,
RSTn,
TX_En_Sig, //发送使能信号
TX_Data,
BPS_CLK,
TX_Done_Sig,
TX_Pin_Out
);
input CLK_25M;
input RSTn;
input TX_En_Sig; //发送使能信号
input [7:0]TX_Data;
input BPS_CLK; //时钟 bps-每秒传送位数(bits per second);字节/秒(bytes per second)
output TX_Done_Sig; //发送完成信号
output TX_Pin_Out; //发送引脚
/********************************************************/
reg [3:0]i;
reg rTX;
reg isDone;
always @ ( posedge CLK_25M or negedge RSTn )
begin
if( !RSTn )
begin
i <= 4'd0; //0000
rTX <= 1'b1; //1
isDone <= 1'b0;//0
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 :
if( BPS_CLK ) begin i <= i + 1'b1; isDone <= 1'b1; end
4'd12 :
begin i <= 1'b0; isDone <= 1'b0; end
endcase
end
/********************************************************/
assign TX_Pin_Out = rTX;
assign TX_Done_Sig = isDone;
/*********************************************************/
endmodule
举报