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

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

[复制链接]
mmuuss586 发布时间:2020-4-29 12:18
阅读主题, 点击返回1楼
2 收藏 2 评论73 发布时间:2020-4-29 12:18
73个回答
mmuuss586 回答时间:2020-4-29 12:53:36
初始化程序如下参考:
" z8 v) ~; w  Z8 i) K: K2 H& o% s  /* Initialize all configured peripherals */1 I+ ^/ {7 m6 T, H: ~$ l, I
  MX_GPIO_Init();
, {" \+ j2 Q7 B) m# \  MX_USART2_UART_Init();" E8 b  X0 f$ i' X) x2 @
  MX_TIM1_Init();2 R5 E; @! H0 l6 ]7 q
        STEPMOTOR_TIMx_Init();                /定时器输出初始化
8 ]5 H6 s! w9 z& r2 B: c4 j  /* USER CODE BEGIN 2 */: ~! T8 D8 V7 w0 A) [
        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能# R2 m; _# a* Y& Z; A$ p8 u6 u
  /* USER CODE END 2 */" l+ o) x6 T8 h: i% M$ v& ~
  /* Infinite loop */5 f' ?: T, E6 \0 E
  /* USER CODE BEGIN WHILE */
- S% R% _5 i- L9 O  while (1)
/ ^, _8 G" [: d$ [1 a! [" {  {
8 l: c' C- m7 G. t, P+ L    /* USER CODE END WHILE */2 g0 Z( G8 \- J; h, F! W+ A1 v
                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
& u0 n/ K+ g6 C3 I                LedOnOff();                                //LED闪烁处理
. L' h0 R5 g9 d. {                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
' ^$ e7 Y1 E# s2 R: `3 P7 A                LedOnOff();                                //LED闪烁处理6 g' O, }9 f0 J! p& V
    /* USER CODE BEGIN 3 */
& C# I3 ?7 }8 _; D$ {- `* j1 L  } ; M% s1 i4 x) ^
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)  u  q& F4 g- t+ `
/**
( |5 g. {2 W$ @* c/ V% K  * 函数功能: 相对位置运动:运动给定的步数) s4 g! J/ a# ~: I0 k
  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
& o& a; J$ U6 B$ ^6 V8 s              accel  加速度,实际值为accel*0.1*rad/sec^25 l  l2 v. W0 V+ u* W
              decel  减速度,实际值为decel*0.1*rad/sec^29 _( {& a6 h& N! U
              speed  最大速度,实际值为speed*0.1*rad/sec
! a; E* r. v" F& a$ Q& F  * 返 回 值: 无
' r" T' n- ]+ G, I7 g. |3 ~4 t" X  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
) ~8 s8 B6 W' O, Q' _0 T  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且0 f6 j/ T8 l/ Q- R+ F5 I  h7 w/ T+ ?
  *           速度很慢,那还没达到最大速度就要开始减速6 S  t5 e' c* a' `9 m& v  F
  */
9 m$ h  b1 E, q6 t: \void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)/ ^/ t) V. N  J' o
{  
3 O& [. _- r9 A$ {3 L$ w  __IO uint16_t tim_count;% O/ A/ P% J. n4 z. W
  // 达到最大速度时的步数8 p# ?9 N7 X8 b9 S. A! p( B* {6 c5 b
  __IO uint32_t max_s_lim;
5 E( k! y! K! d  // 必须要开始减速的步数(如果加速没有达到最大速度)
; l5 p3 M& k0 A6 p% q/ V+ D  __IO uint32_t accel_lim;
  G, M6 j( W( L( p! E. r" x- e
7 g  `; ?( J6 c+ w& W  if(step < 0) // 步数为负数
4 y: V1 O+ y/ Z1 W* _, v" I  {- H% o9 p1 }/ h& A9 c; n! E( X9 H
    srd.dir = CCW; // 逆时针方向旋转
0 l' {  n  c6 z5 ~) t+ ~    STEPMOTOR_DIR_REVERSAL();
7 T& \' M  \' V# W9 D3 }    step =-step;   // 获取步数绝对值
0 W9 f& t; ~3 v4 H7 W9 F6 d. h2 v  }5 K# @) k0 C- A) S
  else$ z' M, L; i4 O
  {
1 x  H* v3 Y8 q, r' v. T. W) ]    srd.dir = CW; // 顺时针方向旋转
3 @5 A* k% p; V" J( |2 ?    STEPMOTOR_DIR_FORWARD();. ~+ Z. k4 I! S
  }
& U% Q; `$ O$ Z# Z  9 K8 T  J1 i% t7 {/ s
  if(step == 1)    // 步数为1
' @1 Z7 C2 S4 \" U  {/ F& r0 a7 ^% N# f; ?, @
    srd.accel_count = -1;   // 只移动一步6 m& ]& I9 L$ M& \- r
    srd.run_state = DECEL;  // 减速状态.
1 D: Z7 r8 i) x, J  T" u    srd.step_delay = 1000;        // 短延时       
6 `" T" P! W4 c8 ^  }1 Q$ b, E8 L# t+ ?  i1 H
  else if(step != 0)  // 如果目标运动步数不为0
" z" k# }; @- G2 _  {
9 v' u+ X6 v( K$ N+ d    // 我们的驱动器用户手册有详细的计算及推导过程0 z9 U5 V3 U/ q

1 D/ k' d' R1 a) ]5 C1 \    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。* p  Q! s+ P) z+ M
    // min_delay = (alpha / tt)/ w
1 s$ r3 a( Q. S. G6 t4 X% L    srd.min_delay = (int32_t)(A_T_x10/speed);
# m( ~) ^8 G/ c+ o' ]/ x+ @" V( b% ^
    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
' C& Q8 g7 }1 Q1 u: X    // step_delay = 1/tt * sqrt(2*alpha/accel)
& B/ l6 H- t4 M. K* m5 {$ U    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100
9 Y5 f5 Z# u1 C; R, Y    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);
3 d% s+ y2 I( {4 C) s" t9 S/ E5 Y1 a" \2 s
    // 计算多少步之后达到最大速度的限制
, x! w$ B/ X  ]$ ?    // max_s_lim = speed^2 / (2*alpha*accel)
* e0 Q6 e/ n0 ]' Z' k9 ]    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));
) y) W4 O1 Z3 j6 `    // 如果达到最大速度小于0.5步,我们将四舍五入为0
; S6 w8 E7 |" @( N4 ^/ q    // 但实际我们必须移动至少一步才能达到想要的速度( W/ g  T4 |: v) `. A8 V
    if(max_s_lim == 0){
. e2 S1 h4 v) W1 h2 Y' c3 \      max_s_lim = 1;
& |8 Q% f% _1 y    }
- p2 q9 m# Z% A- m1 n. X
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速
6 k+ u1 a2 d3 Q2 J5 p8 F, Y    // n1 = (n1+n2)decel / (accel + decel)& v8 o5 Z+ x* l) Y, O8 g( v
    accel_lim = (uint32_t)(step*decel/(accel+decel));) \- {# k0 a. ?  d8 t) D5 B
    // 我们必须加速至少1步才能才能开始减速.
- w8 t" S" [( m  p9 u8 _- L) p8 X! P    if(accel_lim == 0){5 b0 R) a9 C7 `7 S( ?* L; c
      accel_lim = 1;
8 o; w) X0 w6 v) t    }
0 a9 N+ {" X- q. ~5 ~) Q0 O8 X8 t' B7 v  p+ [8 Q
    // 使用限制条件我们可以计算出减速阶段步数0 }8 w' P, ?2 h. Z" Q
    if(accel_lim <= max_s_lim){5 H5 t$ W! w' H1 ^2 {
      srd.decel_val = accel_lim - step;* q% D* i7 \  M) \: e% b0 L( ~
    }+ n8 y1 l" X- ?
    else{4 j& o" f( K1 D6 }
      srd.decel_val = -(max_s_lim*accel/decel);9 a' X+ K2 _2 K
    }
0 t# h* T/ ^( |$ _2 `  v$ a    // 当只剩下一步我们必须减速
# {4 \3 _( _! y4 X  I    if(srd.decel_val == 0){
% z& G0 l# J# ?- j      srd.decel_val = -1;9 M) L- y& n. S: O  ^
    }2 L' {$ W& f% Z6 S
+ x2 ^. Y% o- k- |% C! M$ r1 ~
    // 计算开始减速时的步数
+ t3 G" w7 l6 X, M' n# |7 m% m) z    srd.decel_start = step + srd.decel_val;
$ x+ n# ~1 a8 T9 Q
0 ~3 V& y0 H% ?( J    // 如果最大速度很慢,我们就不需要进行加速运动
% z; W' v! O5 K2 G5 S    if(srd.step_delay <= srd.min_delay){
1 R  m! O1 {8 [& q9 @+ x8 s# S$ q      srd.step_delay = srd.min_delay;$ A/ j* F; |. v0 P# K  I
      srd.run_state = RUN;
+ \$ p3 |0 a5 H: T    }
9 X) }) C# i2 Z# g) J1 h    else{
% s6 z" v: c; |# ?% Z$ r$ n+ H+ h      srd.run_state = ACCEL;. A1 E& S( S0 C
    }    1 D# h5 i9 [2 t( R. z+ r" W
    // 复位加速度计数值+ h; c& C2 {) p6 _
    srd.accel_count = 0;. g6 `- ?2 E) z0 @
  }+ f0 Z$ C! K% T& W
  MotionStatus = 1; // 电机为运动状态
, v- B3 l, G: |' h, W  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);8 `; o$ D' w  h& W
  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值% o( d. a. F' U
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道 4 c* s. ]+ s2 q. C9 V$ }) N
  STEPMOTOR_OUTPUT_ENABLE();' N# \" y, L. h( r: o
}
8 I) T, L1 B5 h3 [8 ]) J
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考4 ], ~- F. m* L* X0 N
/**; c4 e9 S0 \/ l* ~4 X! D
  * 函数功能: 定时器中断服务函数, ^  v: n( s+ z: J9 e
  * 输入参数: 无
' d6 V' p3 }& p# W. t- k. ?/ z/ `  * 返 回 值: 无$ d7 Q4 t; [% Y' h. o5 x
  * 说    明: 实现加减速过程
0 P* s9 c7 f* r  */5 \, D" @7 V+ |
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理  M6 A/ i3 T8 V: D% N& h
{
+ C+ m: u7 ~0 f' W4 j: H5 P  __IO uint16_t tim_count=0;  \8 o6 H6 T  ]: M. g
  // 保存新(下)一个延时周期5 E8 C9 G% x0 `/ N7 w1 g4 r
  uint16_t new_step_delay=0;
7 R' Z4 W" X# `& a  // 加速过程中最后一次延时(脉冲周期).& T2 @' l4 z6 x' t$ `0 i4 _& l  K' r9 U. s
  __IO static uint16_t last_accel_delay=0;9 K" \: i6 L1 m
  // 总移动步数计数器
5 h* E/ v) E. l0 m8 x; r  __IO static uint32_t step_count = 0;+ c8 j# j+ L/ C  ]+ I% j3 P5 Q4 x
  // 记录new_step_delay中的余数,提高下一步计算的精度
