基于stm32的两路正弦波相位差测量

利用stm32测量两路正弦波相位差,有四种主要思路:

1. 两路直接捕获信号直接得到时间差

即将正弦波过比较器变成方波(stm32直接测量正弦波也可以的,频率较大时误差基本上在忍受范围的),开启两路捕获得到上升沿的时间差,即可得到其相位差,但如果系统中信号噪声较大,此方法就很难测准。

辅助比较器电路:
在这里插入图片描述
(input0为比较值,这里是过零比较,接地就好了)

stm32代码:

void TIM2_IRQHandler(void)
{ 		    
 	if((TIM2CH1_CAPTURE_STA&0X80)==0)
	{
		if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
		{	     
			if(TIM2CH1_CAPTURE_STA&0X40)
			{
				if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)
				{
					TIM2CH1_CAPTURE_STA|=0X80;		
					TIM2CH1_CAPTURE_VAL=0XFFFFFFFF;
				}else TIM2CH1_CAPTURE_STA++;
			}	 
		}//这是溢出处理,要是采集的信号频率较高,则可以不用这一段代码。
		if(TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
		{	
			if(TIM2CH1_CAPTURE_STA&0X40)				
			{	  			
				TIM2CH1_CAPTURE_STA|=0X80;		
				TIM2CH1_CAPTURE_VAL=TIM_GetCapture1(TIM2);
	 			TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising); 
			}else  								
			{
				TIM2CH1_CAPTURE_STA=0;			
				TIM2CH1_CAPTURE_VAL=0;
				TIM2CH1_CAPTURE_STA|=0X40;		
				TIM_Cmd(TIM2,DISABLE ); 	
	 			TIM_SetCounter(TIM2,0);
	 			TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);		
				TIM_Cmd(TIM2,ENABLE ); 
			}		    
		}			     	    					   
 	}
	TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); 
}

2. 两路信号过或非门转换成占空比测量

即将正弦波过比较器变成方波,过或非门得到占空比,使得测量相位差变成测量占空比,这里选用的或非门为SN74HC7002,由于这个或非门具有施密特触发器,使得系统抗噪性得到提高。
电路图:
在这里插入图片描述
电路图做了信号的隔直处理,去处理信号的直流分量。
STM32代码如下:

TIM_ICInitTypeDef  TIM2_ICInitStructure;

void TIM2_Cap_Init(u16 arr,u16 psc)
{	 
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);	
 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
	
	GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;   
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_ResetBits(GPIOA,GPIO_Pin_0);                              	//PA0口为信号接入口					     
	

	TIM_TimeBaseStructure.TIM_Period = arr;  
	TIM_TimeBaseStructure.TIM_Prescaler =psc; 	   
	TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 
	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
  

	TIM2_ICInitStructure.TIM_Channel = TIM_Channel_1; 
	TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;	
	TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
	TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;	  
	TIM2_ICInitStructure.TIM_ICFilter = 0x00;
	TIM_ICInit(TIM2, &TIM2_ICInitStructure);


	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; 
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Init(&NVIC_InitStructure);  
	
	TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC1,ENABLE);
	
 	TIM_Cmd(TIM2,ENABLE ); 	
}


u8  TIM2CH1_CAPTURE_STA=0;		    				
u16	TIM2CH1_CAPTURE_VAL1;
u16	TIM2CH1_CAPTURE_VAL2;   
 

