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

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

[复制链接]
mmuuss586 发布时间:2020-4-29 12:18
阅读主题, 点击返回1楼
1 收藏 2 评论71 发布时间:2020-4-29 12:18
71个回答
mmuuss586 回答时间:2020-4-29 12:53:36
初始化程序如下参考:, O, f/ J& M! Q$ {, o
  /* Initialize all configured peripherals */5 D+ O& B7 o, V' }
  MX_GPIO_Init();
; o( w" P9 X* J' r# o& F  MX_USART2_UART_Init();1 H+ d# x- x& x" @" K) K
  MX_TIM1_Init();
% F' w5 r* Y* X' {) o1 f; `# N) y        STEPMOTOR_TIMx_Init();                /定时器输出初始化, ^: {, `5 V7 d  y; h
  /* USER CODE BEGIN 2 */
" E- e' x0 U/ x$ }; ~7 J7 ^        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能$ F3 j6 t. u, K) j
  /* USER CODE END 2 */. T' b- g; v+ q" R9 T4 Y, M5 H* s
  /* Infinite loop */4 S) B5 A" A% r2 l! p- k
  /* USER CODE BEGIN WHILE */
# V3 M# g9 A! e% L# s  while (1)# D: U+ X# g$ d& L# i9 u* r5 o/ ^' i
  {
! x3 J/ G0 V8 z% C% B    /* USER CODE END WHILE */( Z0 h3 \# [+ k5 V7 J
                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
6 `, }: b2 O" Z- f0 n' M  J4 q                LedOnOff();                                //LED闪烁处理# v2 g; L( j- [
                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
/ L+ f& U; R# m7 [  n( X& i: a                LedOnOff();                                //LED闪烁处理, V8 H9 n; d6 m) P, O
    /* USER CODE BEGIN 3 */
0 v. [$ b' a; Y  }
' E( x9 {3 E8 {5 s* _) c" A+ s3 t
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)+ X. y: C9 m+ b  L7 d) B8 F3 K$ T
/**
! r& _, y1 e$ V7 A6 l! z  * 函数功能: 相对位置运动:运动给定的步数
$ X4 v7 D7 W; K/ P+ R) o; Z  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
3 M1 l9 j$ @" h6 H              accel  加速度,实际值为accel*0.1*rad/sec^2
6 g6 a9 h3 N2 @: x0 a              decel  减速度,实际值为decel*0.1*rad/sec^23 v+ s7 V' w  X+ [
              speed  最大速度,实际值为speed*0.1*rad/sec
) k, O0 i3 \3 p6 A  ]  T6 Z  * 返 回 值: 无
: c1 {  n( s* T  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
$ D0 U$ f+ }5 ^: i  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且/ h4 M) u0 }1 @6 R! l+ m" m& j
  *           速度很慢,那还没达到最大速度就要开始减速- b: B' k  A3 V7 G, g3 a
  */
+ z5 w0 d  T0 evoid STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)" g; J3 _9 v1 H
{  
2 F" k) O; H" D% l' j& M  D  __IO uint16_t tim_count;* k  d" l( T* \8 ]3 s
  // 达到最大速度时的步数
3 t5 _# ~8 ^7 ^5 _- b  __IO uint32_t max_s_lim;' f$ R$ g/ m0 X4 f7 h6 Y. G
  // 必须要开始减速的步数(如果加速没有达到最大速度)
: F+ ]$ z0 ]; Z1 P  __IO uint32_t accel_lim;
, }: v) D1 `7 I
6 c1 ^$ g; d6 N, X  {' I, n  if(step < 0) // 步数为负数1 N' a" W0 H" b) W9 B
  {" q& a, ]& G2 |: [, A2 N! A2 K
    srd.dir = CCW; // 逆时针方向旋转
. }9 r$ h1 y* @- B$ B3 e    STEPMOTOR_DIR_REVERSAL();
7 d# A; i) A. q6 r- W# a% q5 D# v    step =-step;   // 获取步数绝对值  U- D0 D# k( G
  }2 r% v# i8 {9 x* \
  else4 i- [1 e+ S3 Q& p
  {
7 e% _% A5 C5 [" u' D- M    srd.dir = CW; // 顺时针方向旋转
1 ]7 v$ T  b5 e    STEPMOTOR_DIR_FORWARD();+ B! B7 u" A) Y7 c5 N
  }- Z4 Q5 W- q/ z+ `- t
  9 g. x- R& T8 f; n2 |, Z; V2 X( ]
  if(step == 1)    // 步数为1
2 u, v  @% y( c1 Z) t  ]5 `  {& T# E7 \3 ~, c5 l; [4 \
    srd.accel_count = -1;   // 只移动一步
" ~) H4 n. ^* d  L    srd.run_state = DECEL;  // 减速状态.8 X; Q9 e. L  A
    srd.step_delay = 1000;        // 短延时        , K% Y- q; u& n, }: Q. Y
  }, Z0 \! N+ V% ]* {  s/ V8 b1 L* y
  else if(step != 0)  // 如果目标运动步数不为06 f% P! q6 H& h% b
  {
6 }3 V1 T) T; W  h/ i0 h0 T+ c7 d    // 我们的驱动器用户手册有详细的计算及推导过程
, R3 N) q9 }" n* }  V( |% L
2 j9 K' ^+ E9 _. v8 t+ m    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。( N$ {& D, q( I" d; w* c, i
    // min_delay = (alpha / tt)/ w% m; R3 r0 H' t
    srd.min_delay = (int32_t)(A_T_x10/speed);
