stm32 T型加速控制步进电机



#define  AXIS_PULSE_0    GPIO_Pin_8
#define  AXIS_PULSE_1    GPIO_Pin_2
#define  AXIS_PULSE_2    GPIO_Pin_7
#define  AXIS_PULSE_3    GPIO_Pin_3

u16 AxisPulsePin[4] = {AXIS_PULSE_0, AXIS_PULSE_1, AXIS_PULSE_2, AXIS_PULSE_3};// pa8, pa2, pa7, pa3
u16 AxisDirPin[4] = {GPIO_Pin_0, GPIO_Pin_2, GPIO_Pin_3, GPIO_Pin_13}; // pc0, pc2, pc3, pc13

double tim_count_num = 1000000;
#define step_psc 71

#define STOP  0 //停止
#define ACCEL 1 //加速
#define DECEL 2 //减速
#define RUN   3 //最大速度运行
#define PAUSE 4 //减速停止

AxisData axisData[4];  //工作状态

void get_ad_step(long steps, double start_speed, double max_speed, double a_speed, double d_speed, int *a_step, int *d_step){
 int a, d;
 double count = 0;
 double v = start_speed;
 a = 1;
 d = 1;
 while(v < max_speed){
  v += a_speed/v;
  a ++;
 }
 v = start_speed;
 while(v < max_speed){
  v += d_speed/v;
  d++;
 }
 if(a + d <= steps){
  *a_step = a;
  *d_step = d;
 }else{
  *a_step = steps * a /(a + d);
  *d_step = steps - *a_step;
 }
}

void init_axis_data(int ax, long steps, double start_speed, double max_speed, double a_speed, double d_speed)
{
 int a_step, d_step;
 get_ad_step(steps, start_speed, max_speed, a_speed, d_speed, &a_step, &d_step);
 
 if(steps >= 0)
 {
  axisData[ax].dir = 1;
  axisData[ax].step_count = steps;
 }else{
  axisData[ax].dir = -1;
  axisData[ax].step_count = -steps;
 }
 axisData[ax].start_speed = start_speed;
 axisData[ax].cur_speed = start_speed;
 axisData[ax].max_speed = max_speed;
 axisData[ax].a_speed = a_speed;
 axisData[ax].d_speed = d_speed;
 axisData[ax].a_step = a_step;
 axisData[ax].d_step = d_step;
 axisData[ax].step_delay = tim_count_num/start_speed;
 axisData[ax].max_delay = tim_count_num/start_speed;
 axisData[ax].min_delay = tim_count_num/max_speed;
 axisData[ax].step_run = 0;
 axisData[ax].run_state = ACCEL;
}

int stepper_t_move(int ax, long steps, double start_speed, double max_speed, double a_speed, double d_speed)
{
// if(ax < 0 || ax > 4 )
// {
//  return -1;
// }
 init_axis_data(ax, steps, start_speed, max_speed, a_speed, d_speed);
 if(steps >= 0){
  GPIO_SetBits(GPIOC, AxisDirPin[ax]);
 }else{
  GPIO_ResetBits(GPIOC, AxisDirPin[ax]);
 }
 if(ax == 0){
 }else if(ax == 1){
  TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
  TIM2->ARR =  axisData[1].step_delay;
  TIM_Cmd(TIM2, ENABLE);
 }else if(ax == 2){
 }else if(ax == 3){
 }
}

//获取ax轴运行状态  0表示已停止
int stepper_get_state(int ax)
{
 return axisData[ax].run_state;
}

//获取剩余步数 ax 轴号
long  stepper_get_rem_steps(int ax)
{
 return axisData[ax].step_count - axisData[ax].step_run;
}

//减速停止
void stepper_set_pause(int ax)
{
 axisData[ax].run_state = PAUSE;
}