void TIM2_IRQHandler(void)
{ 

 	if((TIM2CH1_CAPTURE_STA&0X80)==0)	
	{	  

	if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET)
		{	
			if((TIM2CH1_CAPTURE_STA&0X40))				
			{	  			
				TIM2CH1_CAPTURE_STA|=0X80;		        //捕捉到下降沿,停止计时,即一个周期的时间            
				TIM2CH1_CAPTURE_VAL2=TIM_GetCapture1(TIM2);
			}
			else if((TIM2CH1_CAPTURE_STA&0X20))  								
			{
				TIM2CH1_CAPTURE_STA|=0X40;				 //捕捉到第二个上升沿,记录时间,即高电平时间                  
				TIM2CH1_CAPTURE_VAL1=TIM_GetCapture1(TIM2);
		   		TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Falling);
			}	
      		else  								
			{
				TIM2CH1_CAPTURE_STA=0;
			    TIM2CH1_CAPTURE_VAL1=0;
				TIM2CH1_CAPTURE_VAL2=0;
	 			TIM_SetCounter(TIM2,0);
				TIM2CH1_CAPTURE_STA|=0X20;	
		    	TIM_OC1PolarityConfig(TIM2,TIM_ICPolarity_Rising);
			}		    
		}			     	    					   
 	}
 
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC1|TIM_IT_Update); 
}

占空比即为 (TIM2CH1_CAPTURE_VAL1 / TIM2CH1_CAPTURE_VAL2)
相位差就是占空比乘以180,即为(TIM2CH1_CAPTURE_VAL1 / TIM2CH1_CAPTURE_VAL2)*180
主程序代码:

extern u8  TIM2CH1_CAPTURE_STA;		    				
extern u16	TIM2CH1_CAPTURE_VAL1;	  				
extern u16	TIM2CH1_CAPTURE_VAL2;

 int main(void)
 {	
	u16 temp1,temp2,phase_difference; 

	if(TIM2CH1_CAPTURE_STA&0X80)
	{
		{	
			temp1=TIM2CH1_CAPTURE_VAL1;
			temp2=TIM2CH1_CAPTURE_VAL2;
      		phase_difference = temp1/temp2*180;
			TIM2CH1_CAPTURE_STA=0;
		}
	}
}

3. 利用求相关来测量相位差

求相关测相位差在噪声严重的情况下误差还是蛮大的,这里就简单的讲一下,这是利用了互相关函数的两同频正弦信号的互相关函数零时刻值与其相位差的余弦值成正比的原理获得相位差。

具体公式:
在这里插入图片描述
matlab仿真代码(由仿真即可看出噪声影响对结果影响较大)

		SNR = 10 ^( 0.1 * k);          %信噪比的公式:10*lg(PS/PN)
        N0 = 1/SNR;                    %N0为噪声
        Sigma = sqrt(N0/2);            

        t=0:0.00002:0.01;              %采样信号50kHz,持续时间10ms
        f=0.002;                       %被采样信号500Hz
        num=1/f;                       %num是周期

        w=pi/4;                       
        x1=sin(2*pi*num*t);            %产生信号x1
        y1=sin(2*pi*num*t+w);          %产生信号x2

        n1=Sigma.*randn(1,num+1);      %n1是噪声
        y2=y1+n1;                      %给y1信号加噪

        Ix=sum(x1.^2)/num;
        Iy=sum(y2.^2)/num;
        Ixy=sum(x1.*y2)/num;
        c=180*acos(2*Ixy/sqrt(4*Ix*Iy))/pi; 
  • 19
    点赞
  • 195
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
STM32测量正弦波相位差可以使用定时器来实现。根据引用\[1\]中的公式,可以通过计算两个波形上升沿的时间差与波形周期的比值,再乘以360°来得到相位差测量结果。具体的代码实现可以参考引用\[3\]中给出的主程序代码。在该代码中,通过定时器捕获两个波形上升沿的时间,并计算时间差,然后根据公式计算相位差,并将结果显示在LCD上。需要注意的是,该代码是基于STM32的,具体的实现可能会有所不同,需要根据具体的开发板和编程环境进行相应的调整。 #### 引用[.reference_title] - *1* [stm32 检测相位差 并简单实现两个单片机的通信](https://blog.csdn.net/m0_59140170/article/details/124887867)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [基于stm32两路正弦波相位差测量](https://blog.csdn.net/weixin_43656566/article/details/90086294)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [STM32相位差(根据时间差)](https://blog.csdn.net/qq_64157010/article/details/130675672)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值