# b  i  l+ {4 s+ F( t$ S: ^, L# E. A9 ?* {$ c
    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^24 Y/ G: |* N5 Y
    // step_delay = 1/tt * sqrt(2*alpha/accel): J! T5 {( K% H
    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100: I7 C' X4 W; b: P& _0 z0 A3 B
    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);- J% m/ Y5 E* o) v. Y
+ g5 E2 M4 x7 U# u# {; L
    // 计算多少步之后达到最大速度的限制5 g& ^: C3 @# e7 N5 p! S9 s
    // max_s_lim = speed^2 / (2*alpha*accel); ^$ g- x; M3 q5 H) }8 n8 D
    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));
- p& j0 Q  |: y5 W, j; u: @    // 如果达到最大速度小于0.5步,我们将四舍五入为0
' b! g9 c) A8 ^5 R    // 但实际我们必须移动至少一步才能达到想要的速度0 L/ I7 }" Q7 u# E
    if(max_s_lim == 0){8 U4 o& c8 z5 q! [7 Z5 Y& R
      max_s_lim = 1;
) o3 _& z+ v5 [1 q+ `+ M    }& O: V% [& L: e  y! {5 x. U
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速
4 y. f' A& f6 p) J9 p3 K: u4 ]" O    // n1 = (n1+n2)decel / (accel + decel)6 U/ E1 N7 g$ g1 F% b; R/ L$ z7 t
    accel_lim = (uint32_t)(step*decel/(accel+decel));
. \9 C" u# w- R5 Y) t/ Q7 b, }    // 我们必须加速至少1步才能才能开始减速.: `, V- q2 b3 A9 Y# q  s3 g4 |
    if(accel_lim == 0){
" u/ Z( p% R1 i& ^+ Z      accel_lim = 1;% ?" X6 d# @) ~, `0 ?: ~8 d5 b9 v! d
    }. h& m" D# K# A9 f. L
7 w0 C# x9 D4 E  @# A. i
    // 使用限制条件我们可以计算出减速阶段步数" K' z  I6 y! z; X# M& s
    if(accel_lim <= max_s_lim){
2 o) K% e" q! A. Q( Q" G- q" \      srd.decel_val = accel_lim - step;
; Q7 G  `% W$ V& E( K9 c0 |. W7 i    }
, M) v0 w# O  `& V    else{
, Y* U; v  o# N/ s& `# p: v      srd.decel_val = -(max_s_lim*accel/decel);" M0 s6 Z1 Q: r! D
    }" x2 }- }- L' b8 b" n
    // 当只剩下一步我们必须减速
; @% d/ d7 q) |1 R1 |    if(srd.decel_val == 0){! U% `4 t, w3 ~. E4 Z
      srd.decel_val = -1;
$ V) D! a# g1 t2 n# r    }! M2 ]0 h4 y8 o- w. L+ P" |

; E% K# z% |' p! r. w    // 计算开始减速时的步数3 r/ Q$ y) y0 n7 B5 E
    srd.decel_start = step + srd.decel_val;- k6 `/ r, }( Y7 s6 @" y  H

) ?4 M2 ~( s9 Q' y) {: f    // 如果最大速度很慢,我们就不需要进行加速运动
. I; u$ B3 n6 L# I    if(srd.step_delay <= srd.min_delay){
+ h/ Z( i( u/ Y/ @8 y5 x      srd.step_delay = srd.min_delay;
; v/ }& m+ _, ~+ n$ ^" s6 t  L* e      srd.run_state = RUN;  R) o: T' Q. C" S) {6 s- o4 i1 u
    }1 P" o' W" X/ e- S4 R& i
    else{0 p5 v6 {2 P# H- v
      srd.run_state = ACCEL;6 i0 v7 E6 t6 i: y: e7 p& ]
    }    2 N8 Q5 v/ e: H2 u
    // 复位加速度计数值
* z+ U: \/ K- }7 p# ?9 v    srd.accel_count = 0;
) U2 I; U9 }0 ~3 }  }
$ t9 x7 O0 f; s$ T- K/ h  MotionStatus = 1; // 电机为运动状态1 o0 D' O# h! d( K. }! l
  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);. u$ q8 c& l2 s) d, V' A
  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值: Z: i7 s8 N% D2 G  S. ]$ B! S" _: ?
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道 " p  T2 M; q, w/ H
  STEPMOTOR_OUTPUT_ENABLE();
