您的位置:首页 > 其它

stm32正交编码器问题

2015-12-07 10:50 246 查看
查看了很多资料讲解到stm32编码器,自己也做学习了一下,用stm32外接as5047测试电动机的转速,经过调试可以测出来,但是问题在于 电机的速度为什么和串口打印延时有关???路过的大神求教。。。#include "encoder.h"
#include "usart.h"
#include "usart.h"

#define TRUE 1
#define FALSE 0
s16 hPrevious_angle, hSpeed_Buffer[SPEED_BUFFER_SIZE], hRot_Speed;
static u8 bSpeed_Buffer_Index = 0;
static volatile u16 hEncoder_Timer_Overflow;
static unsigned char bIs_First_Measurement = TRUE;

void ENC_Init(void)
{
<span style="white-space:pre"> </span>TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
<span style="white-space:pre"> </span>TIM_ICInitTypeDef TIM_ICInitStructure;

<span style="white-space:pre"> </span>GPIO_InitTypeDef GPIO_InitStructure;
<span style="white-space:pre"> </span>NVIC_InitTypeDef NVIC_InitStructure;

<span style="white-space:pre"> </span>RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
<span style="white-space:pre"> </span>RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

<span style="white-space:pre"> </span>GPIO_StructInit(&GPIO_InitStructure);

<span style="white-space:pre"> </span>GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
<span style="white-space:pre"> </span>GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
<span style="white-space:pre"> </span>GPIO_Init(GPIOA, &GPIO_InitStructure);

<span style="white-space:pre"> </span>NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
<span style="white-space:pre"> </span>NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
<span style="white-space:pre"> </span>NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
<span style="white-space:pre"> </span>NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
<span style="white-space:pre"> </span>NVIC_Init(&NVIC_InitStructure);

<span style="white-space:pre"> </span>TIM_DeInit(ENCODER_TIMER);
<span style="white-space:pre"> </span>TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

<span style="white-space:pre"> </span>TIM_TimeBaseStructure.TIM_Prescaler = 0;
<span style="white-space:pre"> </span>TIM_TimeBaseStructure.TIM_Period = 2000-1;
<span style="white-space:pre"> </span>TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
<span style="white-space:pre"> </span>TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
<span style="white-space:pre"> </span>TIM_TimeBaseInit(ENCODER_TIMER, &TIM_TimeBaseStructure);
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>TIM_EncoderInterfaceConfig(ENCODER_TIMER, TIM_EncoderMode_TI12,
TIM_ICPolarity_Rising, TIM_ICPolarity_Rising);
<span style="white-space:pre"> </span>TIM_ICStructInit(&TIM_ICInitStructure);
<span style="white-space:pre"> </span>TIM_ICInitStructure.TIM_ICFilter = ICx_FILTER;
<span style="white-space:pre"> </span>TIM_ICInit(ENCODER_TIMER, &TIM_ICInitStructure);

<span style="white-space:pre"> </span>TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);
<span style="white-space:pre"> </span>TIM_ITConfig(ENCODER_TIMER, TIM_IT_Update, ENABLE);

<span style="white-space:pre"> </span>TIM3->CNT = COUNTER_RESET;

<span style="white-space:pre"> </span>ENC_Clear_Speed_Buffer();

