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

游名科技: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
初始化程序如下参考:
: h/ }% o" o7 J1 g% x. }5 X9 |3 q  /* Initialize all configured peripherals */$ K1 f' c+ i4 Y* e3 e+ a. U! ]
  MX_GPIO_Init();
& E4 j% J* V  u; T' L7 V9 d9 z  MX_USART2_UART_Init();; ^" m0 L( c: Z) U
  MX_TIM1_Init();
- ]% o) I/ \8 v( W        STEPMOTOR_TIMx_Init();                /定时器输出初始化
+ x( S9 J  R( w; b  /* USER CODE BEGIN 2 */& L+ {) h4 n1 @  Q; y) g& W
        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能
5 e  u) c/ A6 E; X  /* USER CODE END 2 */. s0 _! d; f: ]6 T% E
  /* Infinite loop */1 r! K& Q2 v1 _4 }# X  H* J3 l
  /* USER CODE BEGIN WHILE */6 U' D4 s  h: K( p  c
  while (1)- @% a% S+ H5 {% c9 q8 t# C+ x5 v
  {
1 F! E- L! S  S7 ]; `4 L8 B    /* USER CODE END WHILE */
* E1 W* ]  @( f" J2 f- C  C                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)# }- G2 @( w9 v% t5 H
                LedOnOff();                                //LED闪烁处理" l% p5 j) N# n: \" Y  K! ^" ?
                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
7 W5 ^# `! S' W, Z* {7 ^; w' \1 q                LedOnOff();                                //LED闪烁处理
% p6 [  K9 p% ?7 T    /* USER CODE BEGIN 3 */3 t+ Z% S9 W/ i5 C% m' K. l; j$ b
  }
: u0 I: y9 x2 J+ D
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)
% J' t$ k+ j( z: M/**
9 z  H/ Q# e$ [% S  * 函数功能: 相对位置运动:运动给定的步数% H2 d: }5 x( ?/ z- ?& L3 T
  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).8 F; R+ G7 `9 j& a
              accel  加速度,实际值为accel*0.1*rad/sec^2+ O8 `& ]' R; T: G
              decel  减速度,实际值为decel*0.1*rad/sec^22 W" x, M0 `& X. Y
              speed  最大速度,实际值为speed*0.1*rad/sec
