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

游名科技: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
初始化程序如下参考:8 [% i/ O5 g/ h" F1 u3 y! N0 l) h' V
  /* Initialize all configured peripherals */( J) T9 d4 G0 w9 C8 S7 W0 Y- {3 a
  MX_GPIO_Init();: B1 K/ k3 ~2 ]9 @4 U
  MX_USART2_UART_Init();
5 X" H' A. x; [+ y, f  MX_TIM1_Init();
6 \# f8 `# c# g/ d# Z- k( M% V! M' ~        STEPMOTOR_TIMx_Init();                /定时器输出初始化
4 L( O8 M* K8 H; w& `. e; y  /* USER CODE BEGIN 2 */
+ j2 P/ n& u: |1 Y0 p8 ]* [5 B        STEPMOTOR_OUTPUT_DISABLE();        //TMC2160禁止使能  z) _* a) j# M0 C: ~( C2 d5 z! t+ m' ~
  /* USER CODE END 2 */
9 ?2 S9 J7 m  r$ C9 V  /* Infinite loop */  p& g( P, O$ L8 p
  /* USER CODE BEGIN WHILE */
6 ~6 D; N& M! M8 z8 R5 V: q  while (1)
# |% x. F; o$ z+ {: k- }7 o. v2 T  {
, Z, U  k7 G3 v0 P    /* USER CODE END WHILE */
- P' R, K8 o, x5 B+ ?5 S/ q/ _                STEPMOTOR_AxisMoveRel(6400*-2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
0 A/ I9 h: W7 W9 N7 L1 X* x" j% B                LedOnOff();                                //LED闪烁处理
  P, x$ ~  S6 p& f* _: A                STEPMOTOR_AxisMoveRel(6400*2, 5000 , 5000 , 1200);                        //控制TMC2160驱动步进电机反转2圈(32细分,1.8度则一圈需要6400个脉冲)
0 a* S& J- S' X9 m: h# n                LedOnOff();                                //LED闪烁处理
0 G; e- [8 [: p# k1 k$ J8 |0 n    /* USER CODE BEGIN 3 */
% @; S2 h1 W% y# N, t- {9 L/ Z  }
- d# h' \8 D  z
mmuuss586 回答时间:2020-4-29 12:54:33
//相对位置移动参考(参考硬石的电机开发板资料)5 W; r0 l9 w! D3 n4 V
/**) j  c3 j, R) k6 @3 R* p9 V/ _+ l
  * 函数功能: 相对位置运动:运动给定的步数
8 f8 ]+ o5 Y4 \$ e$ i$ l  * 输入参数: step:移动的步数 (正数为顺时针,负数为逆时针).
1 u. ?- G1 U/ @5 d              accel  加速度,实际值为accel*0.1*rad/sec^28 k8 o6 y  e9 v9 v( d* Y5 H
              decel  减速度,实际值为decel*0.1*rad/sec^2- [3 m( N4 S  Q* U# D6 \3 |- w. \
              speed  最大速度,实际值为speed*0.1*rad/sec* a/ ?' P" r1 z+ v; h' I) D
  * 返 回 值: 无/ {. F2 j2 j# I
  * 说    明: 以给定的步数移动步进电机,先加速到最大速度,然后在合适位置开始, e. R) a5 K5 a. M
  *           减速至停止,使得整个运动距离为指定的步数。如果加减速阶段很短并且2 B$ u  G, ]- W
  *           速度很慢,那还没达到最大速度就要开始减速
* a  i6 p' Z8 k" U/ N  */: Z) g8 L8 _- Y. e7 @4 r$ G% ~
void STEPMOTOR_AxisMoveRel(__IO int32_t step, __IO uint32_t accel, __IO uint32_t decel, __IO uint32_t speed)( f8 n3 H$ i8 }# N( f) Q
{  * e# s9 K9 N2 f. m! o1 J& p- q) V
  __IO uint16_t tim_count;
/ M6 C4 J/ D6 F6 j5 q  // 达到最大速度时的步数" }' H# \, M! q" n9 D6 n( Q
  __IO uint32_t max_s_lim;
% a) L- {/ }# N# {. u6 O, H( ~  // 必须要开始减速的步数(如果加速没有达到最大速度)
$ p! C& Q; y, q  __IO uint32_t accel_lim;1 v! P% X1 g  a3 W0 y$ B- h! m
( L; [9 w3 C: F
  if(step < 0) // 步数为负数
5 |6 z' T3 R" Y' y  {
% s% U( T1 x+ E- g2 N    srd.dir = CCW; // 逆时针方向旋转/ @' h% V2 {' s! R" L' c
    STEPMOTOR_DIR_REVERSAL();8 }4 m) U( V6 e
    step =-step;   // 获取步数绝对值
/ g5 n+ }3 j" d( @  }0 v' X. g4 Q* {& e; Z; e
  else! X! E# H5 g- Z. D6 d! t0 N
  {
& ]& U* |/ N' i2 Q; W- ?4 {    srd.dir = CW; // 顺时针方向旋转; y3 H3 |9 v$ m% n3 c7 T' `
    STEPMOTOR_DIR_FORWARD();
2 k: w- \7 P; {( y  }7 W  t" v' W# j3 ?. r
  
3 m+ v' R4 |! L1 R3 ^  if(step == 1)    // 步数为1$ Y0 y% f2 R9 w. q0 X
  {! b8 U. _; V! x: B$ [
    srd.accel_count = -1;   // 只移动一步
4 O+ V0 @9 {0 D) H, J    srd.run_state = DECEL;  // 减速状态.
8 U! E& z. K# m- B+ D8 v# b    srd.step_delay = 1000;        // 短延时       
' W+ f* C0 |/ \* `3 C  }
3 t4 J! h2 D9 p; \$ _8 o- L  else if(step != 0)  // 如果目标运动步数不为05 v. S) f, l6 \  M. u
  {% F" {/ s( P+ o9 T$ u
    // 我们的驱动器用户手册有详细的计算及推导过程, z* Y1 V2 U5 \$ U& [

; q& @# E* n6 Q! f0 M1 D/ U2 }    // 设置最大速度极限, 计算得到min_delay用于定时器的计数器的值。3 Y) ]3 ^9 V9 Z/ b/ i
    // min_delay = (alpha / tt)/ w. Z; c6 ]( ]1 A8 U; m2 Q
    srd.min_delay = (int32_t)(A_T_x10/speed);
/ v' Q0 `3 m2 a; C* c- H; _/ z3 j# v6 }) t  ^
    // 通过计算第一个(c0) 的步进延时来设定加速度,其中accel单位为0.1rad/sec^2
' |0 |9 m  t+ h    // step_delay = 1/tt * sqrt(2*alpha/accel)  b2 t% ]  H% \1 d: t4 s7 P
    // step_delay = ( tfreq*0.676/10 )*10 * sqrt( (2*alpha*100000) / (accel*10) )/100
8 \" ]/ ^$ ^& ~0 ~" n1 q* A& {    srd.step_delay = (int32_t)((T1_FREQ_148 * sqrt(A_SQ / accel))/10);6 [+ q" b. W  }% q5 o

: f. N2 a8 n, N    // 计算多少步之后达到最大速度的限制
$ p, O& ~: {6 P  G2 D( f( Z    // max_s_lim = speed^2 / (2*alpha*accel)  v# ]" g/ w' u7 i
    max_s_lim = (uint32_t)(speed*speed/(A_x200*accel/10));
" q) B4 A+ o  V5 D7 G1 K* T+ g    // 如果达到最大速度小于0.5步,我们将四舍五入为0
. |% }2 x# g+ M    // 但实际我们必须移动至少一步才能达到想要的速度- ?8 s9 x9 y6 `. p
    if(max_s_lim == 0){7 K. \) m( S. O0 s& y1 V& s
      max_s_lim = 1;
- X# q; Q) }. F* I* Y    }
2 z8 o* X3 s/ V/ M+ B. C$ D
mmuuss586 回答时间:2020-4-29 12:55:03
// 计算多少步之后我们必须开始减速
2 @! N- k: W$ \' r/ V: V    // n1 = (n1+n2)decel / (accel + decel)
" o) _! ?- x/ u6 y    accel_lim = (uint32_t)(step*decel/(accel+decel));
; \- Z0 A, f" Q9 S! M    // 我们必须加速至少1步才能才能开始减速.
4 ^( u6 A, m9 ?, z# r& t9 i    if(accel_lim == 0){
7 ~* t; l$ J. ]/ O" t      accel_lim = 1;( x: A7 d! b8 r5 \
    }
, ~* _; S* \5 S/ P7 @  L9 \) ?6 C! }& L% g3 x+ Z9 d# O) i5 R. h
    // 使用限制条件我们可以计算出减速阶段步数) k1 l7 [/ z6 D  o
    if(accel_lim <= max_s_lim){) s8 M$ v- t0 a3 g0 B- l' W/ h
      srd.decel_val = accel_lim - step;0 o" ~$ u0 W0 r% l; T
    }
7 v' ^  J' V7 \+ s  q# V6 ]    else{4 h% ~4 N& n% N+ A% _8 P
      srd.decel_val = -(max_s_lim*accel/decel);) w0 o5 @8 Q. [: U
    }
1 p; y6 A" l# T" U  z8 U5 M+ b    // 当只剩下一步我们必须减速
, |- W: N3 ?4 ]( u8 T; H- _& s' J1 n& D    if(srd.decel_val == 0){
' e+ p2 z" M3 y% g; J      srd.decel_val = -1;/ q+ p% g& T) v" ]& N  p! w
    }7 o+ ~; I/ p, R6 H: @. n

- _9 H- n- E8 D0 M8 f2 V    // 计算开始减速时的步数
# s6 `- |1 G1 g: p6 I/ D& K    srd.decel_start = step + srd.decel_val;
% z2 z3 u5 S% n3 f$ D7 y0 [8 n8 z9 T+ {; y" q% t6 Z% C
    // 如果最大速度很慢,我们就不需要进行加速运动% G# i9 D; H' o5 |: ]# v' \) w+ n
    if(srd.step_delay <= srd.min_delay){
8 `, o, X* }4 e+ y/ w      srd.step_delay = srd.min_delay;  V! P' s8 o. E! |3 c7 I/ _! g
      srd.run_state = RUN;
3 B1 Z  N( u* S  o8 [    }& @+ X) y& ^% `" U
    else{$ o0 y% [" ?, {8 ?" p
      srd.run_state = ACCEL;
, t6 [, i: O9 b* y: L" d1 h    }    8 x' w) M/ P, h. c8 ~' H
    // 复位加速度计数值6 V3 K8 v2 m* Q/ l. Z% s
    srd.accel_count = 0;
1 d- j* i. N' ^, t+ L' R  }" G+ \! p6 G. Z) T. x# {( I6 M
  MotionStatus = 1; // 电机为运动状态$ Z8 R# ]2 Q5 O$ m8 a
  tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);) M1 e! q- q0 n0 t* T8 p* i9 p/ g
  __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay); // 设置定时器比较值- `* m$ e5 I9 l4 C! g  a7 o6 e
  TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_ENABLE);                                                                // 使能定时器通道
4 `5 {+ m4 H1 {) t  e9 ^  STEPMOTOR_OUTPUT_ENABLE();
% ^5 Y4 Q, u& B}. H% A( X! D% x- _
mmuuss586 回答时间:2020-4-29 12:55:37
//定时器中断函数参考0 C+ m9 M1 x6 Y1 V, p
/**( Q" v1 u( W9 L/ R+ e
  * 函数功能: 定时器中断服务函数1 `5 o+ ^& m# g- z
  * 输入参数: 无& C* P- {6 m% m
  * 返 回 值: 无
" a# W' E* ^( G) z  * 说    明: 实现加减速过程/ C5 s+ A+ b0 N' T6 L
  */, ?5 b: L' g- @9 r9 Q
void STEPMOTOR_TIMx_IRQHandler(void)//定时器中断处理5 y2 w4 q0 X, ^! U$ j# X
{
9 ]) I: K( @" _# L+ S5 h$ [" z  __IO uint16_t tim_count=0;
" B5 I. W9 M' g9 t: |  // 保存新(下)一个延时周期: A7 H1 ^/ Z, ^" M# c" {2 F
  uint16_t new_step_delay=0;
- q) `: ^% ~0 x  // 加速过程中最后一次延时(脉冲周期).
3 E4 m$ q- i/ v( w% {0 [: I+ B$ Y  __IO static uint16_t last_accel_delay=0;) Q6 N3 _3 K- o0 a1 S
  // 总移动步数计数器
4 Y. ^5 K# z4 u+ ~  __IO static uint32_t step_count = 0;9 Y+ N: h2 _" V1 j/ g/ [
  // 记录new_step_delay中的余数,提高下一步计算的精度6 A$ o' h8 k3 y# c# d: C+ _
  __IO static int32_t rest = 0;5 O5 V+ z! Y5 ~* F5 p
  //定时器使用翻转模式,需要进入两次中断才输出一个完整脉冲
  O& g7 t- @* t" y8 Y3 C4 l  __IO static uint8_t i=0;% u! y/ u5 z+ d1 i* @! p
  
! ]1 K; S; b3 V0 C7 @  if(__HAL_TIM_GET_IT_SOURCE(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx) !=RESET)
  x, B8 V* W: o3 X) g- l! E  O7 l  {: U& j, y6 M, r& h+ J, K
    // 清楚定时器中断' {) D4 W: q8 Z
    __HAL_TIM_CLEAR_IT(&htimx_STEPMOTOR, STEPMOTOR_TIM_IT_CCx);% b. M( O8 z8 i$ B: }: I
    0 G9 h8 U- F$ u: A. _
    // 设置比较值9 C  }! R0 [1 S+ G
    tim_count=__HAL_TIM_GET_COUNTER(&htimx_STEPMOTOR);+ W) }8 V+ D6 f# p( G( {: @
    __HAL_TIM_SET_COMPARE(&htimx_STEPMOTOR,STEPMOTOR_TIM_CHANNEL_x,tim_count+srd.step_delay);! B9 [6 {' y" D: K  |

' P% G2 {$ K( t, r8 J. z! ~    i++;     // 定时器中断次数计数值
! ?3 [: N5 v. v2 j2 _  c    if(i==2) // 2次,说明已经输出一个完整脉冲
" I) K# O/ o5 M! y- W; E; e    {
( o. T, \2 P+ z: R% m. Q+ ?      i=0;   // 清零定时器中断次数计数值
" I* l- t. V: d5 e      switch(srd.run_state) // 加减速曲线阶段' ]# J5 J, c$ i1 J7 x* w5 [
      {
) W  M# w# J* q1 k5 w        case STOP:
) L6 G- i- Z# z' W- n4 Q- G7 l$ |          step_count = 0;  // 清零步数计数器) V4 k# Z" c7 `# K6 r- J
          rest = 0;        // 清零余值
2 G% B* @# ^& ]& d) K* {( x! o          // 关闭通道9 M' R$ G4 l7 \+ G
          TIM_CCxChannelCmd(STEPMOTOR_TIMx, STEPMOTOR_TIM_CHANNEL_x, TIM_CCx_DISABLE);        % j) I2 w& O. n3 k  t6 N
          __HAL_TIM_CLEAR_FLAG(&htimx_STEPMOTOR, STEPMOTOR_TIM_FLAG_CCx);) K1 w% }4 H: B) D8 U9 x- y
          STEPMOTOR_OUTPUT_DISABLE();  `& g+ c$ v# b. \- {0 M
          MotionStatus = 0;  //  电机为停止状态     
: U! I! w; f" W& v          break;
. F5 [" x9 Q% X4 H! v0 |, G9 n9 }5 W
        case ACCEL:+ `  O/ {0 K  U  b4 h$ U7 }6 u
          step_count++;      // 步数加1; Q" E1 E* |9 \' c8 m" D
          if(srd.dir==CW)* d- [2 {: J8 D1 _& H; \
          {                 
, ~- X1 q- a! Z3 t9 M: d/ a& ~$ W8 d            step_position++; // 绝对位置加1: l  ~+ j1 e$ w
          }
( u" C* ^& H+ U: \          else
) w* K" H. L) B' W2 e          {% i0 s+ c( u0 r" R
            step_position--; // 绝对位置减11 K6 P3 Y2 h* j/ d" {
          }7 @9 b3 M2 }! k; u
          srd.accel_count++; // 加速计数值加1. o  m' N( G, q
          new_step_delay = srd.step_delay - (((2 *srd.step_delay) + rest)/(4 * srd.accel_count + 1));//计算新(下)一步脉冲周期(时间间隔): R' n& {2 {: A- h: B( L' k
          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
* G) E: c2 z: h" C5 W) |          if(step_count >= srd.decel_start)// 检查是够应该开始减速. E# M0 q, m8 a2 z9 T
          {$ h9 `$ k% _4 |; D/ x6 c  ?  C
            srd.accel_count = srd.decel_val; // 加速计数值为减速阶段计数值的初始值( @6 O. k6 T$ H: W
            srd.run_state = DECEL;           // 下个脉冲进入减速阶段
- t7 _  w6 ^1 I* G% ], S          }; d- e" z/ r' p. J5 P+ f/ C# \
          else if(new_step_delay <= srd.min_delay) // 检查是否到达期望的最大速度
6 l6 R; p9 J$ F, e( [1 a1 Y9 o7 Q          {/ f! v9 f/ u+ Q& Z9 Y
            last_accel_delay = new_step_delay; // 保存加速过程中最后一次延时(脉冲周期)$ e" a" k9 ?7 E
            new_step_delay = srd.min_delay;    // 使用min_delay(对应最大速度speed)
/ z  z8 h; t8 n: W6 T            rest = 0;                          // 清零余值
8 D; ^' B1 D+ h$ W9 Q4 T8 W            srd.run_state = RUN;               // 设置为匀速运行状态3 F  A7 ^/ o* ^& l, P9 ?
          }& X7 O, e) g) Y
          break;
1 l' A7 \( u. D/ n. @
9 M  w6 E7 B$ b  H        case RUN:- E( U; G* X# v0 F
          step_count++;  // 步数加12 P! v& \6 S4 Y, }3 G
          if(srd.dir==CW)& d* }7 T+ C7 [
          {                  % L: ^( q6 @9 r% K3 T) v
            step_position++; // 绝对位置加1
+ `# ^& ]( i  K& d" f          }
! C8 F' D0 ]* t" d7 I          else
6 D  E+ l) d& L          {
# j% ?! g; O/ \( I, G# c            step_position--; // 绝对位置减1
: A' A' ]6 j+ n+ p          }* z! k* d. H9 |' z# w  x. ^. C" k4 T
          new_step_delay = srd.min_delay;     // 使用min_delay(对应最大速度speed)% |; R( }! G3 M) y$ E; Q
          if(step_count >= srd.decel_start)   // 需要开始减速3 N) x, L6 o1 r8 g& [% T# ~0 L
          {
, W, I, ?9 z5 {* G' o9 `! a            srd.accel_count = srd.decel_val;  // 减速步数做为加速计数值
& `$ O* @" E2 y$ t: p            new_step_delay = last_accel_delay;// 加阶段最后的延时做为减速阶段的起始延时(脉冲周期)0 x7 _- k# V+ q% k; z  c  h6 s. A
            srd.run_state = DECEL;            // 状态改变为减速3 N; o7 B" V7 v: z9 W) n
          }
) ~# t0 X) s+ ^# N% L% T          break;1 u7 a" {3 G2 l: s9 V

7 [6 x3 x& }! c/ ~' q        case DECEL:
) E, n- M4 i6 j! `7 Q" x          step_count++;  // 步数加15 E0 @. |' e, ]- y( A
          if(srd.dir==CW)6 [) L: o8 ^* F$ ?; n, n
          {                 
3 a8 R" [+ T6 ~7 y( u2 e            step_position++; // 绝对位置加1  G. f2 g7 z+ {7 C
          }6 T& M% `8 T" S9 I- L% l
          else( r! x6 `8 b% T" c
          {' F# L9 U8 U$ A7 F
            step_position--; // 绝对位置减1- u/ j4 B- a1 I4 u9 ?  a
          }
3 c' C; j- c1 y. r$ [3 @1 \4 B          srd.accel_count++;
% H* J  h. B2 e% G          new_step_delay = srd.step_delay - (((2 * srd.step_delay) + rest)/(4 * srd.accel_count + 1)); //计算新(下)一步脉冲周期(时间间隔)
; a1 C: U+ o9 }' N2 b8 U          rest = ((2 * srd.step_delay)+rest)%(4 * srd.accel_count + 1);// 计算余数,下次计算补上余数,减少误差
/ v' T8 c. E, @) H2 K# q9 y7 R" `          # [! F% Z" q* z  W/ f( h
          //检查是否为最后一步& X) c% {* c; T% k1 f
          if(srd.accel_count >= 0)
* P) }! K6 G7 Z+ _          {
, X+ J2 A* J$ ]$ i  c            srd.run_state = STOP;
; w% Q% \- ~4 b          }1 X2 R2 G2 w  S
          break;* F4 T/ l$ ^, r' K$ l2 @% J
      }      
