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

游名科技: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
初始化程序如下参考:4 I. f; u8 v9 k1 P3 |+ z% z5 @
  /* Initialize all configured peripherals */
" A/ c7 n$ o+ Q0 w% E. L  MX_GPIO_Init();
! T, d% u3 n7 u6 R  MX_USART2_UART_Init();
0 i3 ]- ~! w$ e4 Q) S, ~  MX_TIM1_Init();
, p. |. I& \+ \/ Q/ u        STEPMOTOR_TIMx_Init();                /定时器输出初始化
5 r& E, m% O. U; S1 a; N  /* USER CODE BEGIN 2 */; f4 M9 m- H2 {2 j0 V) J
        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能; `0 d5 l8 F7 k( a0 D& F$ y. t
  /* USER CODE END 2 */* w- q4 v& u# x! s4 C, C/ V
  /* Infinite loop */  Z- S$ U- c3 s. f+ f) H3 v
  /* USER CODE BEGIN WHILE */
. ]/ J+ s, ?7 x' K# W  while (1)
/ v+ `" J5 p0 ?* D5 x6 i+ q/ _  {
  r5 `) _  y$ O5 H3 r    /* USER CODE END WHILE */# m  n2 W/ k5 R1 J1 a. M
                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)4 i& j0 P) ~8 U
                LedOnOff();                                //LED闪烁处理6 A, N. E; j  m  M$ N8 T# i
                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
. }: O: a4 |, _! @' z. B: D4 n                LedOnOff();                                //LED闪烁处理+ _/ }* O, k& l4 E/ g. {  a
    /* USER CODE BEGIN 3 */
5 |- H# ?4 F; A( f  }
5 U5 I' i2 Y) O5 ?
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)( ~- O4 u# Z3 o! ^$ f
/**
% y8 ^6 J3 q+ y8 D1 y8 o  * 函数功能: 相对位置运动:运动给定的步数
8 B% `/ J. ]. I8 L' U; \0 k: J  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
6 X; ~) @1 }1 [3 ~              accel  加速度,实际值为accel*0.1*rad/sec^2* t4 _4 J* t. Z- ?. h, |- b. g1 ^
              decel  减速度,实际值为decel*0.1*rad/sec^29 U& T( T3 n; z  ]% s. q8 }
              speed  最大速度,实际值为speed*0.1*rad/sec
3 j0 }' @' t: L; l0 _( v! c  * 返 回 值: 无/ @. }6 o) I# c; E; r
  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始