( O5 d) |& @2 |+ J7 [4 }* [  * 返 回 值: 无
5 @& J0 A1 f$ M6 Y4 L  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
" L6 G: E5 {9 `, J- J% J  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且
1 R7 N3 J5 a/ L+ C  *           速度很慢,那还没达到最大速度就要开始减速/ k/ \( g9 @3 R7 L/ C
  */- d3 j% f$ @1 S. I* x
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)
0 y4 T; V. K$ |$ R* ^8 `{  
2 O9 I# K( t2 f5 r. @  __IO uint16_t tim_count;
! I: Z6 z2 \% u! ~  // 达到最大速度时的步数& ~% @+ y& e( `, H1 \5 F& u
  __IO uint32_t max_s_lim;
( {+ i- w0 p4 r0 m* Y$ p  y  // 必须要开始减速的步数(如果加速没有达到最大速度)
' g; c8 z5 x! X4 Q! x  __IO uint32_t accel_lim;1 S- `9 P- U  J
, {( w3 G& s7 L2 x9 P) {8 ~
  if(step < 0) // 步数为负数% G! X' G( x9 H3 L0 R2 k7 ?
  {) F( Q4 @& l: O6 C1 j
    srd.dir = CCW; // 逆时针方向旋转
* W( E7 r: `5 v# T0 x3 Z    STEPMOTOR_DIR_REVERSAL();8 s6 S/ j' q  q$ Q  ?
    step =-step;   // 获取步数绝对值. e' M$ ^" _! n5 ~' ]' f  C. ~4 \2 \
  }
0 r* X7 b3 h( P( V9 Y/ O; s  else3 U5 }0 U  ~. r& C
  {/ L! M% t: G4 o2 M
    srd.dir = CW; // 顺时针方向旋转
% M* L* ]: T" _: L8 e8 b1 @$ n    STEPMOTOR_DIR_FORWARD();! r6 |: S! f8 b8 X
  }  ?: h! Q/ i& C4 }/ `) S7 ?0 W5 r
  - i$ N. @. D2 _3 }: ^
  if(step == 1)    // 步数为1
3 }2 E( L! |, h  {
: \+ I8 H" K, l/ B    srd.accel_count = -1;   // 只移动一步" O- `- g# K/ q) L
    srd.run_state = DECEL;  // 减速状态.) v5 ~6 ~* k# r* w6 l) J
    srd.step_delay = 1000;        // 短延时       
- T) x& W2 d% D, l* y  }6 x4 r  b& x% m3 n" S  m
  else if(step != 0)  // 如果目标运动步数不为0+ c$ D6 b8 S0 [! L
  {
/ O2 g: X/ |; q    // 我们的驱动器用户手册有详细的计算及推导过程5 u8 N* `, {" Y% U( }8 Y4 j
" R0 t5 Y; v  L4 |+ f1 i# ]# v
    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。. d2 L3 h2 r; _; J! E0 a/ C4 a
    // min_delay = (alpha / tt)/ w
/ e+ q5 e( n+ A    srd.min_delay = (int32_t)(A_T_x10/speed);
3 I% H9 G5 G0 U5 \6 i
* v+ F0 o/ U8 U2 b, V/ }: @3 |    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^21 X* M9 m! S5 l; A8 }+ a* \# }' Y
    // step_delay = 1/tt * sqrt(2*alpha/accel)9 [' R9 n9 H- v# e/ q* d
    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100: ?( N+ E; D7 E+ [
    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);
( j/ M* o+ f% R4 ?+ ?2 D, f1 \* h* ]
    // 计算多少步之后达到最大速度的限制  `0 D1 s' t) f
    // max_s_lim = speed^2 / (2*alpha*accel)# r: R; w- t. t
    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));4 P- T0 h1 Y# b3 d; u
    // 如果达到最大速度小于0.5步,我们将四舍五入为06 n  h9 [% _' ?, t* }  Q$ a! ~
    // 但实际我们必须移动至少一步才能达到想要的速度
5 j4 F% X6 z0 i4 y& m$ p' \    if(max_s_lim == 0){% ~3 f% S$ V1 g7 b" q2 Z6 X
      max_s_lim = 1;
& K  Q+ C$ S# c; `! |    }# s: m7 n' p& w" g
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速8 e( R5 V4 Q+ F( g/ c
    // n1 = (n1+n2)decel / (accel + decel)
- ]  N1 u# `/ z    accel_lim = (uint32_t)(step*decel/(accel+decel));
% o4 O, p: x. W& }- k& G    // 我们必须加速至少1步才能才能开始减速.- w0 L# Q- O# `# P6 p- F4 p; c
    if(accel_lim == 0){# d  k( o1 h3 J# I! r( z2 `& q
      accel_lim = 1;# o$ l: M# h: x7 _0 h4 q
    }1 |, R0 s7 k. A9 o3 c& q$ x
( e$ F& Q' l! j0 r1 h0 u4 l
    // 使用限制条件我们可以计算出减速阶段步数
, `( H8 }) t  f8 D    if(accel_lim <= max_s_lim){
) c1 f8 ?' A% h& [) Q      srd.decel_val = accel_lim - step;# a: U% w0 Y6 C1 Y: g- e
    }2 ~9 |# s4 S6 N) ~
    else{
6 j( H# z2 n% M- M- G3 Z& _5 k      srd.decel_val = -(max_s_lim*accel/decel);
) Y7 V& d% w4 l$ q) [) ~  ~    }
' z, D; n' G% o7 _, y- ]& i9 @    // 当只剩下一步我们必须减速5 ~4 l) S7 u3 J6 u3 K+ }
    if(srd.decel_val == 0){* n" y' u0 H: H' T1 k8 r
      srd.decel_val = -1;5 `) ?& c5 \  D# ^9 @: @
    }- C" c, |3 h' r( v- |
" Q1 C; B4 ]$ w: o
    // 计算开始减速时的步数
: L  J2 _# _' E. h7 v    srd.decel_start = step + srd.decel_val;
0 m3 U; s& e$ S% A6 W2 O4 ^$ Q' @" }- h5 u7 l  U3 |
    // 如果最大速度很慢,我们就不需要进行加速运动% W: ?* {2 L1 H1 o
    if(srd.step_delay <= srd.min_delay){7 c, Q1 Y5 O3 r9 b
      srd.step_delay = srd.min_delay;# Z8 x' a- H" q) m
      srd.run_state = RUN;: d/ C; Y4 U5 f2 `! R
    }& e' P. m- V' {0 X
    else{
& M! P, c6 D8 L7 B4 M      srd.run_state = ACCEL;: T9 U$ W* E# j6 h/ x4 i
    }   
9 \7 v( @7 d9 P) G4 x    // 复位加速度计数值* g2 F; m9 G, U$ p
    srd.accel_count = 0;
" ]; N. b) P0 y: z! Y  }# j( `, V/ `! T& v2 }; J0 ~6 t
  MotionStatus = 1; // 电机为运动状态
4 u% {1 [2 J" A& d  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
0 Y5 e7 |9 @+ J) F/ ^$ c- X  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值3 Y: y! f* [# a# L1 l* a+ K9 k
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道
7 ~( p: j0 X6 r& ^  STEPMOTOR_OUTPUT_ENABLE();5 x0 _5 x' `% T: L* u
}0 Q, a! C/ s% a2 Q9 Q) v+ m6 w
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考, m, |) D/ E( m& q2 K
/**
0 X3 U3 f/ _6 o1 t$ F7 _  * 函数功能: 定时器中断服务函数
; }6 F- z6 Q# m. i" N0 S2 L  * 输入参数: 无8 [9 z' q; q/ I) U  d, n7 E
  * 返 回 值: 无7 b9 ^* Z5 ]# ?! Y! w* ?
  * 说    明: 实现加减速过程
  |) [+ S0 F7 f7 K9 |7 |" `% T/ T  */
: p9 w9 `+ _8 U2 evoid STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
: K5 v5 `9 f/ Z% a+ W+ S{ & w- c( g; w' S, W* R2 L
  __IO uint16_t tim_count=0;
5 i* t# h6 o. D2 ]) q% E4 \$ ^7 v  // 保存新(下)一个延时周期/ O' x" m( c; ^7 B9 R
  uint16_t new_step_delay=0;
1 f2 R5 T4 U/ a  // 加速过程中最后一次延时(脉冲周期).  M: C) I* K) B. k9 z
  __IO static uint16_t last_accel_delay=0;
" @# {9 k8 `' k  // 总移动步数计数器
) w3 M& X) r' |$ @. ?; A  __IO static uint32_t step_count = 0;
8 T) j3 Q2 e) B& Z6 c  Y  // 记录new_step_delay中的余数,提高下一步计算的精度
% ]& Z1 P* d' T, ~* ?% m5 h  __IO static int32_t rest = 0;
0 f9 Z% t; y1 W! |  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲( a9 v/ @) K. A2 ]
  __IO static uint8_t i=0;
