两路方波输入到stm32的两路定时器通道,通过检测高电平到来的时间差从而算出相位差,
公式 相位差=360*频率*(时间差)
如果要测正弦波,可以通过电压比较电路转为方波
定时器初始化及定时器中断代码:
void TIM5_Cap_Init(uint16_t arr,uint16_t psc)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3|GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
TIM_TimeBaseStructInit(&TIM_TimeBaseInitStructure);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=arr;
TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure);
TIM_ICInitTypeDef TIM_ICInitStructure;
TIM_ICInitStructure.TIM_Channel=TIM_Channel_4;
TIM_ICInitStructure.TIM_ICFilter=0x00;
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInit(TIM5,&TIM_ICInitStructure);
TIM_ICInitStructure.TIM_Channel=TIM_Channel_3;
TIM_ICInitStructure.TIM_ICFilter=0x00;
TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;
TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
TIM_ICInit(TIM5,&TIM_ICInitStructure);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC4|TIM_IT_CC3,ENABLE);
TIM_Cmd(TIM5,ENABLE);
}
u8 TIM5CH4_Cap_State; //第一路信号捕获标志
u16 TIM5CH4_Cap_Value; //第一路信号捕获值
u8 TIM5CH3_Cap_State; //第二路信号捕获标志
u16 TIM5CH3_Cap_Value; //第二路信号捕获值
void TIM5_IRQHandler()
{
if((TIM5CH4_Cap_State&0x80)==0) //第一路信号未捕获到下降沿
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)
{
if(TIM5CH4_Cap_State&0x40) //第一路信号已捕获到上升沿
{
if((TIM5CH4_Cap_State&0x3f)==0x3f) //第一路信号上升沿到下降沿时间过长,捕获失败
{
TIM5CH4_Cap_State|=0x80;
TIM5CH4_Cap_Value=0xffff;
}
else TIM5CH4_Cap_State++;
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC4)==SET) //捕获中断
{
if(TIM5CH4_Cap_State&0x40) //第一路信号已经捕获到上升沿,则此次为下降沿被捕获
{
TIM5CH4_Cap_State|=0x80; //标志一次检测完成
TIM5CH4_Cap_Value=TIM_GetCapture4(TIM5); //取出定时器的值
TIM_OC4PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置为上升沿捕获
}
else //第一路未捕获到上升沿,则此次为上升沿被捕获
{
TIM5CH4_Cap_State=0;
TIM5CH4_Cap_Value=0;
TIM_SetCounter(TIM5,0);
TIM5CH4_Cap_State|=0X40; //标记捕获到上升沿
TIM_OC4PolarityConfig(TIM5,TIM_ICPolarity_Falling); //设置为下降沿捕获
}
}
}
if((TIM5CH3_Cap_State&0x80)==0)
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)
{
if(TIM5CH3_Cap_State&0x40)
{
if((TIM5CH3_Cap_State&0x3f)==0x3f)
{
TIM5CH3_Cap_State|=0x80;
TIM5CH3_Cap_Value=0xffff;
}
else TIM5CH3_Cap_State++;
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC3)==SET)
{
if(TIM5CH3_Cap_State&0x40)
{
TIM5CH3_Cap_State|=0x80;
TIM5CH3_Cap_Value=TIM_GetCapture3(TIM5);
TIM_OC3PolarityConfig(TIM5,TIM_ICPolarity_Rising);
}
else
{
TIM5CH3_Cap_State=0;
TIM5CH3_Cap_Value=0;
TIM_SetCounter(TIM5,0);
TIM5CH3_Cap_State|=0X40;
TIM_OC3PolarityConfig(TIM5,TIM_ICPolarity_Falling);
}
}
}
TIM_ClearITPendingBit(TIM5,TIM_IT_Update|TIM_IT_CC4|TIM_IT_CC3);
}
在主程序中求其中一路信号的频率,再使用开头给出的公式可求得相位差文章来源:https://www.toymoban.com/news/detail-594996.html
下面给出关于求相位差部分的主程序代码:文章来源地址https://www.toymoban.com/news/detail-594996.html
if((TIM5CH4_Cap_State&0x80) && (TIM5CH3_Cap_State&0x80))
{
timer4_temp=TIM5CH4_Cap_State&0x3f;
timer4_temp*=65536;
timer4_temp+=TIM5CH4_Cap_Value;
timer3_temp=TIM5CH3_Cap_State&0x3f;
timer3_temp*=65536;
timer3_temp+=TIM5CH3_Cap_Value;
if(timer4_temp > timer3_temp)
time_diff = timer4_temp - timer3_temp;
else
time_diff = timer3_temp - timer4_temp;
phase_diff = 360*F*time_diff/1000000;
LCD_ShowNum(410,5+24*1,phase_diff,4,24);
LCD_ShowString(410+4*12,5+24*1,12,24,24,".");
LCD_ShowNum(410+5*12,5+24*1,(u16)(phase_diff*10)%10,1,24);
TIM5CH4_Cap_State = 0;
TIM5CH3_Cap_State = 0;
}
到了这里,关于STM32测相位差(根据时间差)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!