( l. x5 p: T! i! t  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且
/ t; H% ^% c1 b  ?3 k  *           速度很慢,那还没达到最大速度就要开始减速
, K. x+ D5 n2 x0 {, s9 J8 Z9 f  */
% ~: N8 c3 S" }0 |$ X( tvoid STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)* T/ x3 C( ~! E& a$ e4 w3 r8 h3 X. }
{  
! `, z# _% w. \1 x3 i' F  __IO uint16_t tim_count;
' m3 {: I- v2 Z4 p3 b# U  // 达到最大速度时的步数$ x7 R/ X" F8 L3 H! B7 `5 I
  __IO uint32_t max_s_lim;9 ?; t7 P3 B  p0 M
  // 必须要开始减速的步数(如果加速没有达到最大速度)7 L7 B5 _$ ]4 z" R" Y! b
  __IO uint32_t accel_lim;
5 F" z. h. j( Q2 I# s) @- f
2 [- O- n7 Y5 I6 j  if(step < 0) // 步数为负数% G/ p, n, ?& ]8 P' s0 f3 O
  {
' q) Q3 L" A2 ~4 x$ m, T( D    srd.dir = CCW; // 逆时针方向旋转
; S& T1 ?3 t% b% S8 o    STEPMOTOR_DIR_REVERSAL();
6 N1 h! V9 N, v' U6 J    step =-step;   // 获取步数绝对值
$ w* D" b! J9 w* q0 I" s  }
+ T, r$ |# \/ m8 t  else
0 E& i. `( g) c4 W8 v; R7 \  {+ e" ]" @4 x4 G3 z
    srd.dir = CW; // 顺时针方向旋转
! k6 U4 V+ D0 l( A3 ]    STEPMOTOR_DIR_FORWARD();/ S  n7 B" ]( f6 n
  }
) X4 U; v" u% r/ i/ d9 p  0 Q  n6 q. }+ I; E
  if(step == 1)    // 步数为19 l2 Z9 _- F8 \5 }
  {: d& y5 Q9 t- A& @9 u6 o
    srd.accel_count = -1;   // 只移动一步
# z) ~. D! h$ s8 n    srd.run_state = DECEL;  // 减速状态.( I6 d% Y, L" t% y3 Q
    srd.step_delay = 1000;        // 短延时       
2 f6 i1 E$ C# ^& f2 A) E  }8 z* Z, X+ d% D3 x
  else if(step != 0)  // 如果目标运动步数不为0
- x: G) L8 M+ h5 Z3 {5 n  {5 M8 A0 ]/ H( O7 @0 X
    // 我们的驱动器用户手册有详细的计算及推导过程
3 c; W6 V$ I; r# h1 [- C4 ?2 ]
: U, ]# n9 D% k! n0 t    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。7 T& g# v8 ?/ V, i6 I
    // min_delay = (alpha / tt)/ w
& \% ?" m' q* Y. U# J# v* z- \    srd.min_delay = (int32_t)(A_T_x10/speed);) p+ `% }: |- r; f& e
8 m+ d& v. e1 f5 `8 R; P" ~
    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
( a- h' x% u& V! G    // step_delay = 1/tt * sqrt(2*alpha/accel)
9 M& p5 H! K# Q" c' I    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100
; M5 Q. A. Y, D    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);
+ o) O# k- ?( x  s" G7 @
  @4 k. v0 q% k4 P    // 计算多少步之后达到最大速度的限制
$ O) l0 e$ o0 ?4 j" G    // max_s_lim = speed^2 / (2*alpha*accel)
( n" N( e4 A, Q* z" g7 n    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));: m+ \- a: q! z& O
    // 如果达到最大速度小于0.5步,我们将四舍五入为06 h# K; Z) c  k$ y4 v
    // 但实际我们必须移动至少一步才能达到想要的速度  Y; y, W* ^' Z! R) m
    if(max_s_lim == 0){
8 ?; Y5 Y" M/ |) D. @/ Y! c$ X      max_s_lim = 1;8 }$ ]* d. F  O0 q1 U8 X$ G
    }) [2 M/ |) A" a( H7 ~2 G
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速; @; O% X  d, b$ \7 s
    // n1 = (n1+n2)decel / (accel + decel)
2 m# E- W( b0 x$ n    accel_lim = (uint32_t)(step*decel/(accel+decel));( ]  S$ {% F! M& P8 v
    // 我们必须加速至少1步才能才能开始减速.2 M3 t' E$ c( o4 P
    if(accel_lim == 0){1 Y, P0 U% P% o$ }1 r
      accel_lim = 1;9 v, z5 h3 I3 _- R2 s
    }  _# n1 H. l7 k! `! U" E& d" o
7 F" o) s% ~' Z$ U
    // 使用限制条件我们可以计算出减速阶段步数, b) v# d* J" D0 Y4 v3 x
    if(accel_lim <= max_s_lim){
* W' k; a7 O- R7 ]      srd.decel_val = accel_lim - step;/ M( e2 `$ F& [+ m
    }* |7 `( ], v6 k% v- O$ y% P
    else{
" O3 F7 h1 h! Z: \% K: R      srd.decel_val = -(max_s_lim*accel/decel);) R' K4 i1 N! {8 D2 M
    }1 [$ b, M6 @2 t' F# k/ J
    // 当只剩下一步我们必须减速2 C( D& X: E& w5 E
    if(srd.decel_val == 0){8 x% q  D  L/ u
      srd.decel_val = -1;  k* X+ u# S8 I1 f$ f2 K& T
    }+ F4 p  b7 }+ u4 c& y+ H7 [2 f1 A8 r

; O" k. u9 `; `3 R3 r/ W; B1 C    // 计算开始减速时的步数
( V3 c3 e$ N- I/ _    srd.decel_start = step + srd.decel_val;
# j$ ^+ y6 U6 x
7 A6 v8 A; @  Y+ Y6 a    // 如果最大速度很慢,我们就不需要进行加速运动7 e# d1 d! k' F$ E0 r6 F
    if(srd.step_delay <= srd.min_delay){, N3 o* [- D5 S+ T% |& n
      srd.step_delay = srd.min_delay;
9 W- o7 S% U! N2 M, a# Y" S/ b7 E) E( `$ x      srd.run_state = RUN;
8 Y' E3 Z" ?0 q+ o    }
3 _5 b6 G7 X7 h+ @) j! x& |    else{3 X! h& V: d& n1 U- k
      srd.run_state = ACCEL;, T% R$ `+ B8 `: w
    }    ) [! _( m7 S, f- _5 r2 K
    // 复位加速度计数值
8 Z! C0 y7 q) |  \: F    srd.accel_count = 0;
) J/ {" B! x! l  Y0 _6 b  }
- m3 n  C5 X) w% c* A  f' c  MotionStatus = 1; // 电机为运动状态. N$ G, o2 D, d& [2 e
  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);
3 E  K9 R+ X3 Y" v  ~; u' F4 {  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值  r( H5 r6 }2 G& w4 y! Y# I
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道 $ |0 @0 k% S1 c
  STEPMOTOR_OUTPUT_ENABLE();