0 ?, X, W" j. ?5 \& `}
/ T& M4 C; c0 z) G4 j( \
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考
9 z7 _8 P# X' l/**% u; W# s1 |. s; X8 G
  * 函数功能: 定时器中断服务函数
# D% N+ x2 G4 Z! t  * 输入参数: 无' ?3 j7 f% B; z+ A' a1 k$ t" {2 Q
  * 返 回 值: 无1 V* }! a- E, W  I, m
  * 说    明: 实现加减速过程+ C  W1 E% I$ d, K# P
  */0 G; z# i  c: ^+ g; O
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理& l6 F% S+ q- C
{
  A+ p& i0 R' N& E  __IO uint16_t tim_count=0;* @$ R7 y$ T3 @2 N5 Y
  // 保存新(下)一个延时周期3 s: L6 v% g+ z& {9 y8 ?) X3 D" c( E
  uint16_t new_step_delay=0;
: T  L% q6 P* C& {  // 加速过程中最后一次延时(脉冲周期)., Z4 b; H& Q. I" s! o1 J
  __IO static uint16_t last_accel_delay=0;1 ^0 c. U1 ^7 u) j' @/ C7 f! ]7 O
  // 总移动步数计数器
; e; y4 d5 z5 j& s5 C  __IO static uint32_t step_count = 0;
3 w' U& d  Y/ V" U, a- o  // 记录new_step_delay中的余数,提高下一步计算的精度
5 d7 e$ B3 H! z5 d! X  __IO static int32_t rest = 0;
- v. ]  M/ s6 g% t3 P& }  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲
% E& u$ g5 A- r! F/ W  __IO static uint8_t i=0;0 y$ \% X6 i4 W6 s
  5 T4 W* H5 r2 k% K
  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
" A6 Y* d, {5 B6 f, `0 ?; U( e* X  {4 n4 s7 ~3 ~0 W4 x
    // 清楚定时器中断& K+ l) X* m" F5 J! g% Y
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);
- Z7 t* L, Q. x1 E1 x) }   
* A7 w1 d6 h$ }; j! B' X- H0 u: h, ^    // 设置比较值
. ^% c; ?+ h7 T( Y' z8 H. M    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
4 w! N" A3 b; \: Y% g    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
3 Z+ n1 i& s- e& |; N! ~. _* g% ]2 ^7 R6 F8 H9 G* Z
    i++;     // 定时器中断次数计数值
4 T% J! x  C) o% i. E    if(i==2) // 2次,说明已经输出一个完整脉冲
2 i8 n% ]  w' }" o9 V8 J7 ^    {
6 R( C; ]" ~7 V7 Z+ a$ c      i=0;   // 清零定时器中断次数计数值
, ~3 l" L, b! W) U/ k      switch(srd.run_state) // 加减速曲线阶段: l# _7 v4 S8 C
      {7 `( i- x/ U7 C- F% M1 ~
        case STOP:1 q' ^" I  M$ o# Y
          step_count = 0;  // 清零步数计数器
1 ^; i0 r% p; ~1 K          rest = 0;        // 清零余值
& ^: {/ M2 K( D! ^          // 关闭通道7 n- n; A+ w( p% _+ B# \
          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        
9 H2 x: c+ b" R0 ?1 d+ K: C: Q  `          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);% p; Z0 k6 L3 A2 l' x
          STEPMOTOR_OUTPUT_DISABLE();
1 D/ }. ^/ r; N. L# m( ?          MotionStatus = 0;  //  电机为停止状态     % S0 M% `: m* h. `5 e4 Q
          break;
2 C1 p$ Y: a0 P# P+ a  W! a6 |- }3 v) M: \/ s, U0 }/ _& e* i' r6 E
        case ACCEL:2 c( t% W4 h& ]/ V
          step_count++;      // 步数加14 |6 o* z8 }2 g. U: E; ^
          if(srd.dir==CW)
, `3 ]+ v/ D% f# q" ^! [; V1 ^          {                  7 [% H- ^6 V* Q& D
            step_position++; // 绝对位置加1* T( n1 B/ I* d. z, }: T/ d4 w
          }7 L' D" d+ q; A2 H
          else2 U7 j% R) r% l+ v9 v
          {
6 B& f! P5 U. e. c2 Y* v+ s            step_position--; // 绝对位置减1; Q* o: T! l, H* y; Q) }5 n+ ~
          }
/ N1 c4 X3 \- G* k          srd.accel_count++; // 加速计数值加1. i8 c2 |' j" I7 R; o1 G+ E
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)% ^' T- D) Q8 X
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
" _4 ~1 v( V1 D7 ]5 Z          if(step_count >= srd.decel_start)// 检查是够应该开始减速$ M% W0 G+ }* D
          {
: c1 }  F6 H; }3 y, V: g            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值2 P4 W4 u1 @) s- i; }0 U
            srd.run_state = DECEL;           // 下个脉冲进入减速阶段
$ Y1 V& M: C2 _1 |( E3 ~          }. l) a% [/ m) j$ N0 n
          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
" [3 t' V  n9 K8 O          {( I- i$ t: L% ~3 s: E5 g; [( S8 l
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)
) _# F* r! `1 I& g# Y( E, }            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)
1 H' n( q2 ~) V1 N3 @            rest = 0;                          // 清零余值7 `% ?1 i" ?6 k  _6 W
            srd.run_state = RUN;               // 设置为匀速运行状态, E0 u; E9 W* T+ e! C5 R: k
          }
; g# _! M2 p3 Q( Y% b/ g+ K7 z+ q          break;
4 q2 h' ?( c+ L- A; c8 C/ L: R7 t9 {
        case RUN:6 W, Q. p' W; u) y8 s
          step_count++;  // 步数加1
