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

【经验分享】基于STM32之控制步进电机

[复制链接]
STMCU小助手 发布时间:2022-5-14 21:00
一、关于步进电机那点事
/ T: L$ \9 z9 A3 j这次使用的是二相步进电机,博客上也有许多关于步进电机的博文啊,质量也是参差不齐,今天就给大家仔细的介绍一下该电机,我主要还是继承以往的风格,资料方面我也讲的少,主要还是侧重实操方向,希望能够带给大家帮助! s, {7 P$ E. R+ Q1 E
8 L+ \  d+ C6 C7 t' ^
下面是图:
; O5 A/ s* M. t$ r$ L1 }4 e# J. }5 R3 [2 l0 l& n+ S4 y
(NW6T3LWCB0~(}G%`8}$%~K.png
% A& S, \, \& N  [# ~- C
, }- {9 i2 I$ e: t; ^9 v' r$ [1 J首先要认识一下步进电机上的几条线:
, D, p( O( a! g4 ^. b1 B/ P. ?! c& C+ F3 Q7 x5 j; n' W
四条线(红、蓝、绿、黑)& T2 i! h; O, E, Z/ Y. ^- |
! Q! f7 w. y; q! H+ ]* u& f0 O6 ^; A/ P
正常来说对应A+、A-、B+、B-,在电机上基本上也都会标明代表含义,其实步进电机的原理其实都差不多,主要就是学会使用和了解原理就基本上达到我们的目的了,如果想要深入学习,那可以再继续研究······0 X& H! l7 V  X2 q5 N7 ^* _
4 [/ F5 H" D* Q; W
那么怎么使用呢?首先就要搭配一款步进电机的驱动器了,网上随便都可以买到,如图:
3 b  Q5 C- E7 [. [
! w3 ~& ~" }) Y
, Y1 x- U) ]4 f9 J6 A9 ]: l# R% w! d) v
这里我们很明显可以看到它有12个接口,这里再详细介绍一下如何使用接口:
$ k% R7 ^1 S2 w* p6 z) ~1 D
0 A# f9 e; N( A3 w' u7 G1 ^V+:连接电源正极(注意电压在9V~32V之间即可,过大的话你懂得)
4 e/ H$ F; u; n; K4 T9 Z: X" I
: x9 M; i/ O  ^( V4 CGND:连接电源负极; ^# b$ l6 F, `/ t9 C
' t4 m9 X1 Y4 l% U' S( v" t: R" R( o
A+:连接电机绕组A+相
3 L+ }, h( k2 n& s1 m" c0 v
; O; `3 Q+ R0 I' p/ fA- : 连接电机绕组A-相
. p6 i+ \$ `& R9 m' b( U# Z. j
) i, h: f5 v0 ?6 E" mB+:连接电机绕组B+相5 F! r/ U) i5 k  }
) K; g# ~" P4 V' q& u
B- : 连接电机绕组B-相
9 t8 z; i6 Y* w
; c( i( L( Q+ C8 V% x5 @, |CP+:脉冲信号输入正 ( PUL+ )(取决于共阴、共阳接法再来接线,共阴的话CP-接地,CP+接脉冲信号即定时器PWM输出)
, W: b/ q8 W, b2 w
$ |* ]' h/ P4 j, b' h% V/ jCP-:脉冲信号输入负  ( PUL-)2 x( Y8 o! `9 T0 h
0 h& T0 A. F/ W* w
DIR+:电机正、反转控制正(同样取决于共阴共阳接法). d5 V" R9 O- G- ^( D: q
7 z8 I4 l5 F- \/ O9 O
DIR-:电机正、反转控制负& W3 A3 R( z0 [) B

; Q  {' B# o" `EN+:电机脱机控制正(可以不接)
$ A% N, B( r* t  M# a, d" n) @& l/ _0 Y) t- x. {# r+ G& \
EN-:电机脱机控制负
) l; S+ R9 e6 w; \( h- a0 A9 G+ u$ Q8 j- y4 h+ s/ U2 F4 W
二、接线问题
  t- {0 X! F4 v, i$ {上面到这可能对它的接线有了一个想法了,那么具体如何接线呢?嘿嘿,这里有共阴和共阳的常见的两种接法,具体参照下图:
2 _# |* E4 [& U0 }) m' x0 M) n5 n( t: N. ~% ]- O+ l
~26WQ5I1Y7EEZK1Z8KJC61M.png 1 @( s- w& b$ [- z

- z( P4 W7 h9 N" E/ P! ]: } ]KZC1MXDFS[99NB5TT}2~CI.png
. S( y" z6 |6 E, d# V* m- x" p. U6 m/ ~# O1 T
这里我采用了共阴极的接法
$ C) d6 K4 W( k+ F2 v1 c
3 Z$ e# k! L- s那么我的接线:, ~9 v- Q+ |+ T9 W3 V

9 Q; H2 Q+ g7 Y; wDIR+:PA8(随便一个端口即可)! h; t& I1 ?# G1 }
" X: y4 v; K3 Y3 ~9 C
DIR-:GND
9 M2 M- A* `, }, g8 J4 `% K
) v: B0 a( u- V3 g6 U. C: bCP+:PA1(TIM2通道2)8 y: Q% L, _, D6 D

  k) l; Y& P% _* Y: r& a4 bCP-:GND' K' o6 X9 i, m! g

; W; d/ r4 y0 r! G" jENA不接& Y5 y. V6 H7 G$ b) d' U! A9 y7 l

8 ^: i% W( h8 S% W三、主要代码
5 p. R  @- \+ F: a6 b这里的代码搬运后修改一些的,即可上手即可用6 f1 b: H  M" d, [

7 \8 m* g& [( k3 c主函数  }" |/ C0 K& i
2 ?, t! n5 x) u. b+ A" K* {, H
  1. #include "stm32f10x.h", E3 b) C  q4 y8 h, Q' y- J' k% V+ o7 i
  2. #include "sys.h"" F0 ~( @( g& E) S2 `
  3. #include "usart.h"9 B) y5 [+ W+ c# l: ?. z
  4. #include "delay.h"
    9 G2 V) `( ?$ s; G9 V1 j
  5. #include "key.h"
    2 [: g3 G* F% g. F8 B
  6. #include "led.h"         
    : h- v" s0 D; u- q# ~
  7. #include "usmart.h"        
    ( I3 u# ?( F( {# Q6 ]. e) f$ `/ h
  8. #include "driver.h"0 q8 M5 x2 ]) D

  9. + I0 D1 Q1 v4 n0 O5 {# `
  10. //共阴
    ; J0 S% m. `) N$ G! t* \4 s# I
  11. /*0 O/ M* k/ D# G7 K
  12. CP+->PA.1   CP-接GND
    ) q# x) C1 M! d2 g  [
  13. DIR+->PA.8  DIR-接GND% ~3 Z' J6 X5 s* [
  14. */
    6 i  b: }# A0 ~/ o% d
  15. ! N1 q) V  k/ s% {9 \
  16. int main(void)
    " x5 D7 ?. ~$ \8 Y. F3 \/ ?
  17. {         7 v, r  W7 j; m' J0 D
  18.         delay_init();                              
    : U* F# d& p& Q0 H) L8 s4 X
  19.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);           ?0 P# p+ M, T* M( f% p
  20.         uart_init(115200);            
    / x' v$ I8 n) {
  21.         KEY_Init();                        
    ) n( @) S4 C% \) Z5 \( f: s) E
  22.         Driver_Init();                        
    ; a1 t0 g( K  |1 K) D7 ?( F2 M
  23.         TIM2_Init(999,72-1);      
    5 z& s- `9 T% N: K  j, F9 {
  24.         while(1)
    & l* Y% B8 X+ v# a
  25.         {        
    - Z' l$ O+ {6 k4 O
  26.                         Locate_Rle2(500,CW);
    8 B( j5 l9 M6 G
  27.                         delay_ms(5000);
    ! N/ o& g9 ?2 Q0 U
  28.                         delay_ms(5000);
    ) `  y( X, ?: h; K
  29.                         delay_ms(5000);' J, A% M7 J/ I1 P7 @+ N
  30.                         Locate_Rle2(500,CCW);
    " z9 h6 `6 M$ o
  31.                         delay_ms(5000);: Z  m7 X* B: }9 A8 E6 S8 {
  32.                         delay_ms(5000);; K5 A4 d6 \, ?# {
  33.                         delay_ms(5000);
    " ~3 O0 R) H3 |& B* ]! y# ^
  34.                 }* R5 r8 m7 H) g8 L$ E# b

  35. + M2 K. k% G4 ]; m$ Z  A$ a
  36. }        
复制代码

' `: b9 F: j+ `  _$ g7 m 定时器函数:2 t5 c$ ^& B4 Z$ }/ L, z9 u* C
: F# O- d( z0 F" z0 k' N
  1. #include "stm32f10x.h"
    : H- a2 a4 [4 S4 b
  2. #include "driver.h"
    * \, F! S, V' Q$ q# |% I% ^" `
  3. #include "delay.h"* U4 i/ e0 T) V4 E3 }
  4. #include "usart.h"5 |5 U7 x7 z' x6 e+ j
  5. 5 K$ r, L, \5 g# h% P
  6. long current_pos[2]={0,0};
    / J6 V( }* |1 l8 q+ k; p2 L$ h
  7. int motor_dir2=0;
    2 \, J: Z* q6 @( n% y# J
  8. u8 count[2]={0,0};$ B' n- E- O3 `1 M& z

  9. % x% n1 F$ N: B9 ?: B  x" x
  10. void Driver_Init(void)
      r) t- h; V6 x# f& }. g
  11. {
    6 r0 f+ N9 T# W) Y+ b
  12.         GPIO_InitTypeDef  GPIO_InitStructure;( K! _0 H0 I! |4 K# [3 D
  13. " z1 r+ O1 i/ f% c* x# m* i# V
  14.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);        
    , L8 A6 Y/ }$ p8 Q6 J; E1 h3 `

  15. 3 k4 F0 }  m/ K8 i& {4 C* C! |5 A% ?9 [
  16.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;        
    ( o2 `# K) D8 t% S
  17.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 
    . m: e: j9 j1 C1 O' x; X* C7 A
  18.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;        
    * T( Q( M3 S, _! o" Q/ b
  19.         GPIO_Init(GPIOA, &GPIO_InitStructure);                                       
    * G" X$ N$ G  b; M# Q
  20.         GPIO_SetBits(GPIOA,GPIO_Pin_8);                                                5 F; Q2 G; B% c% j3 B* J  P+ i
  21. }8 O  _/ v6 h/ U4 ]# R
  22. % b$ k" C& k7 Y
  23. ; D8 c9 ?$ [. O  l8 o* y1 Q
  24. void TIM2_Init(u16 arr,u16 psc)
    5 g( J* k6 O- Z* W3 ?9 n: {
  25. {                                                          5 |/ L+ s, C9 ?- x) r( e
  26.         GPIO_InitTypeDef GPIO_InitStructure;
    ! C- C9 `7 _/ Q2 i8 z  L
  27.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    & E: I9 a# R8 B# i& E# Y) e" f- L
  28.         TIM_OCInitTypeDef  TIM_OCInitStructure;# \* v+ |% X8 m
  29.         NVIC_InitTypeDef NVIC_InitStructure;: r/ z+ O4 v6 F) F3 ]
  30. # r% \# a# E4 o: T$ v7 p  {1 I
  31.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);         ; W% X% ?% `5 b7 w1 w
  32.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);                                                                              - u& L% z8 S9 d' {

  33. " Q; p. F$ L' g0 I/ b  q
  34.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                                //TIM2_CH2
    4 A' w# V( N9 v% v
  35.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;                        6 x1 Z9 b& W1 S5 [/ `
  36.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;% |) S  @9 J6 B7 Z
  37.         GPIO_Init(GPIOA, &GPIO_InitStructure);
    ' `* i6 p. W! l1 p$ c$ f
  38.         + Y& p4 R( b& z3 x; a% u2 _( [1 E
  39.         TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
    5 b  J% t0 p- ]" z
  40.         
    7 h9 ]' M1 L/ S2 F" R2 m, [
  41.         TIM_TimeBaseStructure.TIM_Period = arr;                                         
    - r8 Y# _+ D+ Z- [, L1 n5 B
  42.         TIM_TimeBaseStructure.TIM_Prescaler =psc;                                
      `; |; z: X. Z5 e
  43.         TIM_TimeBaseStructure.TIM_ClockDivision = 0;                         " S/ \2 D, w; m, B; o
  44.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 1 o8 _7 C$ d4 I3 U. G; o, ~& J' i
  45.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);                 5 A" K+ J+ Y9 o! K0 c# d  {3 B2 x: S
  46.         TIM_ClearITPendingBit(TIM2,TIM_IT_Update);                                % p* k. f: d- s( }

  47. # Z* Z0 s4 S4 g# V
  48.         TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Regular);
    8 K9 F' ?4 p" e. d5 m
  49.         TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single);                        
    1 O# H) N1 M2 k0 x' @3 |% s
  50.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;               
    . Z# e6 @# Z# w3 a* e6 r' T7 D
  51.         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; ) W. @) z- G) @  ]" [
  52.         TIM_OCInitStructure.TIM_Pulse = arr>>1;                                 
    # \$ k: |) A' i5 I, ?2 v- Y  @
  53.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    5 \$ {% l4 a0 h/ X4 G, p# N" m
  54.         TIM_OC2Init(TIM2, &TIM_OCInitStructure);                                 ; X) y% c: {( N0 b

  55. % J/ e" I! _( Z3 {
  56.         TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);                  2 B( ]' N6 ?9 o
  57.         TIM_ARRPreloadConfig(TIM2, ENABLE);                                         * h$ h" a4 L8 @2 p8 z
  58.         % k  J; u% m/ W$ O1 ^6 d
  59.         TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);                          + z# _% ]# H" M7 w% }
  60. , M0 a2 X9 N: O
  61.         NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                  ! k, O  Z. c0 Y. {5 {8 |' _/ P
  62.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  % D0 }& L$ u& \% P+ T& o
  63.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                 * P$ R% z: z; S+ c
  64.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         4 g: y# N* k* g0 y
  65.         NVIC_Init(&NVIC_InitStructure);                                                  
    - W5 H: ^& O. p- s7 |
  66.         7 a" g7 L& @# D. d! R9 i# F7 h
  67.         TIM_ClearITPendingBit(TIM2, TIM_IT_Update);                          1 B/ D6 N) T5 `" W
  68.         TIM_Cmd(TIM2, DISABLE);                                                                                                                           
    4 l9 j$ g. C5 x6 `6 [) x+ J
  69. }
    / ]' F3 j+ h3 p0 A% E4 {: C
  70. /******* TIM2*********/0 c1 W! y+ N: F" S4 N( G
  71. void TIM2_IRQHandler(void)
    7 W. R5 y" n. f/ _) `. I
  72. {
    6 ?# I3 [$ C# h+ ]* ^
  73.         if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)!=RESET)% v# n  J2 A0 A, X1 e
  74.         {
    % q# N: F! U& W- [  W
  75.                 TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);        % z2 W) ]* J, Y1 O! A5 X
  76.                 count[0]++; 6 O+ L3 i* L% G& V6 b& i
  77.                 TIM_GenerateEvent(TIM2,TIM_EventSource_Update);
    8 x5 a! A" t2 g# K
  78.         ; Y# l2 J% l. g6 o  j* R  p0 g2 [1 I
  79.                 TIM_Cmd(TIM2, ENABLE);                                            ! ?3 Y) Z* O2 u8 w) n
  80. 2 o% w3 }3 q  k( _" Y
  81.                 if(count[0]==200)
    - t6 h4 M* [8 i  C7 P. ?
  82.                 {0 P/ g& z- C4 m) U
  83.                         if(motor_dir2==CW)                                                   % o9 n/ x0 B0 n
  84.                                 current_pos[0]+=count[0];
    ) g# _' L9 N. _7 F3 C
  85.                         else                                                                    
    * r6 ~( I1 }) |, a
  86.                                 current_pos[0]-=count[0];
    / f2 v* _2 {; [- O: }
  87.                         TIM_Cmd(TIM2, DISABLE);                                                   
    ; G* q% M) r7 _! E$ C, s' u& [1 P+ i
  88.                         printf("motor2µ±Ç°Î»ÖÃ=%ld\r\n",current_pos[0]);: \" o! j& d0 L5 h3 N8 _- \4 C
  89.                         count[0]=0;. c; J+ J" O; ]. ]) H
  90.                 }# L. e  T  c0 F' I
  91.         + f5 o( A& c3 s: T& E/ o
  92.         }+ A) p6 Q' r; D3 [3 O9 W+ Y, \; T$ j
  93. }5 ?$ l, Q8 G3 s
  94. 1 Q& m/ s9 m( i9 T$ \9 U; i
  95. void TIM2_Startup(u32 frequency)   
    5 x3 k, }! d/ A& @9 K3 |+ p
  96. {
    ) ~4 u& @9 x  g
  97.         u16 temp_arr=1000000/frequency-1;
    / P+ X" \7 N9 v& H% ^! w
  98.         TIM_SetAutoreload(TIM2,temp_arr);
    + B: ]$ v4 G! P5 \7 I+ J; R2 H4 s
  99.         TIM_SetCompare2(TIM2,temp_arr>>1); + r( R9 |0 U4 O& z
  100.         
    & Y$ e4 v$ F$ Y5 f) P" e1 z% G, ?
  101.         TIM_SetCounter(TIM2,0);
    9 E) D* Z5 Q( `9 o" C
  102.         TIM_Cmd(TIM2, ENABLE);  
    4 l! ^# h5 t3 P0 c) r9 S2 z
  103. }9 H. d" U( K2 s

  104. * t% B+ ]" R0 p/ Q: Y
  105. - _) e$ a; o# f- P9 i- ~) e6 t  R
  106. void Locate_Rle2(u32 frequency,DIR_Type dir) 4 Z- o1 g! J1 ~* N4 @
  107. {
    - Y0 J9 z5 T, o  W5 S4 X
  108.         
    ( `, C: v/ Z# |( z; T
  109.         if(TIM2->CR1&0x01)
    3 d" ]; Y( R1 B- X4 R
  110.         {
    + }" ^" U8 T# |- A6 e. ~
  111.                 printf("\r\nThe last time pulses is not send finished,wait please!\r\n");. R1 U( v8 S0 e/ p5 m
  112.                 return;
    4 s4 M3 W, g6 [
  113.         }
    ; d) Z$ N4 q: a' ~) [3 l
  114.         if((frequency<20)||(frequency>100000))7 J9 [2 {, d2 X& I* G! x: I! @
  115.         {
    8 h& z/ \; e3 U/ p
  116.                 printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");+ _% q6 X& H# E' G- m0 b
  117.                 return;8 u* a7 o: q  C$ \7 |9 \7 E
  118.         }! z7 l3 {1 H0 k$ ~" ?
  119.         motor_dir2=dir;$ H! b$ [# c  @( i
  120.         ( \/ _; T( O( T: q8 t- A
  121.         DRIVER_DIR2=motor_dir2;                                
    ! m* [7 S7 a; ^8 H! s
  122.         TIM2_Startup(frequency);                        
    ; M. O0 I+ S5 o) o; q) Z3 T: G2 _
  123. }( Y# c& a& C: V: p2 p
复制代码
* M7 s6 F" k) j  j: X8 _) a
到这里你就会发现其实原理还是相当简单的,剩下的也不再深入了,希望能够对大家帮助哈哈
+ b: h, R* N$ V) r0 o) p2 F6 [- @9 B0 w  {# L, f/ A
实现目的:1 D6 d$ l9 L/ Y& }. S1 _2 b
6 e6 |5 s; p/ ?/ k! l6 n' u6 O# x6 z
该程序就是实现正转后隔一会再反转,大家可以根据自己需求设置到自己想要的转动情况,同时要让他停下来,只需要在自己需要的地方设置一个TIM_SetCompare2(TIM2,0)即可停下,可以自由设置。
, \8 Q% \5 x0 y; I
6 Z' ~9 F' c9 [7 Z, r( R. C四、总结! R* `: a+ b% q& I! o; j
今天关于步进电机就暂且介绍到这里,后面有需要会再特别介绍一下,文章写得还是比较简单,相信对于你还是可以很轻松入手的) E) o  S, l* k8 [% R
. L: I  p9 P0 c* ~$ o" X

) y% E( k4 u$ y$ b* V
赞 收藏 评论0 发布时间:2022-5-14 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版