资讯详情

STM32光电码盘正交编码测速

最近在做STM32正交编码测速,下载了一个看似官方提供的程序,却看不懂,希望看到贴的大侠不吝赐教。

s16 ENC_Get_Electrical_Angle(void)//s16 int16_t

{

s32 temp;

temp=(s32)(TIM_GetCounter(ENCODER_TIMER))*(s32)(UINT32_MAX/(4*ENCODER_PPR));//s32 int32_t

return((s16)(temp/65536)); // s16 result

}

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

* Function Name : ENC_Clear_Speed_Buffer

* Description : Clear speed buffer used for average speed calculation

* Input : None

* Output : None

* Return : None

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

void ENC_Clear_Speed_Buffer(void)

{

u32 i;

for(i=0;i

{

hSpeed_Buffer=0;

}

bIs_First_Measurement = 1;

}

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

* Function Name : ENC_Calc_Rot_Speed

* Description : Compute return latest speed measurement

* Input : None

* Output : s16

* Return : Return the speed in 0.1 Hz resolution.

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

s16 ENC_Calc_Rot_Speed(void)//int16_t

{

s32 wDelta_angle;

u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two;

u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two;

signed long long temp;

s16 haux;

if(!bIs_First_Measurement)

{

// 1st reading of overflow counter

hEnc_Timer_Overflow_sample_one=hEncoder_Timer_Overflow;

// 1st reading of encoder timer counter

hCurrent_angle_sample_one=ENCODER_TIMER->CNT;

// 2nd reading of overflow counter

hEnc_Timer_Overflow_sample_two=hEncoder_Timer_Overflow;

// 2nd reading of encoder timer counter

hCurrent_angle_sample_two=ENCODER_TIMER->CNT;

// Reset hEncoder_Timer_Overflow and read the counter value for the next

// measurement

hEncoder_Timer_Overflow=0;

haux=ENCODER_TIMER->CNT;

if(hEncoder_Timer_Overflow!=0)

{

haux = ENCODER_TIMER->CNT;

hEncoder_Timer_Overflow = 0;

}

if(hEnc_Timer_Overflow_sample_one != hEnc_Timer_Overflow_sample_two)

{

//Compare sample 1 & 2 and check if an overflow has been generated right

//after the reading of encoder timer. If yes, copy sample 2 result in

//sample 1 for next process

hCurrent_angle_sample_one = hCurrent_angle_sample_two;

hEnc_Timer_Overflow_sample_one = hEnc_Timer_Overflow_sample_two;

}

if ( (ENCODER_TIMER->CR1 & TIM_CounterMode_Down) == TIM_CounterMode_Down)

{

// encoder timer down-counting

wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle -

(hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));

}

else

{

//encoder timer up-counting

wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle

(hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));

}

// speed computation as delta angle * 1/(speed sempling time)

temp = (signed long long)(wDelta_angle*SPEED_SAMPLING_FREQ);

temp *= 10; // 0.1 Hz resolution

temp /= (4*ENCODER_PPR);

} //is first measurement, discard it

else

{

bIs_First_Measurement = 0;

temp = 0;

hEncoder_Timer_Overflow = 0;

haux = ENCODER_TIMER->CNT;

// Check if Encoder_Timer_Overflow is still zero. In case an overflow IT

// occured it resets overflow counter and wPWM_Counter_Angular_Velocity

if (hEncoder_Timer_Overflow != 0)

{

haux = ENCODER_TIMER->CNT;

hEncoder_Timer_Overflow = 0;

}

}

hPrevious_angle = haux;

return((s16) temp);

}

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

* Function Name : ENC_Calc_Average_Speed

* Description : Compute smoothed motor speed based on last SPEED_BUFER_SIZE

informations and store it variable

* Input         : None

* Output         : s16

* Return         : Return rotor speed in 0.1 Hz resolution. This routine

will return the average mechanical speed of the motor.

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

void ENC_Calc_Average_Speed(void)

{

s32 wtemp;

u32 i;

wtemp = ENC_Calc_Rot_Speed();

/* Compute the average of the read speeds */

hSpeed_Buffer[bSpeed_Buffer_Index] = (s16)wtemp;

bSpeed_Buffer_Index++;

if (bSpeed_Buffer_Index == SPEED_BUFFER_SIZE)

{

bSpeed_Buffer_Index = 0;

}

wtemp=0;

for (i=0;i

{

wtemp += hSpeed_Buffer;

}

wtemp /= SPEED_BUFFER_SIZE;

hRot_Speed = ((s16)(wtemp));

}

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

* Function Name : TIM4_IRQHandler

* Description   : This function handles TIMx Update interrupt request.

Encoder unit connected to TIM4

* Input         : None

* Output         : None

* Return         : None

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

void TIM4_IRQHandler(void)

{

/* Clear the interrupt pending flag */

TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);

if (hEncoder_Timer_Overflow != UINT16_MAX )

{

hEncoder_Timer_Overflow++;

}

}

标签: 10nd光电传感器h61光电传感器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台