void init_stepper()
{
 GPIO_InitTypeDef GPIO_InitStructure;
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 TIM_OCInitTypeDef  TIM_OCInitStructure;
 
 NVIC_Configuration();         //设置NVIC中断分组2:2位抢占优先级,2位响应优先级

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM5 | RCC_APB2Periph_AFIO , ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
 //初始化脉冲输出口
 GPIO_InitStructure.GPIO_Pin = AxisPulsePin[0] | AxisPulsePin[1] | AxisPulsePin[2] | AxisPulsePin[3];
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
  //初始化方向输出口
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
 GPIO_InitStructure.GPIO_Pin = AxisDirPin[0] | AxisDirPin[1] | AxisDirPin[2] | AxisDirPin[3]; //TIM1_CH1
 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
 
}
void TIM2_init()
{
 TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 TIM_OCInitTypeDef  TIM_OCInitStructure;

       //初始化TIM2
 TIM_TimeBaseStructure.TIM_Period = axisData[1].step_delay; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
 TIM_TimeBaseStructure.TIM_Prescaler =step_psc; //设置用来作为TIMx时钟频率除数的预分频值
 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
// TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
 
 /*初始化TIM2 Channel3 PWM模式*/ 
 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 计数值 < CCRX时 为高电平,否则为低电平
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
 TIM_OCInitStructure.TIM_Pulse = 0;
 TIM_OC3Init(TIM2, &TIM_OCInitStructure); 
 
 TIM_ClearFlag(TIM2,TIM_FLAG_Update);
// TIM_ARRPreloadConfig(TIM3,DISABLE) ;
 TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR3上的预装载寄存器
 
 TIM_ITConfig(  //使能或者失能指定的TIM中断
  TIM2, //TIM3
  TIM_IT_Update ,
  ENABLE  //使能
  );
 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM2中断
 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占优先级0级
 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  //从优先级3级
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
 NVIC_Init(&NVIC_InitStructure);  //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
 
}


void TIM2_IRQHandler(void)   //TIM2中断
{
 u8 ReadValue;
 if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
 {
  TIM_ClearITPendingBit(TIM2, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
 }
 
 axisData[1].step_run ++;
 if(axisData[1].run_state == RUN){
  if(  axisData[1].step_run > axisData[1].step_count){
   axisData[1].run_state = STOP;
   TIM_Cmd(TIM2, DISABLE);
   return;
  }
  
  if(axisData[1].step_count - axisData[1].step_run  <= axisData[1].d_step){
   axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
   axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
   axisData[1].run_state = DECEL;
  }

 }else if(axisData[1].run_state == ACCEL){
  TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
  TIM2->ARR =  axisData[1].step_delay;
  if(axisData[1].step_delay > axisData[1].min_delay){
   axisData[1].cur_speed += axisData[1].a_speed/axisData[1].cur_speed;
   axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
   
   if(axisData[1].step_delay < axisData[1].min_delay){
    axisData[1].step_delay = axisData[1].min_delay;
   }
  }
  if(axisData[1].step_run  >= axisData[1].a_step){
   axisData[1].run_state = RUN;
  }
 }else if(axisData[1].run_state == DECEL){
  if(  axisData[1].step_run > axisData[1].step_count){
   axisData[1].run_state = STOP;
   TIM_Cmd(TIM2, DISABLE);
   return;
  }
   
  TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
  TIM2->ARR =  axisData[1].step_delay;
  if(axisData[1].step_delay < axisData[1].max_delay){
   axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
   axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
   
   if(axisData[1].step_delay > axisData[1].max_delay){
    axisData[1].step_delay = axisData[1].max_delay;
   }
  }
  
 }else if (axisData[1].run_state == PAUSE){
  TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
  TIM2->ARR =  axisData[1].step_delay;
  if(axisData[1].step_delay < axisData[1].max_delay){
   axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
   axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
   
   if(axisData[1].step_delay > axisData[1].max_delay){
    axisData[1].step_delay = axisData[1].max_delay;
   }
  }else{
   axisData[1].run_state = STOP;
   TIM_Cmd(TIM2, DISABLE);
   return;
  }
 }else{
  axisData[1].run_state = STOP;
  TIM_Cmd(TIM2, DISABLE);
  return;
 }
  
  
}


 int main(void)
 {
 init_stepper();
 TIM2_init();
 stepper_t_move(1, 1000, 200, 4000, 2000, 2000);
 
 while(1)
 {
 }

 }


以上只是示列代码,正在将代码封装成可以直接调用的库


  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值