8 G3 Z7 J0 U% U& z}
, Y/ N% k# N9 y5 l+ h) k3 T; u# M6 ^4 w
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考
" B: W; d% i1 ]" f/**
( g) R# g) D! C  * 函数功能: 定时器中断服务函数
" U/ k/ D1 ^6 [* ^. L  * 输入参数: 无
. H$ W0 O$ C/ d* c/ E  * 返 回 值: 无, |9 i3 S7 h( d+ v  u  R
  * 说    明: 实现加减速过程
# S8 i' \1 ]9 u3 U  */8 a' p4 K  h9 d  w6 F' A/ l! f& H% {
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理
; }! o* S9 d" Y" P' I' |{ * O. s# k; Q, m- c4 c/ k8 ~
  __IO uint16_t tim_count=0;
/ A! D2 z5 ]/ Q  // 保存新(下)一个延时周期, w2 u  k% r. w; r
  uint16_t new_step_delay=0;
2 v- d2 f5 R6 }! }! c; N  // 加速过程中最后一次延时(脉冲周期).9 [1 j1 Q* Y% y( w  l
  __IO static uint16_t last_accel_delay=0;$ y, }$ B3 r7 O, |/ m
  // 总移动步数计数器
# Q; O3 V+ G. F4 d5 I8 c- _  __IO static uint32_t step_count = 0;! Z: q9 R6 P- r' x- p" z
  // 记录new_step_delay中的余数,提高下一步计算的精度
; q  Y: V8 A( k9 R9 }  __IO static int32_t rest = 0;3 ~- K; A! _8 x) R
  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲! k" [# C9 z8 ^5 I9 `
  __IO static uint8_t i=0;
* |5 K1 Z5 @$ S0 T' E# {  * s( D3 {  _( c/ Z7 b
  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
6 X7 j, Y1 a$ n) m  {
7 o+ W" b6 @) @    // 清楚定时器中断) Y! q- d) Y& x; S( d
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);4 x" O) q! G& ~$ h
    7 c$ T% k4 B0 K* _' ~
    // 设置比较值4 q. |* x# F2 E& v' g' ^: S
    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);- V/ f; Y4 z+ n9 g
    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);6 o) X  @/ ~3 J" D

! W8 \1 K( h8 n: b: `    i++;     // 定时器中断次数计数值6 n; D2 s+ G# C! f
    if(i==2) // 2次,说明已经输出一个完整脉冲
" j/ Q  x5 j3 W, r    {
. I" W9 G4 w: }3 A' l- q      i=0;   // 清零定时器中断次数计数值
. N$ s8 O* z3 j7 M: ~4 M$ U      switch(srd.run_state) // 加减速曲线阶段: h$ N, t. I" }
      {
( {1 q6 o% [& P& e6 g* h( M, f        case STOP:1 \0 Q& [7 {5 ]# u$ j6 [5 @
          step_count = 0;  // 清零步数计数器
( M/ P$ ]; l' v5 c" }0 k% P5 P          rest = 0;        // 清零余值* x2 \" ?6 v  d* e. G9 r( q
          // 关闭通道
$ s" M9 x% N2 e0 N1 c          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        
& {" C/ x( o/ x* ]3 n+ P1 o          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);& q. d- |6 G! L) R& \4 }3 X- d
          STEPMOTOR_OUTPUT_DISABLE();
2 X2 f+ v8 T& b7 D  K! Q4 S- [          MotionStatus = 0;  //  电机为停止状态     7 i0 K5 P' `9 P
          break;, P4 y) c" Q- z4 Z) B' r5 }; }2 D' e: J
1 R& U  _1 ]! b: ]5 P
        case ACCEL:
+ b! @4 W% b$ }: Q          step_count++;      // 步数加1' D( ^! P  U" h+ v2 T
          if(srd.dir==CW); }' }2 c" m& W! V/ ]1 a1 H* N: d
          {                 
# A9 p3 G) ~: E. _$ I+ O+ l! a            step_position++; // 绝对位置加1
/ I9 A& I% c. I; O+ `: y& i7 b$ ?/ u          }
8 }' _7 I" @9 K4 Q$ C          else7 Q5 o6 H" `3 f8 R% g
          {" k. v6 q, M4 m$ r0 S
            step_position--; // 绝对位置减1
5 z& K2 q# D' r6 j6 ~( i$ [( x          }
1 a" `* ]0 R- [# L2 r4 Z9 V- T* }* \          srd.accel_count++; // 加速计数值加17 ^8 N4 X4 l+ C$ c) a% P) Q$ @+ C/ o0 {
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔)5 Y9 V: e7 _0 x7 i, U1 K* J
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
* c, i& w7 Q, y- T          if(step_count >= srd.decel_start)// 检查是够应该开始减速
6 n( O" g' U2 N2 I4 H/ g( V5 I6 G- Y          {, i8 x( \1 \. R; O# j  _  [( A% Y4 _
            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值  G8 S8 h5 F* H' }9 `5 u' o
            srd.run_state = DECEL;           // 下个脉冲进入减速阶段8 u; M8 B- R$ n' F4 N% f5 O
          }
1 u! D) p: T* H  q- m7 r  U5 I          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
9 c& |7 ^' }" m0 w/ p          {
% i8 j! ?7 R& z; V1 j+ l' O: s            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)
  C  E: O9 q0 r+ M, S4 V            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)