5 S: |% \9 ]% K+ r# m, D          if(srd.dir==CW)
$ J4 ?2 U& h: q+ F          {                 
3 B# |, p0 j- M; S  y. E            step_position++; // 绝对位置加1" E- ?/ ?. C3 S6 g1 O% H
          }
1 U# h# N  R( k/ }; q) _. i: w          else
( w& _8 E6 ?6 L$ l          {. \+ l1 D/ J/ }: n6 ~. O
            step_position--; // 绝对位置减1% X* _! E1 J1 s3 Q6 a
          }
( s4 d+ X% o, I/ o, o          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)
6 C" j& U8 A# i& O/ w          if(step_count >= srd.decel_start)   // 需要开始减速
0 ~# A4 k4 K# b9 A          {
" s, L$ s) Z7 A( C2 c            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值0 F5 x8 ^8 r2 p6 s2 G+ v
            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)
3 E* T2 r; y9 N7 Q+ t            srd.run_state = DECEL;            // 状态改变为减速# V. A7 O( \; ?  V/ I) d: m( W7 G
          }
$ m7 D# ?" i/ A/ J. M# ^          break;
. k* u, b* [3 e% n
% R9 w/ @) I2 |7 a% y" x$ `        case DECEL:2 x2 y# u7 W9 K/ o0 U, p' O' }
          step_count++;  // 步数加1
* ~6 ~5 B& j+ [5 S, C& }          if(srd.dir==CW)
7 ?4 |7 K6 ]$ M" k+ |+ H* R4 I6 c          {                 
/ d. X. a- r5 v  Z: W- O            step_position++; // 绝对位置加1
" W" g8 i3 u2 v) k5 x          }! ?. ^6 t: k  N  e3 V' y6 T; ]
          else
6 ?0 ^4 {# f1 e2 P: F2 D          {! B4 E+ [+ v- P4 h; b3 F) ^+ X  W
            step_position--; // 绝对位置减1! d5 I9 G8 M, g; ~' A9 E2 R" c. e
          }
9 e$ a& j. p! x, @+ H  Y          srd.accel_count++;! H# u4 y4 ?5 ^3 q( J" g# A) g* o
          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
! Z$ d+ D8 }- N2 U- L5 f! m' ~4 o" ^          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差& n: y4 b4 k9 U# f
          : X1 P. _5 r% Z  C
          //检查是否为最后一步
' A8 f, ~( `" G( [8 S          if(srd.accel_count >= 0)
& a# x  e& I: i6 A- v/ f          {
: h% B; ^9 ^+ C* O% |) |3 U! M7 C            srd.run_state = STOP;, T) y& J# ^8 H. W
          }
( i1 n5 z: O5 q0 M7 J          break;4 h' H# g$ K: T1 s3 U* V$ k
      }        B" U! F7 s  B) \. }
      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
3 v% @' e3 `$ B+ u9 p) c6 L3 N    }
5 A8 E1 u6 A4 `* r- x  }
' R) N/ Q8 s0 r5 r2 I3 J& Z7 E& b+ Q}
! n8 b0 j) M; \0 ]$ \! k- j7 x  l
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明) `' c7 i: U  H. ?+ p
    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!+ f9 z2 Z- }$ r  Z

. a0 W# y. A3 L1 e* N! Y8 M
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。
8 M4 m/ N9 ], O; F: t, U
* P3 V0 \4 o; |5 ~* v6 ?; _% p技术群:171897584
2 k; |  e) c6 `# y9 L( H/ d3 G公众号:游名开源
% D2 b5 {; e3 [9 {) N2 H
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:224 f. M% o# ?1 I
电机相对运动的函数和中断函数看着像硬石开发板里面的代码。

. O: A" R: {, G# H6 _: X2 D是的,参考他们的,有说明:写着参考硬石的
mmuuss586 回答时间:2020-5-16 20:42:48
mmuuss586 回答时间:2020-5-20 12:07:25
mmuuss586 回答时间:2020-5-21 16:26:39
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版