解决stm32f1和FPGA串口通信的问题(stm32接收FPGA发送)

最近在做低频数字式相位测量仪,很多人都是卡在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

//(国赛fpga)
//时钟 bps-每秒传送位数(bits per second);字节/秒(bytes per second)
//Found from the internet, verify OK
module tx_bps_module
(
    CLK_25M,
	 RSTn,
	 Count_Sig, 
	 BPS_CLK
);

    input CLK_25M;
	 input RSTn;
	 input Count_Sig;
	 output BPS_CLK;
	 
	 /*************Count_BPS = CLK / wish bps************* */
	 
	 reg [11:0]Count_BPS;  //12位
	 
	 always @ ( posedge CLK_25M or negedge RSTn )//当25M上升沿到来或者复位
	   begin
	     if( !RSTn )
		     Count_BPS <= 12'd0;
		  else if( Count_BPS == 12'd2604 )  //25M/2604=9600波特率
//测试暂用
	//	  else if( Count_BPS == 12'd80 )  //25M/2604=9600波特率

		          Count_BPS <= 12'd0;
		        else if( Count_Sig)          // Count_BPS <= 12'd2604
		               Count_BPS <= Count_BPS + 1'b1;
		             else
		               Count_BPS <= 12'd0;
		end	 
	 /********************************/

    assign BPS_CLK = ( Count_BPS == 12'd1302 ) ? 1'b1 : 1'b0;

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

endmodule

顶层文件

	//频率测量模块 实例化    
	mesureFreq 	U1_mesure_things
	(
		.CLK_25M		(CLK_25M     ), //系统时钟,默认25M        
		.fxA			(fxA	       ), //被测信号---   来自顶层          
		.fxB		   (fxB		    ), //基准信号---   来自顶层  
		.CLK_200M	(CLK_200M	 ), //200M时钟   
		.Start_sig	(Start_sig	 ), //测量开始信号       
		.fxCnt		(fxCnt		 ), //被测信号计数个数  
		.fBaseCnt	(fBaseCnt	 ), //基准信号计数个数   
		.DutyCnt	   (DutyCnt		 ), //占空比计数个数     
		.DelayCnt	(DelayCnt    ), //时间间隔计数个数         
		.Done_sig	(Cnt_done_sig), //计数完成信号        
		.LED		   (LED			 )  //LED        到顶层                         
		);

2、STM32部分

串口接收

//串口1中断处理函数
void USART1_IRQHandler(void)
{
	unsigned char res;

	if(USART1->SR&(1<<5))//接收到数据
	{
		res=USART1->DR;
		if((USART_RX_STA&0x80)==0)//接收未完成
		{
			if(USART_RX_STA&0x40)//接收到了0x0d
			{
				if(res!=0x0a)
					USART_RX_STA=0;//接收错误,重新开始
				else
					{
						USART_RX_STA|=0x80;	//接收完成了
//						showhz32str(0,600,"接收完成",BLACK,GREEN);
//						printf("%s\r\n",USART_RX_BUF);
					}
			}
			else //还没收到0X0D
			{
				if(res==0x0d)
				{
					USART_RX_BUF[USART_RX_STA]=0;
					USART_RX_STA|=0x40;
				}
				else
				{
					USART_RX_BUF[USART_RX_STA]=res;
					USART_RX_STA++;
					if(USART_RX_STA>63)
					{
						USART_RX_STA=0;//接收数据错误,重新开始接收
//						showhz32str(0,600,"接收数据错误",BLACK,GREEN);
				  }
				}
			}
		}
	}
}

下图此代码写在main()函数里面

usart.h头文件里面包含     extern char USART_RX_BUF[64];                 //接收缓冲,最大64个字节. extern unsigned char                                                         USART_RX_STA;    //接收状态标记  bit7,接收完成标志  bit6,接收到0x0d  bit5~0,接收到的有效字节数目
 

		
		//进行串口通信接收数据
		if(USART_RX_STA & 0x80)						//USART_RX_STA=0x80;//接收状态标记  bit7,接收完成标志  bit6,接收到0x0d  bit5~0,接收到的有效字节数目
		{
			count=0;
			
/****************************************************************************************************/	
			
					x=(USART_RX_BUF[8]<<24)+(USART_RX_BUF[9]<<16)+(USART_RX_BUF[10]<<8)+USART_RX_BUF[11];
					y=(USART_RX_BUF[12]<<24)+(USART_RX_BUF[13]<<16)+(USART_RX_BUF[14]<<8)+USART_RX_BUF[15];
					duty=(USART_RX_BUF[0]<<24)+(USART_RX_BUF[1]<<16)+(USART_RX_BUF[2]<<8)+USART_RX_BUF[3];
/*相位差计数时间*/  delay=(USART_RX_BUF[4]<<24)+(USART_RX_BUF[5]<<16)+(USART_RX_BUF[6]<<8)+USART_RX_BUF[7];
/*****************************************************************************************************/
			

stm32f103vet6代码

数字式相位测量仪(2)stm32f1工程.zip_stm32与FPGA如何通信,收发数-C代码类资源-CSDN下载

FPGA代码

phase(test).zip_stm32fpga串口通信STM32发送FPGA接收-硬件开发代码类资源-CSDN下载

  • 28
    点赞
  • 196
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 49
    评论
评论 49
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蜻蜓队长c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值