3 v) r" i4 A8 C0 w  
: V/ g* S& Q! X: [  W  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)# V2 P! U4 R' n5 C; u/ S* \
  {
) t, s" {0 I* N+ |" x- O( V# j4 `    // 清楚定时器中断# A, I2 k% R/ e. ], R0 d
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);1 S0 u9 Y/ e' B# s8 b) j  z2 R
    & @0 h' r5 n) y
    // 设置比较值
: h7 r/ o/ ]0 l: J    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
" s) f; r6 _3 C    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);
! r. m. Y6 C) A& v) B0 n
6 b% x6 h' {# D1 X9 w5 R    i++;     // 定时器中断次数计数值2 P' h# X2 f! N$ d  ?
    if(i==2) // 2次,说明已经输出一个完整脉冲7 ^5 v6 k- Q- H
    {
" H$ K; X/ H3 D! P+ [' v      i=0;   // 清零定时器中断次数计数值
1 U8 X$ j0 ]: ]3 t% a1 `      switch(srd.run_state) // 加减速曲线阶段; i# L5 L4 R  a$ l# J
      {- S3 n  x7 D3 ?; D
        case STOP:2 Z" [, S7 q! G/ K8 M6 D
          step_count = 0;  // 清零步数计数器
" t4 j+ h( e) W0 P3 h2 _. F          rest = 0;        // 清零余值
% W1 e# B* z) [( h, g8 B. V          // 关闭通道
/ x/ b' r: S. Q" G* l6 s7 o          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        - ]+ x, F$ ~9 p
          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);
2 r, U1 ~" w  d5 t1 r1 v( E7 A8 [          STEPMOTOR_OUTPUT_DISABLE();! t1 r8 l4 C# X+ H
          MotionStatus = 0;  //  电机为停止状态     % e1 d6 n$ L0 Z! G
          break;
9 J- ^/ f+ ^/ K7 o8 q1 e( G$ D6 H2 P) V3 r8 p
        case ACCEL:
9 Y# A4 }& Y9 ^          step_count++;      // 步数加15 N0 S; z! G0 O( z$ T
          if(srd.dir==CW)  D$ h& a& m! I# i7 r& [
          {                  & b, Q" k. ]7 n2 t) V2 j
            step_position++; // 绝对位置加1* W; k5 N5 ]" s) H- [- H6 D- o. q* W
          }% C; d7 f. I4 n! f2 N  O5 ~0 h$ i
          else
5 Q8 N% I- E9 k, U& p          {
. V" K7 y# f: G3 z- {            step_position--; // 绝对位置减1
6 ^  Q! g# c6 L: y* g' R9 ]& a          }
% h! W2 s- j& e( ?9 j# U          srd.accel_count++; // 加速计数值加12 E+ h1 C" f3 T6 |3 |: j9 |4 A
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)
" i, \) F3 G* N$ a9 _          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
4 N# z1 Y7 U" T0 ?$ G0 M! Y+ r          if(step_count >= srd.decel_start)// 检查是够应该开始减速
2 |- s, n4 w; O          {
# {, m% Y9 I% P6 T5 _6 [            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值  j6 e2 L2 e( _/ A6 ^" U
            srd.run_state = DECEL;           // 下个脉冲进入减速阶段
& E* B, {( I. e: o2 W' w          }
) ]7 ?5 \2 l: {1 X7 a" [% @          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
- U) X* T; i7 ?3 s: o7 o. X          {  M. ]3 D' f: e+ X
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期): I0 V1 ^2 N) v5 G
            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)6 X5 N1 X7 ]5 y7 G7 G
            rest = 0;                          // 清零余值
, \! y; h# `7 h( c$ r2 x4 u. Q5 R            srd.run_state = RUN;               // 设置为匀速运行状态$ i- ]5 T5 a3 w  q1 v6 R
          }