3 e0 r6 l- |2 S2 U3 B4 n  __IO static int32_t rest = 0;+ m0 x$ r  `' R& Q3 ^- R  F
  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲5 z) Z% |3 Z/ [9 F/ C
  __IO static uint8_t i=0;" Z2 f" ]; y* H# T' `1 K9 {
  . [4 Y$ ~1 L! u
  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
1 i. d. J  V2 B- i# @1 R7 H  {7 u2 N; o! V6 N) C4 W" P7 r
    // 清楚定时器中断+ `% I: ]& ]- X  o1 j
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);
' g/ o4 h0 X7 ?7 X- D   
$ K( I- f# h) f% [* H5 _    // 设置比较值* I& Z. y" c! f
    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);: y5 D2 p& R9 W9 j/ i9 _
    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);$ u# u; R, J7 q6 i0 c
/ _' e. m' C/ H7 Z4 L& a
    i++;     // 定时器中断次数计数值# @3 M, m4 `7 d- H% |
    if(i==2) // 2次,说明已经输出一个完整脉冲
% w; Z$ I1 J1 p) w3 r& ?' U9 O    {
% T: h7 `$ X& x0 N& K) |' L' S      i=0;   // 清零定时器中断次数计数值# G1 d, F6 B- w, \! {( Q
      switch(srd.run_state) // 加减速曲线阶段
& r; v* u9 f# E1 k1 A      {2 t  Q2 a( J1 S+ K
        case STOP:
' }1 C+ ]3 z5 ?( Q3 h          step_count = 0;  // 清零步数计数器  ^6 |' z% P0 E3 r: v& X8 }
          rest = 0;        // 清零余值
4 ~# p5 |0 c1 ~! B8 K. B3 j, _; i: Z          // 关闭通道
8 I, q8 C8 G. \; d- U, k          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        
) _+ p* R1 {2 d. T/ O          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);
( o' v3 w! z0 w' j4 r: `          STEPMOTOR_OUTPUT_DISABLE();
2 Z* ]* N' i7 O          MotionStatus = 0;  //  电机为停止状态     
9 _5 F: g1 f! T$ ^% W          break;6 q8 [2 U/ h4 q# f6 W1 W3 _

4 d' K* T" s8 @8 B2 K$ s        case ACCEL:0 n6 _; G" C1 k8 h$ P3 R9 E0 A/ Z
          step_count++;      // 步数加1
2 s4 n9 P% @" |/ k          if(srd.dir==CW)
& w) c7 ^. i" G9 n3 R, U          {                 
+ q( `5 V3 v1 k: o5 ]            step_position++; // 绝对位置加1' x. ?! a1 l5 J" o; F
          }' m; ?$ s  w& P4 b; D1 Z( O/ b
          else
$ K" \# x* p$ r0 m          {
- h3 f  s, m+ m- c9 }' R2 A. M2 C            step_position--; // 绝对位置减1
& s' L- T8 F9 a2 y1 V' n  L          }
/ l9 M0 D* o9 p% S9 z# T+ {: p          srd.accel_count++; // 加速计数值加1" o, t5 m; W& E' ~
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)/ {0 ]( L' U2 I, U' F& C* q
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
& E- ^; u' ^6 Y" U7 }4 O: ]          if(step_count >= srd.decel_start)// 检查是够应该开始减速
9 @8 C% ?6 J4 T. s5 C+ O          {
3 b# v% S) j( ]0 H            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值
7 a1 e" x6 U- U+ u6 M            srd.run_state = DECEL;           // 下个脉冲进入减速阶段8 j  S; D- ]& X  C0 w9 Z0 ]* V
          }  J+ `3 c% [  W+ V! C
          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
  p6 ~. j  @: |/ X          {* m/ O8 ]2 a% X" T
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)" P5 @- M! p0 @  ^4 M$ n* I3 P
            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)6 R; K3 P( Z: g4 \
            rest = 0;                          // 清零余值! g# d" C) y* u! e' `$ _
            srd.run_state = RUN;               // 设置为匀速运行状态
# _$ f1 s7 D# p2 X, @          }
6 C1 [% r% T* J. W: u" }: o          break;
+ @3 `* E7 _% y, c2 d, [
# d  k" F5 w3 w8 I3 M& g# {) B        case RUN:( {7 Q0 x# A7 v7 @
          step_count++;  // 步数加16 ]3 @8 |! ~) l
          if(srd.dir==CW)$ U( p' l3 m! {! h# W: t# L7 n" ]: E
          {                  5 i# @/ o3 r9 o0 @6 p
            step_position++; // 绝对位置加1
  q6 `9 z; y7 ]% r  T' s1 y          }
: |. M2 f* ?0 Z% w  ]# G          else
+ V# R0 H& O! u          {) s5 H5 R7 g5 ]2 y7 o( W* V
            step_position--; // 绝对位置减1
