你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

游名科技:STM32F103+TMC2160:86步进电机和驱动一体原理图/PCB...  

[复制链接]
mmuuss586 发布时间:2020-4-29 12:18
阅读主题, 点击返回1楼
收藏 评论50 发布时间:2020-4-29 12:18
50个回答
mmuuss586 回答时间:2020-4-29 12:50:00

3D显示效果:
1.jpg

mmuuss586 回答时间:2020-4-29 12:50:39
三、拨码开关设置
拨码开关ON:设置为高电平1,反之低电平0
细分设置:CFG1、CFG0
CFG1、CFG0:
        11:64细分
10:32细分
01:16细分
00:8细分
运行电流设置:CFG4、CFG3、CFG2
CFG4、CFG3、CFG2:
        111:IRUN=31
        110:IRUN=28
        101:IRUN=26
100:IRUN=24
011:IRUN=22
010:IRUN=20
001:IRUN=18
000:IRUN=16
Irms=Vfs/(IRUN/32)/(Rsense*1.414);
Vfs =325mV,Rsense为0.05欧时,则最大电流为4.5A左右;
mmuuss586 回答时间:2020-4-29 12:51:48
1.png
mmuuss586 回答时间:2020-4-29 12:52:33
斩波模式选择:CFG5
CFG5:
1:SpreadCyle模式,低速、低平稳运行模式
0:SpreadCyle模式,高速、高运动稳定模式
保持电流设置:CFG6
CFG6:
1:保持电流=运行电流/2
0:保持电流=运行电流
mmuuss586 回答时间:2020-4-29 12:53:13
四、软件说明
DIR+STEP接口模式位置控制(无需SPI接口)
COM端:接24V或12V或5V
DRV_ENN、STER、DIR:接集电极开路输出
为测试方便:
        COM端:接3.3V
          DRV_ENN:使能,接PB14
