一、实验目的
对AB相脉冲信号计数并测量电机转过的位置和转速。
二、实验内容
2.1 引脚配置
初始化配置:三件套
配置TIM5为编码模式,通道一和通道二分别作为AB相脉冲的输入通道。
编码器线数为2500,四倍频后电机转动一圈编码器发出1000个脉冲。设定计数周期为20000,后面程序中会在计数溢出中断中将计数值设置为10000,则电机正转时,向上计数10000 to 20000循环计数;电机反转时,向下计数10000 to 0循环计数。
开启TIM5时钟中断,作为计数溢出判断标志。
配置TIM6作为计时时钟,确定测速的时间间隔。
设定测速频率为50Hz,fcs = 84M/(840-1)/2000 = 50Hz;开启时钟中断,在中断回调程序中计算速度。
2.2 测量位置和速度程序编写
开启TIM5时钟编码模式并使能定时器的更新中断;初始TIM5时钟计数值为10000。启动TIM6定时器并更新中断。
HAL_TIM_Encoder_Start(&htim5,TIM_CHANNEL_ALL); // start TIM5 encoder
__HAL_TIM_ENABLE_IT(&htim5,TIM_IT_UPDATE); //????????????,?????
__HAL_TIM_SET_COUNTER(&htim5, 10000); //????????????10000
HAL_TIM_Base_Start_IT(&htim6); //20ms update interrupt measure speed
在TIM5更新中断触发时,判断如果计数值<10000;则向上计数溢出,电机转动圈数加1;反之,电机转动圈数减1。
在TIM6中断触发时(触发频率为50hz),测定电机转动方向motor1_direct,若direct = 0,则电机顺时针转,若direct = 1,则电机逆时针转;转速 motor1_speed单位rpm;电机转过的位置N:1/10000 r。
uint16_t motor1_speed = 0;
uint16_t motor1_direct = 0;
int motor1_count = 0;
int motor1_lastcount = 0;
int motor1_overflowNum = 0;
uint16_t PULSE_PRE_ROUND = 2500;
int N = 0; //cycles
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){
if(htim->Instance == TIM5)//????????????,?????
{
if(TIM5->CNT < 10000) motor1_overflowNum++; //???????
else if(TIM5->CNT >= 10000) motor1_overflowNum--; //???????
__HAL_TIM_SetCounter(&htim5, 10000); //???????
}
if(htim->Instance == TIM6) //measure speed,direct //else if will take error
{
motor1_direct = __HAL_TIM_IS_TIM_COUNTING_DOWN(&htim5);//??????(??),????0,??????1
motor1_count = TIM5->CNT + motor1_overflowNum * (4 * PULSE_PRE_ROUND) ;
if(abs(motor1_count - motor1_lastcount) <= 3333) //rate rpm = 2000 2000/60/100*10000 100hz
{
if(motor1_direct == 0 )
{
motor1_speed = (float)(motor1_count - motor1_lastcount )/ ( 4 * PULSE_PRE_ROUND) * k * fcs ;//unit: r/mim
}
if(motor1_direct == 1)
{
motor1_speed = - (float)(motor1_count - motor1_lastcount )/ (4 * PULSE_PRE_ROUND) * k * fcs ;//???????
}
}
if(motor1_count - motor1_lastcount == 0) //电机停止转动后位置置零
{
__HAL_TIM_SetCounter(&htim5, 10000);
}
N = motor1_count - (4 * PULSE_PRE_ROUND);
motor1_lastcount = motor1_count;
HAL_GPIO_TogglePin(GPIOD,GPIO_PIN_6);
}
}