打印
[STM32F4]

stm32步进电机T型加减速

[复制链接]
1115|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
STM32F407的TIM1输出PWM,cubeMX配置。使用的是内部时钟,配置系统时钟为64MHz。TIM2每200us进入一次中断,每次中断中增加或减少PWM脉冲频率,达到匀加速、匀减速的效果。但是匀加速期间发出的PWM脉冲个数并不等与计算的个数,而匀减速期间所发的脉冲个数等于计算的个数。

使用特权

评论回复
沙发
huangchui| | 2022-2-20 13:30 | 只看该作者

还有什么现象?能再详细描述下吗?

使用特权

评论回复
板凳
zwll| | 2022-2-20 13:31 | 只看该作者
比如说脉冲频率从50Hz增加到28346Hz,期间需要发出502脉冲,可实际至发了6个脉冲;脉冲频率从28346Hz降低到50Hz时,实际发出的脉冲个数504个。

使用特权

评论回复
地板
dingy| | 2022-2-20 13:33 | 只看该作者
从大降到小没问题,从小增到大就不对了

使用特权

评论回复
5
supernan| | 2022-2-20 13:36 | 只看该作者

楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
6
heweibig|  楼主 | 2022-2-20 13:38 | 只看该作者
速度调节函数:void Speed_Adjust(uint16_t delta_speed)
{
                if(Motor.ActiveSpeed > (Motor.TargetSpeed+delta_speed))
                {
                                Motor.ActiveSpeed -= delta_speed;
                }
                else if(Motor.ActiveSpeed < (Motor.TargetSpeed-delta_speed))
                {
                                Motor.ActiveSpeed += delta_speed;
                }
                else
                {
                                Motor.ActiveSpeed = Motor.TargetSpeed;
                }

                if(Motor.ActiveSpeed < 50)
                {
                                Motor.ActiveSpeed = 50;
                }
                else if(Motor.ActiveSpeed > 1000000)
                {
                                Motor.ActiveSpeed = 1000000;
                }
               
                __HAL_TIM_SET_AUTORELOAD(&htim1,MOTOR_TIME_FREQ/Motor.ActiveSpeed);
                __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (MOTOR_TIME_FREQ/Motor.ActiveSpeed)/2);
}

使用特权

评论回复
7
jlyuan| | 2022-2-20 13:41 | 只看该作者
期望的电机运动轨迹

使用特权

评论回复
8
heweibig|  楼主 | 2022-2-20 13:43 | 只看该作者

使用特权

评论回复
9
heweibig|  楼主 | 2022-2-20 13:47 | 只看该作者
定时器配置函数:

使用特权

评论回复
10
heweibig|  楼主 | 2022-2-20 13:49 | 只看该作者
void MX_TIM1_Init(void)

{

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};

  TIM_MasterConfigTypeDef sMasterConfig = {0};

  TIM_OC_InitTypeDef sConfigOC = {0};

  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig = {0};



  htim1.Instance = TIM1;

  htim1.Init.Prescaler = 31;

  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim1.Init.Period = 40000;

  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  htim1.Init.RepetitionCounter = 0;

  htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)

  {

    Error_Handler();

  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)

  {

    Error_Handler();

  }

  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)

  {

    Error_Handler();

  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)

  {

    Error_Handler();

  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 20000;

  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;

  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;

  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;

  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)

  {

    Error_Handler();

  }

  __HAL_TIM_DISABLE_OCxPRELOAD(&htim1, TIM_CHANNEL_1);

  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;

  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;

  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;

  sBreakDeadTimeConfig.DeadTime = 0;

  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;

  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;

  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;

  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)

  {

    Error_Handler();

  }

  HAL_TIM_MspPostInit(&htim1);



}

使用特权

评论回复
11
jiajs| | 2022-2-20 13:50 | 只看该作者
使能定时器的预重载寄存器和输出比较预装载寄存器后,加速阶段的脉冲个数好转,但是减速阶段的脉冲个数又不对了。。。

使用特权

评论回复
12
heweibig|  楼主 | 2022-2-20 13:52 | 只看该作者
所以我怀疑问题出在定时器的影子寄存器。没有使能的时候,减速阶段的脉冲个数是对的。

使用特权

评论回复
13
heweibig|  楼主 | 2022-2-20 13:54 | 只看该作者
通过修改定时器的自动重载值,改变输出的PWM频率,同时修改输出比较值,使占空比维持在50%。定时器1的时钟频率为2MHz。

使用特权

评论回复
14
dengdc| | 2022-2-20 13:57 | 只看该作者
没看出来哪里程序问题,跟踪下看看;

使用特权

评论回复
15
wangpe| | 2022-2-20 13:59 | 只看该作者
一个方向没问题,另一个方向有问题,问题应该好找的

使用特权

评论回复
16
heweibig|  楼主 | 2022-2-20 14:06 | 只看该作者
找到问题了。频率从小增到大的过程中,自动重载值是由大变小的,在实时的调节频率时由于禁止了影子寄存器,如果最新设置的自动重载值小于定时器的当前计数值,就会导致当前即将发出的脉冲丢失;如果频率从大减小的过程自动重载值是由小变大的,所以最新设置的自动重载值不会大于定时器的当前计数值,脉冲也就不会丢失。

使用特权

评论回复
17
heweibig|  楼主 | 2022-2-20 14:07 | 只看该作者
void Speed_Adjust(uint16_t delta_speed)
{
                if(Motor.ActiveSpeed > (Motor.TargetSpeed+delta_speed))
                {
                                Motor.ActiveSpeed -= delta_speed;
                }
                else if(Motor.ActiveSpeed < (Motor.TargetSpeed-delta_speed))
                {
                                Motor.ActiveSpeed += delta_speed;
                }
                else
                {
                                Motor.ActiveSpeed = Motor.TargetSpeed;
                }

                if(Motor.ActiveSpeed < 50)
                {
                                Motor.ActiveSpeed = 50;
                }
                else if(Motor.ActiveSpeed > 1000000)
                {
                                Motor.ActiveSpeed = 1000000;
                }
               
                if((MOTOR_TIME_FREQ/Motor.ActiveSpeed) > (__HAL_TIM_GET_COUNTER(&htim1)))
                {
                                __HAL_TIM_SET_AUTORELOAD(&htim1,MOTOR_TIME_FREQ/Motor.ActiveSpeed);
                                __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, (MOTOR_TIME_FREQ/Motor.ActiveSpeed)/2);
                }
}
代码加一句,只有设置的自动重载在大于当前计数值时才更新自动重装值和输出比较值。

使用特权

评论回复
18
zhanghqi| | 2022-2-20 14:09 | 只看该作者
提示一下  PWM输出时一个周期内电平变化的时刻会触发中断,在这个中断里面重新设置arr就行,当然脉冲输出有极限,极限取决于中断执行的时间,中断时间超过arr时间会多发脉冲出来

使用特权

评论回复
19
heweibig|  楼主 | 2022-2-20 14:11 | 只看该作者
谢谢。刚才试了一下,方法可行,必须使能影子寄存器,加减速阶段的脉冲误差和我现在的差不多。

使用特权

评论回复
20
renyaq| | 2022-2-20 14:13 | 只看该作者
为什么不用S型,启动停止都稳,梯形是入门。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

869

主题

13089

帖子

7

粉丝