赞
踩
两路方波输入到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);
- }
在主程序中求其中一路信号的频率,再使用开头给出的公式可求得相位差
下面给出关于求相位差部分的主程序代码:
- 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;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。