DIR:方向, PB15
STEP:脉冲,PA8
mmuuss586 回答时间:2020-4-29 12:53:36
初始化程序如下参考:
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART2_UART_Init();
  MX_TIM1_Init();
        STEPMOTOR_TIMx_Init();                /定时器输出初始化
  /* USER CODE BEGIN 2 */
        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能
  /* USER CODE END 2 */
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
                LedOnOff();                                //LED闪烁处理
                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
                LedOnOff();                                //LED闪烁处理
    /* USER CODE BEGIN 3 */
  }
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)
/**
  * 函数功能: 相对位置运动:运动给定的步数
  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
              accel  加速度,实际值为accel*0.1*rad/sec^2
              decel  减速度,实际值为decel*0.1*rad/sec^2
              speed  最大速度,实际值为speed*0.1*rad/sec
  * 返 回 值: 无
  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且
  *           速度很慢,那还没达到最大速度就要开始减速
  */
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)
{  
  __IO uint16_t tim_count;
  // 达到最大速度时的步数
  __IO uint32_t max_s_lim;
  // 必须要开始减速的步数(如果加速没有达到最大速度)
  __IO uint32_t accel_lim;

  if(step < 0) // 步数为负数
  {
    srd.dir = CCW; // 逆时针方向旋转
    STEPMOTOR_DIR_REVERSAL();
    step =-step;   // 获取步数绝对值
  }
  else
  {
    srd.dir = CW; // 顺时针方向旋转
    STEPMOTOR_DIR_FORWARD();
  }
  
  if(step == 1)    // 步数为1
  {
    srd.accel_count = -1;   // 只移动一步
    srd.run_state = DECEL;  // 减速状态.
    srd.step_delay = 1000;        // 短延时       
  }
  else if(step != 0)  // 如果目标运动步数不为0
  {
    // 我们的驱动器用户手册有详细的计算及推导过程

    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。
    // min_delay = (alpha / tt)/ w
    srd.min_delay = (int32_t)(A_T_x10/speed);

    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
    // step_delay = 1/tt * sqrt(2*alpha/accel)
    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100
    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);

    // 计算多少步之后达到最大速度的限制
    // max_s_lim = speed^2 / (2*alpha*accel)
    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));
    // 如果达到最大速度小于0.5步,我们将四舍五入为0
    // 但实际我们必须移动至少一步才能达到想要的速度
    if(max_s_lim == 0){
      max_s_lim = 1;
    }
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速
    // n1 = (n1+n2)decel / (accel + decel)
    accel_lim = (uint32_t)(step*decel/(accel+decel));
    // 我们必须加速至少1步才能才能开始减速.
    if(accel_lim == 0){
      accel_lim = 1;
    }

    // 使用限制条件我们可以计算出减速阶段步数
    if(accel_lim <= max_s_lim){
      srd.decel_val = accel_lim - step;
    }
    else{
      srd.decel_val = -(max_s_lim*accel/decel);
    }
    // 当只剩下一步我们必须减速
    if(srd.decel_val == 0){
      srd.decel_val = -1;
    }

    // 计算开始减速时的步数
    srd.decel_start = step + srd.decel_val;

    // 如果最大速度很慢,我们就不需要进行加速运动
    if(srd.step_delay <= srd.min_delay){
      srd.step_delay = srd.min_delay;
      srd.run_state = RUN;
    }
    else{
      srd.run_state = ACCEL;
    }   
    // 复位加速度计数值
    srd.accel_count = 0;
  }
  MotionStatus = 1; // 电机为运动状态
  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道
  STEPMOTOR_OUTPUT_ENABLE();
}
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考
/**
  * 函数功能: 定时器中断服务函数
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明: 实现加减速过程
  */
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
{
  __IO uint16_t tim_count=0;
  // 保存新(下)一个延时周期
  uint16_t new_step_delay=0;
  // 加速过程中最后一次延时(脉冲周期).
  __IO static uint16_t last_accel_delay=0;
  // 总移动步数计数器
  __IO static uint32_t step_count = 0;
  // 记录new_step_delay中的余数,提高下一步计算的精度
  __IO static int32_t rest = 0;
  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲
  __IO static uint8_t i=0;
  
  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
  {
    // 清楚定时器中断
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);
   
    // 设置比较值
    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);

    i++;     // 定时器中断次数计数值
    if(i==2) // 2次,说明已经输出一个完整脉冲
    {
      i=0;   // 清零定时器中断次数计数值
      switch(srd.run_state) // 加减速曲线阶段
      {
        case STOP:
          step_count = 0;  // 清零步数计数器
          rest = 0;        // 清零余值
          // 关闭通道
          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        
          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);
          STEPMOTOR_OUTPUT_DISABLE();
          MotionStatus = 0;  //  电机为停止状态     
          break;

        case ACCEL:
          step_count++;      // 步数加1
          if(srd.dir==CW)
          {                 
            step_position++; // 绝对位置加1
          }
          else
          {
            step_position--; // 绝对位置减1
          }
          srd.accel_count++; // 加速计数值加1
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
          if(step_count >= srd.decel_start)// 检查是够应该开始减速
          {
            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值
            srd.run_state = DECEL;           // 下个脉冲进入减速阶段
          }
          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
          {
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)
            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)
            rest = 0;                          // 清零余值
            srd.run_state = RUN;               // 设置为匀速运行状态
          }
          break;

        case RUN:
          step_count++;  // 步数加1
          if(srd.dir==CW)
          {                 
            step_position++; // 绝对位置加1
          }
          else
          {
            step_position--; // 绝对位置减1
          }
          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)
          if(step_count >= srd.decel_start)   // 需要开始减速
          {
            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值
            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)
            srd.run_state = DECEL;            // 状态改变为减速
          }
          break;

        case DECEL:
          step_count++;  // 步数加1
          if(srd.dir==CW)
          {                 
            step_position++; // 绝对位置加1
          }
          else
          {
            step_position--; // 绝对位置减1
          }
          srd.accel_count++;
          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
         
          //检查是否为最后一步
          if(srd.accel_count >= 0)
          {
            srd.run_state = STOP;
          }
          break;
      }      
      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
    }
  }
}
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明
    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版