<span style="white-space:pre"> </span>TIM_Cmd(ENCODER_TIMER, ENABLE);
}
/*
s16 ENC_Get_Electrical_Angle(void)
{
s32 temp;
temp = (s32)(TIM_GetCounter(ENCODER_TIMER)) * (s32)(4294967295 / (4*ENCODER_PPR));
return((s16)(temp/65536));
}
*/
void ENC_Clear_Speed_Buffer(void)
{
<span style="white-space:pre"> </span>u32 i;
<span style="white-space:pre"> </span>for (i=0;i<SPEED_BUFFER_SIZE;i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hSpeed_Buffer[i] = 0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>bIs_First_Measurement = TRUE;
}

s16 ENC_Calc_Rot_Speed(void)
{
<span style="white-space:pre"> </span>s32 wDelta_angle;
<span style="white-space:pre"> </span>u16 hEnc_Timer_Overflow_sample_one, hEnc_Timer_Overflow_sample_two;
<span style="white-space:pre"> </span>u16 hCurrent_angle_sample_one, hCurrent_angle_sample_two;
<span style="white-space:pre"> </span>signed long long temp;
<span style="white-space:pre"> </span>s16 haux;

<span style="white-space:pre"> </span>if (!bIs_First_Measurement)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hEnc_Timer_Overflow_sample_one = hEncoder_Timer
a25f
_Overflow;
<span style="white-space:pre"> </span>hCurrent_angle_sample_one = ENCODER_TIMER->CNT;
<span style="white-space:pre"> </span>hEnc_Timer_Overflow_sample_two = hEncoder_Timer_Overflow;
<span style="white-space:pre"> </span>hCurrent_angle_sample_two = ENCODER_TIMER->CNT;
<span style="white-space:pre"> </span>hEncoder_Timer_Overflow = 0;
<span style="white-space:pre"> </span>haux = ENCODER_TIMER->CNT;

<span style="white-space:pre"> </span>if (hEncoder_Timer_Overflow != 0)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>haux = ENCODER_TIMER->CNT;
<span style="white-space:pre"> </span>hEncoder_Timer_Overflow = 0;
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>if (hEnc_Timer_Overflow_sample_one != hEnc_Timer_Overflow_sample_two)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hCurrent_angle_sample_one = hCurrent_angle_sample_two;
<span style="white-space:pre"> </span>hEnc_Timer_Overflow_sample_one = hEnc_Timer_Overflow_sample_two;
<span style="white-space:pre"> </span>}

<span style="white-space:pre"> </span>if ( (ENCODER_TIMER->CR1 & TIM_CounterMode_Down) == TIM_CounterMode_Down)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle -
<span style="white-space:pre"> </span>(hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>wDelta_angle = (s32)(hCurrent_angle_sample_one - hPrevious_angle +
(<span style="white-space:pre"> </span>hEnc_Timer_Overflow_sample_one) * (4*ENCODER_PPR));
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>temp = (signed long long)(wDelta_angle * SPEED_SAMPLING_FREQ);
<span style="white-space:pre"> </span>temp *= 10; // 0.1 Hz resolution
<span style="white-space:pre"> </span>temp /= (4*ENCODER_PPR);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>else
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span> <span style="white-space:pre"> </span>bIs_First_Measurement = FALSE;
<span style="white-space:pre"> </span>temp = 0;
<span style="white-space:pre"> </span>hEncoder_Timer_Overflow = 0;
<span style="white-space:pre"> </span>haux = ENCODER_TIMER->CNT;
<span style="white-space:pre"> </span>if (hEncoder_Timer_Overflow != 0)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>haux = ENCODER_TIMER->CNT;
<span style="white-space:pre"> </span>hEncoder_Timer_Overflow = 0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>hPrevious_angle = haux;
<span style="white-space:pre"> </span>return((s16) temp);
}

s16 ENC_Calc_Average_Speed(void)
{
<span style="white-space:pre"> </span>s32 wtemp,wtemp_1=0;
<span style="white-space:pre"> </span>u32 i;

<span style="white-space:pre"> </span>for (i=0;i<SPEED_BUFFER_SIZE;i++)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>if (bSpeed_Buffer_Index == SPEED_BUFFER_SIZE)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>bSpeed_Buffer_Index = 0;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>wtemp = ENC_Calc_Rot_Speed();
<span style="white-space:pre"> </span>hSpeed_Buffer[bSpeed_Buffer_Index] = (s16)wtemp;
<span style="white-space:pre"> </span>bSpeed_Buffer_Index++;
<span style="white-space:pre"> </span>wtemp_1 += wtemp;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>wtemp_1 /= SPEED_BUFFER_SIZE;

<span style="white-space:pre"> </span>hRot_Speed = ((s16)(wtemp_1));
<span style="white-space:pre"> </span>return hRot_Speed;
}

void TIM3_IRQHandler(void)
{
<span style="white-space:pre"> </span>TIM_ClearFlag(ENCODER_TIMER, TIM_FLAG_Update);

<span style="white-space:pre"> </span>if (hEncoder_Timer_Overflow != 65535)
<span style="white-space:pre"> </span>{
<span style="white-space:pre"> </span>hEncoder_Timer_Overflow++;
<span style="white-space:pre"> </span>}
}


其实不用平均一下测试的转速更准确。。。。。。。。。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: