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

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

[复制链接]
mmuuss586 发布时间:2020-4-29 12:18
赞 2 收藏 2 评论73 发布时间:2020-4-29 12:18
73个回答
mmuuss586 回答时间:2020-4-29 12:53:36
初始化程序如下参考:
. t4 S3 c6 @& Z4 |" f6 F# a+ L  /* Initialize all configured peripherals */
  M- N9 n, X  y4 ]! J( K  MX_GPIO_Init();% V+ t$ \" M- l/ l% x! ~
  MX_USART2_UART_Init();; M* O0 u$ S! m+ @
  MX_TIM1_Init();9 l  O$ `: W7 e' g
        STEPMOTOR_TIMx_Init();                /定时器输出初始化$ o& C5 c/ @- E* W
  /* USER CODE BEGIN 2 */
; }9 `7 Q% ~1 ~+ H8 D& M, m        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能
" n5 h1 ~+ i2 n" Q% `6 ~7 E; y  /* USER CODE END 2 */  k% G6 t4 q9 A, F/ ~7 u$ n% V7 f
  /* Infinite loop */" q2 \7 S" f2 Z% }1 V3 w% u& ^
  /* USER CODE BEGIN WHILE */0 `7 Y4 Q  F, ]- o6 Y& w
  while (1)" h  \& s! _1 M- Q$ G0 F) @
  {
8 B/ G) |. |# X+ c0 @/ o  ?, s/ d    /* USER CODE END WHILE */: ^5 g! v6 q8 ]
                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)( l! H$ Y1 m  S* {' D7 M  e
                LedOnOff();                                //LED闪烁处理4 ]7 k, r% r4 v# O3 i
                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
9 ?0 v$ c; k6 Z9 ]9 h                LedOnOff();                                //LED闪烁处理8 U0 l) R0 p) U
    /* USER CODE BEGIN 3 */3 ~8 C7 E+ l5 L) d
  }
& \, ^+ T6 ]2 D. O& J* R
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)
' L: R+ `: A. c# m* O2 e. V; }% q/**  _; h& ?! M' R* _0 C
  * 函数功能: 相对位置运动:运动给定的步数
& b/ E5 X* j4 b( R8 W) u  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).$ t/ M" K% }, P+ G4 V- S5 }
              accel  加速度,实际值为accel*0.1*rad/sec^2
! O; l5 k1 p& k0 [& I# a              decel  减速度,实际值为decel*0.1*rad/sec^2, h- _$ f3 E7 d4 D
              speed  最大速度,实际值为speed*0.1*rad/sec! y7 n$ r! Q7 u3 U0 E
  * 返 回 值: 无! h7 i; E6 V; |, @9 @
  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
2 p- a* q- |1 J, g( W7 ]& n  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且# d$ ^% l3 t$ ^4 N5 u9 Z% ?
  *           速度很慢,那还没达到最大速度就要开始减速
) j; j  A' \2 P' ^" O  */
8 z% x: v* k" pvoid STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)
7 e$ i3 ^+ f7 d/ ^8 Y, ?/ l{  
) Z7 ]$ M6 m' ?3 B  __IO uint16_t tim_count;
9 g: A. W- f8 A7 H  |+ [& S  // 达到最大速度时的步数
& W' Q8 n2 f3 X0 Y8 G; G$ O  __IO uint32_t max_s_lim;
1 }: t6 x4 R8 Q  // 必须要开始减速的步数(如果加速没有达到最大速度)) a. V7 M1 c- \
  __IO uint32_t accel_lim;/ i. |7 t. b7 \1 V7 X

  r: c7 B  w( Z# a6 F1 d  if(step < 0) // 步数为负数3 _  u, W" u: k0 c3 \
  {
! T0 J' n5 n# D; ^    srd.dir = CCW; // 逆时针方向旋转
* J' n1 v; j1 G) I' |! O5 K    STEPMOTOR_DIR_REVERSAL();% k8 U9 ]$ Z# g- M/ s* {, S$ M
    step =-step;   // 获取步数绝对值
1 v& V& T8 T! p) ?/ @. w  }
( Y8 w0 ~2 Q% @* ]5 I2 q' P  else* O. A7 E( B. c6 k
  {
$ ~; Q  N" C& X- ^6 p( V* \    srd.dir = CW; // 顺时针方向旋转# s4 ?( ?/ U3 Q- u
    STEPMOTOR_DIR_FORWARD();
5 S* [+ E5 V& y* f' |  }
2 p6 B) T+ D( o6 u3 A  ' d% P. e1 H, C0 Y, b/ f$ @
  if(step == 1)    // 步数为1
- c" z* S; Y& g$ l  {* k7 ^$ r+ Y8 v$ m$ Z) q
    srd.accel_count = -1;   // 只移动一步
5 ]6 v) c% K& o    srd.run_state = DECEL;  // 减速状态.
% m0 b+ j+ S3 M    srd.step_delay = 1000;        // 短延时        % g" Y  s3 D4 a  u5 |) u& d
  }$ }' a: i* o/ c9 R- d
  else if(step != 0)  // 如果目标运动步数不为0# {+ D4 M7 N+ O$ F4 H
  {" O% S( ]' M3 g" ]
    // 我们的驱动器用户手册有详细的计算及推导过程
$ q/ A7 h$ H) [
, U% v( a# v$ M    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。
3 ]4 M; L9 a8 B. N" ?6 X    // min_delay = (alpha / tt)/ w* _7 X5 q* S) o- `9 a& `
    srd.min_delay = (int32_t)(A_T_x10/speed);
, z& x3 H5 T* \& u9 f7 t  @0 ~0 z  P
    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
7 S* ~( P3 i. i* G: Y    // step_delay = 1/tt * sqrt(2*alpha/accel)
3 [* V+ v9 I9 K/ `    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100" h- r7 z( w& b* @2 z
    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);# [' J, H3 _1 H% {6 v6 ?

  N5 t- S* p  @    // 计算多少步之后达到最大速度的限制
5 u2 g# w4 P& j" Q7 `    // max_s_lim = speed^2 / (2*alpha*accel)0 k$ t( c3 U2 T6 ?2 j
    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));* V" S) M4 x+ l' W: p
    // 如果达到最大速度小于0.5步,我们将四舍五入为0
6 U* c4 g, q5 L7 P6 f0 T4 M9 G& B    // 但实际我们必须移动至少一步才能达到想要的速度0 O3 ]# V, g$ Y3 W) z+ p
    if(max_s_lim == 0){
/ R+ U4 y& F/ H2 r( Z) {      max_s_lim = 1;
  _/ O0 ~" F- g, D  W6 R; R6 ~    }4 B3 g, q; K* B
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速9 h  m3 ?  Y! e0 q( o7 a7 a. q
    // n1 = (n1+n2)decel / (accel + decel)" ]5 }8 M0 B2 a% x) W5 L' I6 M  f# U
    accel_lim = (uint32_t)(step*decel/(accel+decel));
$ A6 K, h0 L- s    // 我们必须加速至少1步才能才能开始减速.$ w2 L  W' p& r3 ]$ P) L7 C' t
    if(accel_lim == 0){& G/ n1 V/ \' ^3 Y' ~8 I
      accel_lim = 1;) X5 B. [( `1 h4 D$ ?6 c
    }; S2 |, D4 |$ b+ T& S3 C

7 D( D' p1 m. o    // 使用限制条件我们可以计算出减速阶段步数
& N+ X! O& ~  A7 v+ ?0 o    if(accel_lim <= max_s_lim){; m+ G$ V1 \3 f% v! e
      srd.decel_val = accel_lim - step;
( r# K* [' S; a, a4 u5 T" p5 \3 |    }; c& y) Z0 X- n
    else{  a2 @. E% h3 `- N8 z4 S6 W1 [
      srd.decel_val = -(max_s_lim*accel/decel);
8 r4 b9 S/ n9 j4 ?! j& N    }! ?. D. w' V: C; ?: l
    // 当只剩下一步我们必须减速/ u1 N$ {; T" ~; K
    if(srd.decel_val == 0){. M; o' l9 p* O1 ]! J9 j- V
      srd.decel_val = -1;0 q" L3 W9 Y0 c) M% F% d5 P
    }
  c3 {2 c7 i) x, {) q  @/ k* }
7 x  p$ J8 t: Z* b" t2 O9 [9 a7 N    // 计算开始减速时的步数
4 v4 F% q! s( K7 P    srd.decel_start = step + srd.decel_val;
% m% J4 s1 x0 }0 X3 y
4 l8 ^! }) t( r( Q) V& m! Q    // 如果最大速度很慢,我们就不需要进行加速运动
* I# \# B  d$ r! f- c    if(srd.step_delay <= srd.min_delay){
$ e9 @2 A/ `" ?$ ]4 v      srd.step_delay = srd.min_delay;, A9 c4 t% `5 j# |: m+ ]
      srd.run_state = RUN;& S# m8 J* W* D9 r  b* [2 x( _
    }/ ~7 S3 X0 T' e  n0 \- \3 K5 [; e
    else{: r7 \. a9 c; {  X/ u% k% _0 P
      srd.run_state = ACCEL;3 F7 ]4 j7 ~' m) \$ Z
    }    8 t7 Y6 O% S4 ^
    // 复位加速度计数值/ k8 a  r) j( P% h2 r
    srd.accel_count = 0;" ^! J/ g3 ?. _( M) ~" Z% F
  }
( b/ U! f1 N% O! c4 J9 o8 X  MotionStatus = 1; // 电机为运动状态
7 v& i& p1 c4 F, q5 z  l( c( b  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);1 ^; p6 M; r, o5 q0 c/ L
  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值
' V1 ~9 Y! d/ x! V& V9 A+ _  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道 8 B- r% z4 ~' y) r5 d% g
  STEPMOTOR_OUTPUT_ENABLE();: ^$ s) h$ {6 F" _1 Z
}( F* V: _& W4 ~: c) C1 p; c
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考" K) Y6 R1 D4 D. `8 ^4 j
/**( N0 u$ I' l' w
  * 函数功能: 定时器中断服务函数. d! q. V  t3 V  {8 y+ l
  * 输入参数: 无# g: W% B+ k9 @7 \
  * 返 回 值: 无
- s5 |* a$ |6 d& p( h4 v% C  * 说    明: 实现加减速过程: i/ e- e  _% z$ G' t
  */
; R3 t4 U  w7 R, i' _3 Pvoid STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理, T7 |" @, {: F4 [. |
{
8 h' }) n: A# O1 Q  __IO uint16_t tim_count=0;" b" b) f( {3 N# V: ?) p8 `! f
  // 保存新(下)一个延时周期
( T4 v  b1 Q, a( Q  uint16_t new_step_delay=0;* \3 f( A- U+ o
  // 加速过程中最后一次延时(脉冲周期).& y2 ^% Z# V, r# J9 o
  __IO static uint16_t last_accel_delay=0;1 e3 q0 r4 X' `9 u
  // 总移动步数计数器
3 j1 o/ w) O; `) L  __IO static uint32_t step_count = 0;
8 @$ J7 k8 q) I4 @  // 记录new_step_delay中的余数,提高下一步计算的精度
' {0 M5 I& i/ c- Z  __IO static int32_t rest = 0;
0 x# F0 a, c2 \3 O0 H5 E' e$ A  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲* U: D" c- d: n( U5 R3 E. B9 O
  __IO static uint8_t i=0;
8 Q+ v2 @  b; w  
7 s- G" T: m8 ?. D  f/ I  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)( z+ ^5 g+ @  F0 E( ~9 v( A$ j
  {$ Z( _( Z& F( ]
    // 清楚定时器中断
) ?( Q5 |( q6 d4 D, i    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);+ Q: a% X/ Q4 c- a' Z1 P5 d& c$ R
   
$ O- d2 P& {+ e0 a    // 设置比较值
0 |4 \8 N. j: F+ A$ z  m3 C    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);5 N/ U/ b& ?5 R3 I( A" h
    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
9 V* S' {& {5 a# [% m' G" k, ^; M$ H! }5 u, R, E0 u
    i++;     // 定时器中断次数计数值
8 A; n+ l, k  L  B! k  t+ H    if(i==2) // 2次,说明已经输出一个完整脉冲
2 Q0 P4 b8 u1 ^8 m$ w& j    {$ p9 h: E" q2 {
      i=0;   // 清零定时器中断次数计数值
( ^. ?  T) F/ s  p$ y2 h( Z      switch(srd.run_state) // 加减速曲线阶段- p$ j7 U; g' [* z) H4 W" f
      {& O* \3 ^0 }; T4 k/ v0 [
        case STOP:
7 ]2 p% C- b+ e7 W          step_count = 0;  // 清零步数计数器
$ x1 y0 c4 ~) _* w9 h          rest = 0;        // 清零余值
8 g' O6 l* J# J( e+ K/ ?          // 关闭通道# Y( }) Z0 u  G& V
          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        " i9 N- e+ C3 q: q
          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);0 A; r6 X# y+ P; h
          STEPMOTOR_OUTPUT_DISABLE();
' T5 x* ^: t- Q; p7 `; ]# ~          MotionStatus = 0;  //  电机为停止状态     
" D/ \4 Z' f# z$ @' ]          break;
% S! n& D0 R  K- s9 S: c* |8 i- t7 Z3 X4 L
        case ACCEL:: S8 M( I+ i' N" l: V
          step_count++;      // 步数加10 E# F8 L( ], {0 ^) b
          if(srd.dir==CW); R0 \4 k+ |8 Z0 u* `! ~% v% C
          {                  * d& P; Z, s; }1 a
            step_position++; // 绝对位置加1# ^1 j& @: K% [: l4 w! G
          }& g; [6 v# R3 {8 i) v# N' `9 P, P
          else
/ U( C# m; ], {7 ?+ n, }          {
) m4 K3 k  e6 j1 U+ R; V4 H            step_position--; // 绝对位置减1, P5 [! G+ J; P& j) u
          }! n, u7 n$ d1 E- n
          srd.accel_count++; // 加速计数值加1
4 C1 C: E6 U2 {6 f$ P          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)
7 y3 T9 B8 w* Z( U$ a          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
6 n$ ~- u& m& Q* @+ [          if(step_count >= srd.decel_start)// 检查是够应该开始减速
$ G- U/ b0 z9 o) F  E9 _. t, P. \          {* L; v# W/ j$ |! B, c
            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值
, p1 I" f* |7 C) q$ ]; e& s            srd.run_state = DECEL;           // 下个脉冲进入减速阶段
! Y% z( H5 O/ E! N+ h% j' M          }' l6 ]" q" {0 P. k7 R
          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
& w  K* n+ O9 [5 S- B7 _          {5 L* w( w- {, Y$ y( p
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)2 m" D2 {, n: o9 J  X% \4 E. o; x
            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)
" K# I2 f. ~0 M, ^            rest = 0;                          // 清零余值1 H# W3 F/ U8 V& t0 o6 I6 D
            srd.run_state = RUN;               // 设置为匀速运行状态9 y& B: ?4 H! v3 U
          }" s& x; i/ L2 R
          break;1 Z: i9 h8 Y5 F5 O6 x  L

, D) U3 I0 S5 g& j        case RUN:( B2 O3 @7 s2 k
          step_count++;  // 步数加1% \4 O% i  {9 J# H
          if(srd.dir==CW)) Z2 s  [, `5 Q! o/ N
          {                  - J. v7 A. Y7 F- k3 Z! F. A9 c
            step_position++; // 绝对位置加1# a/ N" s+ V* r" T! g
          }
' y8 \( K1 {: S: h  ^          else
  p$ {4 V7 S1 E          {
5 g2 f" K/ |% Z9 N            step_position--; // 绝对位置减1
6 \- r; d1 g4 d1 D- ^1 Z+ h1 J  n          }
' R* I+ I0 L. j& {' M. V          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)
' K) p6 F  \% @          if(step_count >= srd.decel_start)   // 需要开始减速
& ^) b; S) V6 E: E# i* C; t          {
% W+ Z9 |/ A: `9 U; H- T            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值
5 G! h& F: T: n7 I- j            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)6 @4 ^  K9 Q8 e8 T& ~6 R; B8 Q
            srd.run_state = DECEL;            // 状态改变为减速0 x& u+ u9 D2 X0 O  K
          }
) t; K6 M% J1 `" F          break;
) z% h7 T' }6 \$ c2 N
/ L0 _3 L6 j: X  Y/ A        case DECEL:
/ g; ^# k3 U8 Y( P1 @5 n2 y3 ]' C          step_count++;  // 步数加1
% ^; Y% S8 z& O5 t% ^          if(srd.dir==CW)
& T, R  h2 ^& l5 c8 u& _5 ]; ^+ P  j          {                 
% \0 @$ e: W8 I9 H            step_position++; // 绝对位置加1" M# c# }: K9 N7 @$ ?
          }! a) C4 t5 Z6 d0 Z, \' v
          else
4 O# n( S5 j- \+ w          {4 c4 r( A; u; b' T8 V( ~% c
            step_position--; // 绝对位置减1! I. N* j8 y  v5 R
          }9 D% w" q# f! [, d
          srd.accel_count++;' t! ~# R& y3 y3 A8 ?6 v. F: M2 H
          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
* z0 B( t; m( V& `; [; U. v/ r) T          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差! z4 F, y& E* c- n' S# I
          / @( m, i! ?* \! V  K) a) y5 W
          //检查是否为最后一步
3 s# c+ r/ @" h4 C. R7 l          if(srd.accel_count >= 0)5 U/ I- w. b9 ~7 J8 w8 H: {
          {& Z( L+ Y( B- r. ~' s+ ]. r
            srd.run_state = STOP;
6 O' ]' x2 h5 [/ W          }
1 f5 ]0 x4 G/ o# t          break;( Z. x! e6 e3 h4 ~0 ?" T' |, |
      }      
0 ]7 ?* k) `) Z5 D! \0 P      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值8 ~, L/ `7 B# r/ h0 r6 E
    }
2 o' N3 z  h4 s8 d! r2 S  }
% I3 d9 R) y- P% n7 o$ g0 ~}
+ W* Z% b6 U0 u1 [
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明9 Y0 p! y* D2 l5 k
    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!& Z% J- X9 A' V6 N

4 {) F# \% \8 r% U2 i- y
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。% K, F3 H* x" V! Y

( }& P( W! C; O) H# `技术群:171897584. a% w+ ~; F8 {) Z8 Z; ?) p8 i
公众号:游名开源
- e) X# K, Y8 B+ x* T  A
mmuuss586 回答时间:2020-4-30 10:19:43
mmuuss586 回答时间:2020-5-1 21:22:14
mmuuss586 回答时间:2020-5-5 19:56:35
mmuuss586 回答时间:2020-5-9 13:16:00
cpsrd570 回答时间:2020-5-9 18:22:38
电机相对运动的函数和中断函数看着像硬石开发板里面的代码。
mmuuss586 回答时间:2020-5-11 12:28:03
cpsrd570 发表于 2020-5-9 18:229 T9 z  ~& K- P
电机相对运动的函数和中断函数看着像硬石开发板里面的代码。

% V, U! Q! Q- R% L+ ^1 _. M& L1 [是的,参考他们的,有说明:写着参考硬石的
mmuuss586 回答时间:2020-5-16 20:42:48
mmuuss586 回答时间:2020-5-20 12:07:25
mmuuss586 回答时间:2020-5-21 16:26:39

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版