( l& J; ?, n1 G$ P& ?, b+ s      srd.step_delay = new_step_delay; // 为下个(新的)延时(脉冲周期)赋值. K8 f9 K$ V& ?. o5 ^) A! q
    }
; V- k) i- v# F$ @/ _  n, ^  }
1 e& ?6 O3 C1 X; r}
5 {: _$ ?  ^5 U9 L
mmuuss586 回答时间:2020-4-29 12:56:22
五、开源补充说明
. I  A0 ^3 I, L0 `) B% _    如果确实需要原理图和PCB的用户,请联系我们的客服或管理员私下索取谢谢!& d5 ?& h6 h5 Z! s2 i0 f1 m  Z
( t# \9 r) d: {: W* G  E
mmuuss586 回答时间:2020-4-29 12:56:49
如对文档有疑问或有技术问题需要交流,可联系Trinamic原厂或我们。* z+ s# {$ {7 e9 P
2 p" O! r* K- Y3 G4 Z! @0 l
技术群:171897584& O# h2 \: D, w% Q( K/ L& s
公众号:游名开源
: ~( g) T3 r1 D( C4 a+ M* Y+ F
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 L0 ~1 {' ]2 m' L" _1 Z3 j
电机相对运动的函数和中断函数看着像硬石开发板里面的代码。
0 I* Z( t" u0 B3 l* [1 b; W- O2 f
是的,参考他们的,有说明:写着参考硬石的
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 手机版