% [4 X' q. g) M: t9 ^% ]% d( t; W          }
* D. n- _# M; v; d. U          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)
9 j' O' A# z/ N0 Q% }          if(step_count >= srd.decel_start)   // 需要开始减速6 Y9 l1 T4 U: o/ j6 |" E' E' H5 ~) H
          {
/ A9 m3 v8 d6 D$ g            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值) S; O( f: H" _3 |# G5 j* i9 b; Y
            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)6 I6 A) B8 a2 q. T$ H, V
            srd.run_state = DECEL;            // 状态改变为减速# N( D4 Z7 c7 n' u2 O
          }7 U  @. Q1 ~" i1 h
          break;& j. u) R/ h/ F+ M* d

4 p8 a% j" x# r; B% E        case DECEL:
0 d+ ?8 Q: [( ]* [3 ^6 _          step_count++;  // 步数加1
  l" s' b# h5 X. W, H2 B% y( c          if(srd.dir==CW)+ V5 m8 f2 F( r8 y+ O+ M5 ^3 Q
          {                 
- \) c2 M- g1 ~. Z            step_position++; // 绝对位置加1& i- l. y  I. ]/ U0 a! x
          }
. i) `* k& L& a5 U. g3 w9 J          else
  |& p, o2 n! Y8 ^  c$ I          {
$ Y. q+ e5 c% k1 W9 {            step_position--; // 绝对位置减1% l% |& u$ Z) Y* o: e$ _% w+ L) a9 q
          }
  e% _7 L* t, @8 b: T) L          srd.accel_count++;
2 ~* u3 p# K# G# g' k          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)& V& x8 d  `2 W, i. U1 G
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差4 W. D# P/ @6 X$ U. T) l
          ' l" n. V; M  I& |( f$ K1 \: x
          //检查是否为最后一步2 A" v7 P; E2 }2 P
          if(srd.accel_count >= 0)# L# P" U5 i% D: Q6 h; r
          {
6 h- v' v% n+ |: L1 B1 D" {; h- s9 L0 }            srd.run_state = STOP;: X, ^) Z7 y( W8 K8 t, q; ~
          }3 \. e0 S0 w1 C) K1 J( B
          break;
* c3 {" U4 Z3 |7 l" A      }      
- d, p  m1 H# R* D5 d7 z      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值7 Q- ?/ R" y, S/ z& l4 B
    }( W. \8 U7 j( q8 t, h0 l! {
  }
! n/ D* k! a9 k}
$ f" h" m) r# X/ g
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明1 v  T7 T) b6 T9 G& [9 ]# j
    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!' F& h8 t) }. i1 k! c' \7 Y. q) P

( M# {  _# e8 s3 W6 N
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。
& Z2 r; H# t: q( w: D: G, g
, n9 _! c( f6 W8 L技术群:171897584& }" R: p/ Q2 L$ Z$ p
公众号:游名开源
( |* @9 D, F# f1 B; \6 p
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:22
0 Q+ Y! p+ A* `3 f电机相对运动的函数和中断函数看着像硬石开发板里面的代码。
9 w8 T; Y. a: k) B6 J, {7 c+ g
是的,参考他们的,有说明:写着参考硬石的
mmuuss586 回答时间:2020-5-16 20:42:48
mmuuss586 回答时间:2020-5-20 12:07:25
mmuuss586 回答时间:2020-5-21 16:26:39

所属标签

相似分享

官网相关资源

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