( P* T* K; X7 w6 B5 }( m1 d! t            rest = 0;                          // 清零余值# t/ q. D8 i1 h% T7 e. R6 `
            srd.run_state = RUN;               // 设置为匀速运行状态
/ D) {- j9 Q9 N3 }          }
/ n- R; ]( R8 @          break;  r7 y' k4 `+ s' S

1 t; x, H8 ^: W) g! w$ B! n        case RUN:) r' w) T$ y6 ~4 B$ U
          step_count++;  // 步数加1
: n7 C: p* G3 Z; w% `          if(srd.dir==CW)
4 O) f( \" P- ]+ G3 e4 G. m          {                  & c5 z. n- E+ z; \( D2 ~1 z1 {
            step_position++; // 绝对位置加1
% c1 J+ d4 {# i7 C0 e- e          }
( ?6 f* u$ p- ^9 P8 y/ S          else
- ]. H- t, E! t+ g          {6 E5 g8 b3 E: Y; I8 s/ X8 Q* k* M% ^- n
            step_position--; // 绝对位置减1
6 g/ F) l' P+ J- \6 L8 z          }5 [) ]* G8 L& d! w- J5 [6 y, Z
          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)3 {% s& ]* O* o' r  R; h/ E9 ~
          if(step_count >= srd.decel_start)   // 需要开始减速& r# A: z( W0 }# O! l3 m
          {
  _# q' W" V9 _            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值
" @3 E7 S7 ?# u! M: S1 E9 M2 R            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)
! t% F+ ~( t, F            srd.run_state = DECEL;            // 状态改变为减速
. l. C. b. L. ^0 y2 n6 x          }
; i3 a( q/ i% ?1 F0 n3 Q          break;
3 s* }) j% M' J3 [! D3 M7 f* I. N# }5 c* Z/ a* b- Q+ [
        case DECEL:
2 G) x5 p& C' G4 H& j( r          step_count++;  // 步数加1' n6 V8 R$ j! U/ m7 X( s
          if(srd.dir==CW)
/ \+ M# C/ u7 H; E          {                 
3 U  N0 O4 h, p/ A3 E            step_position++; // 绝对位置加1! u4 c: p4 f$ q& F" T: J7 W
          }
7 ?+ t& X0 g; g  ]/ s2 K+ D! e6 u          else
  K6 g) Y; S0 E" T6 b          {
, K3 Q7 y" R2 R0 t            step_position--; // 绝对位置减1
% b0 D! N1 c4 p          }* X2 E9 O* j; \% S
          srd.accel_count++;
" k0 }, K3 o3 Z; g& ?0 `" c. ^          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
0 u  v6 c; ?. c) L          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
: l1 C" R4 M+ j% u$ S6 o         
- k' ~; M0 M+ _" T- w' Z          //检查是否为最后一步9 Q( E. H5 L, q0 y& f$ r
          if(srd.accel_count >= 0)
* a' K6 l6 L+ n" V          {# Z- v: S7 n9 K/ X
            srd.run_state = STOP;
, s5 b0 p# o  C# D% z4 h          }$ _) [; \1 r8 ]- v6 \$ e$ ~
          break;, m6 ~7 |2 F- d6 @5 x2 x
      }      
: e+ S5 X. k; V; x) V. n      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值
4 K' C( W$ a) v& E9 I3 P# R: v    }
6 m- ?8 E" z( w7 Y  }8 P5 L* X) w0 B$ g
}6 T& F0 n3 I2 c- \/ F9 g
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明
/ U" H# s8 v3 }0 X: G    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!( ]4 c2 e8 g& O. H

: K& v) D/ P1 s$ M
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。
3 T% q4 }( F  g6 `2 Z6 s
$ {; H$ i! }) ?8 Q* z% Z$ |技术群:1718975842 _/ h* |, M% w/ V1 @* R
公众号:游名开源
, ?$ x2 j+ l$ k: [# b% }( O4 [
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
2 `' {$ d" O, J4 P& b9 Y/ m6 C' }电机相对运动的函数和中断函数看着像硬石开发板里面的代码。

( I- l2 d8 K, J; s! y! s; w, B是的,参考他们的,有说明:写着参考硬石的
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 手机版