任意象限直线插补

1.任意象限直线插补原理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrFMFnYC-1635666524162)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211031152906299.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fHsjMMx8-1635666524171)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211031153009004.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DkwAc7is-1635666524178)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20211031153034165.png)]

2.任意象限例程

/* 直线插补参数结构体 */
typedef struct{
  __IO uint32_t endpoint_x;           //终点坐标X
  __IO uint32_t endpoint_y;           //终点坐标Y
  __IO uint32_t endpoint_pulse;       //到达终点位置需要的脉冲数
  __IO uint32_t active_axis;          //当前运动的轴
  __IO int32_t deviation;             //偏差参数
  __IO uint8_t motionstatus : 1;      //插补运动状态
  __IO uint8_t dir_x : 1;             //X轴运动方向
  __IO uint8_t dir_y : 1;             //Y轴运动方向
}LinearInterpolation_TypeDef;
/**
  * @brief  任意直线插补运动
  * @param  coordi_x:终点坐标X的增量
  * @param  coordi_y:终点坐标Y的增量
  * @param  speed:进给速度,定时器计数值
  * @retval 无
  */
void Linear_Interpolation(int32_t coordi_x, int32_t coordi_y, uint16_t speed)
{
  /* 判断当前是否正在做插补运动 */
  if(interpolation_para.motionstatus != 0)
    return;
  
  /* 判断坐标正负,以此决定各轴的运动方向 */
  if(coordi_x < 0)
  {
    interpolation_para.dir_x = CCW;
    coordi_x = -coordi_x;
    MOTOR_DIR(step_motor[x_axis].dir_port, step_motor[x_axis].dir_pin, CCW);
  }
  else
  {
    interpolation_para.dir_x = CW;
    MOTOR_DIR(step_motor[x_axis].dir_port, step_motor[x_axis].dir_pin, CW);
  }
  
  if(coordi_y < 0)
  {
    interpolation_para.dir_y = CCW;
    coordi_y = -coordi_y;
    MOTOR_DIR(step_motor[y_axis].dir_port, step_motor[y_axis].dir_pin, CCW);
  }
  else
  {
    interpolation_para.dir_y = CW;
    MOTOR_DIR(step_motor[y_axis].dir_port, step_motor[y_axis].dir_pin, CW);
  }
  
  /* 开始插补运动 */
  InterPolation_Move(coordi_x, coordi_y, speed);
}
/**
  * @brief  定时器比较中断回调函数
  * @param  htim:定时器句柄指针
	*	@note   无
  * @retval 无
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  uint32_t last_axis = 0;
  
  /* 记录上一步的进给活动轴 */
  last_axis = interpolation_para.active_axis;

  
  /* 根据上一步的偏差,判断的进给方向,并计算下一步的偏差 */
  if(interpolation_para.deviation >= 0)
  {
    /* 偏差>0,在直线上方,进给X轴,计算偏差 */
    interpolation_para.active_axis = x_axis;
    interpolation_para.deviation -= interpolation_para.endpoint_y;
  }
  else
  {
    /* 偏差<0,在直线下方,进给Y轴,计算偏差 */
    interpolation_para.active_axis = y_axis;
    interpolation_para.deviation += interpolation_para.endpoint_x;
  }
  
  /* 下一步的活动轴与上一步的不一致时,需要换轴 */
  if(last_axis != interpolation_para.active_axis)
  {
    TIM_CCxChannelCmd(htim->Instance, step_motor[last_axis].pul_channel, TIM_CCx_DISABLE);
    TIM_CCxChannelCmd(htim->Instance, step_motor[interpolation_para.active_axis].pul_channel, TIM_CCx_ENABLE);
  }
  
  /* 进给总步数减1 */
  interpolation_para.endpoint_pulse--;
    
  /* 判断是否完成插补 */
  if(interpolation_para.endpoint_pulse == 0)
  {
    /* 关闭定时器 */
    TIM_CCxChannelCmd(htim->Instance, step_motor[last_axis].pul_channel, TIM_CCx_DISABLE);
    TIM_CCxChannelCmd(htim->Instance, step_motor[interpolation_para.active_axis].pul_channel, TIM_CCx_DISABLE);
    __HAL_TIM_MOE_DISABLE(htim);
    HAL_TIM_Base_Stop_IT(htim);
    interpolation_para.motionstatus = 0;
  }
}
/**
  * @brief  第一象限直线插补运动
  * @param  inc_x:终点坐标X的增量
  * @param  inc_y:终点坐标Y的增量
  * @param  speed:进给速度
  * @retval 无
  */
static void InterPolation_Move(uint32_t inc_x, uint32_t inc_y, uint16_t speed)
{
  /* 偏差清零 */
  interpolation_para.deviation = 0;
  
  /* 设置终点坐标 */
  interpolation_para.endpoint_x = inc_x;
  interpolation_para.endpoint_y = inc_y;
  /* 所需脉冲数为X、Y坐标增量之和 */
  interpolation_para.endpoint_pulse = inc_x + inc_y;
  
  /* 第一步进给的活动轴为X轴 */
  interpolation_para.active_axis = x_axis;
  /* 计算偏差 */
  interpolation_para.deviation -= interpolation_para.endpoint_y;
  
  /* 设置速度 */
  __HAL_TIM_SET_COMPARE(&TIM_StepperHandle, step_motor[x_axis].pul_channel, speed);
  __HAL_TIM_SET_COMPARE(&TIM_StepperHandle, step_motor[y_axis].pul_channel, speed);
  __HAL_TIM_SET_AUTORELOAD(&TIM_StepperHandle, speed * 2);
  
  /* 使能主输出 */
  __HAL_TIM_MOE_ENABLE(&TIM_StepperHandle);
  /* 开启X轴比较通道输出 */
  TIM_CCxChannelCmd(MOTOR_PUL_TIM, step_motor[interpolation_para.active_axis].pul_channel, TIM_CCx_ENABLE);
  HAL_TIM_Base_Start_IT(&TIM_StepperHandle);
  
  interpolation_para.motionstatus = 1;
}

可以看到,上述代码与第一象限直线插补完全相同,这是因为直线所在象限的判断和进给方向的处理已经在 Linear_Interpolation函数中完成,剩下的直接按照第一象限直线进行插补即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值