楼主: mmuuss586

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

  [复制链接]
  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:50:16 | 显示全部楼层
    分享到:

    3D显示效果:
    1.jpg

    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:50:33 | 显示全部楼层
    三、拨码开关设置
    拨码开关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左右;
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:52:10 | 显示全部楼层
    1.png

    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:52:26 | 显示全部楼层
    斩波模式选择:CFG5
    CFG5:
    1:SpreadCyle模式,低速、低平稳运行模式
    0:SpreadCyle模式,高速、高运动稳定模式
    保持电流设置:CFG6
    CFG6:
    1:保持电流=运行电流/2
    0:保持电流=运行电流
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:53:16 | 显示全部楼层
    四、软件说明
    DIR+STEP接口模式位置控制(无需SPI接口)
    COM端:接24V或12V或5V
    DRV_ENN、STER、DIR:接集电极开路输出
    为测试方便:
            COM端:接3.3V
              DRV_ENN:使能,接PB14
    DIR:方向, PB15
    STEP:脉冲,PA8
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:53:32 | 显示全部楼层
    初始化程序如下参考:
      /* 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 */
      }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:54:37 | 显示全部楼层
    //相对位置移动参考(参考硬石的电机开发板资料)
    /**
      * 函数功能: 相对位置运动:运动给定的步数
      * 输入参数: 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;
        }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:55:07 | 显示全部楼层
    // 计算多少步之后我们必须开始减速
        // 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();
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:55:32 | 显示全部楼层
    //定时器中断函数参考
    /**
      * 函数功能: 定时器中断服务函数
      * 输入参数: 无
      * 返 回 值: 无
      * 说    明: 实现加减速过程
      */
    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; // 为下个(新的)延时(脉冲周期)赋值
        }
      }
    }
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2023-11-10 14:56
  • 签到天数: 141 天

    连续签到: 1 天

    [LV.7]常住居民III

     楼主| 发表于 2020-4-29 12:56:26 | 显示全部楼层
    五、开源补充说明
        如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!

    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 11:25 , Processed in 0.191685 second(s), 33 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.