6 X. u# Y& P7 w* P( m4 \          break;. P7 v6 L$ ^4 a/ L
' V' S; y& f3 g
        case RUN:2 b- U( Y3 S5 O2 `
          step_count++;  // 步数加1
5 V( S' g) f; N          if(srd.dir==CW)
; `- n! ?; M5 J/ N8 C3 r          {                  8 k$ ~" N5 C: Z8 j
            step_position++; // 绝对位置加1+ H( D+ V% C$ S& o$ [) n- w
          }# O" J( R: U$ \, Z% y
          else
- O; h' N7 s$ }- C          {
7 @$ I5 ]- x6 o  U            step_position--; // 绝对位置减1
6 d# C) d3 J; R2 `% P7 K4 N: s% X          }
" C8 J! p) R: l4 w5 o          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)
5 p. _0 a* d6 \          if(step_count >= srd.decel_start)   // 需要开始减速. G, q4 o% |9 R& ^) M
          {
6 Q4 J0 z5 |1 `) u! v9 [0 z4 Q            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值
6 Q5 D' E6 {9 J2 y/ }. I) a+ C            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)
+ G9 z; x( |" \1 [            srd.run_state = DECEL;            // 状态改变为减速) k+ F! T, Z% P6 W
          }
5 X% z) t9 d0 [) D          break;, ?6 b6 A7 }: l: Z
1 o; b3 {; q9 B0 K7 P! E. C9 g5 @2 e
        case DECEL:
! K/ x& B9 S$ @          step_count++;  // 步数加14 C2 Y8 B" d% c6 D) [* Y
          if(srd.dir==CW)1 E/ _- l9 D+ k
          {                 
! [0 x$ \( c) u+ k0 p            step_position++; // 绝对位置加1# `2 w8 T+ b+ o! f3 l% U
          }2 t! g6 X  P* f: q
          else2 D( q' I, k% ?! F
          {
7 h3 C9 |) N  z2 R* b6 S: J0 ]            step_position--; // 绝对位置减1" L/ q! c5 ^( t6 A& q) T8 M! l
          }# ]4 ]/ R# N! j
          srd.accel_count++;' T/ X/ a% I9 B, ?: o
          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)' x5 }# V6 I6 \% c( P5 I
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
6 j* D( \( T: I% ~+ |4 x$ a         
) [: N, D8 z: l, k# D8 R1 n          //检查是否为最后一步
# L5 l4 C8 H1 \5 |& [" V  Q0 j          if(srd.accel_count >= 0)9 x. z0 \/ F& H- A& S+ F8 ^0 o
          {0 y( D* C  t' ~
            srd.run_state = STOP;+ M( k+ B, _- x9 F) L
          }4 y/ O8 E4 q7 n
          break;
6 H9 V- t. z: ]3 D8 e      }      ! B: e+ C; {* W4 O3 [: p6 S
      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值0 H8 j6 }, |$ S1 |. q* @
    }
) c6 a' G4 l0 o& |  e  }" ~8 x! A1 Q6 G6 K/ a
}- ~# R9 t; c1 ^0 ~. K  R. F
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明) |3 q5 [) F$ q6 @6 }
    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!
6 ]6 m- \/ a+ p" M" X& |- H" Y+ R+ v0 I2 ^+ U  d  [/ T0 M
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。; A- p$ K# K: p: ]% }( R

+ s5 M7 {8 p  K# C0 H7 R: M技术群:171897584
. U/ S1 v9 {3 q" w- G% D) }+ J# ~. g公众号:游名开源
2 m0 y. q+ f: d6 C5 B' |' U
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. C1 K4 p( F- t3 E; L& O
电机相对运动的函数和中断函数看着像硬石开发板里面的代码。

& @( j0 |. L5 z3 \4 B3 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 手机版