一、关于步进电机那点事
8 a# I/ |/ f! t T# E这次使用的是二相步进电机,博客上也有许多关于步进电机的博文啊,质量也是参差不齐,今天就给大家仔细的介绍一下该电机,我主要还是继承以往的风格,资料方面我也讲的少,主要还是侧重实操方向,希望能够带给大家帮助. T; h0 D a8 o5 M+ M5 f
9 D! O& d2 Y8 g2 K下面是图: + h% W1 i' C7 e, V+ X
! V# I* k4 p; F/ y1 q
5 W8 g1 I) ~+ ]
% x/ e U3 A- X/ S* d
首先要认识一下步进电机上的几条线: a4 F, {# s: f( q5 i9 t
% ? ~7 P$ w+ ^/ }四条线(红、蓝、绿、黑)1 Y' F$ P) u. j, p' J3 B
, n* C: z3 n. {1 m( i0 x) }
正常来说对应A+、A-、B+、B-,在电机上基本上也都会标明代表含义,其实步进电机的原理其实都差不多,主要就是学会使用和了解原理就基本上达到我们的目的了,如果想要深入学习,那可以再继续研究······6 c# R2 F" h$ y7 q: G& B
4 x' ?4 M0 s" O5 _
那么怎么使用呢?首先就要搭配一款步进电机的驱动器了,网上随便都可以买到,如图:; d3 s& g# Z8 L+ _ q1 N( u
7 Q% f* m7 T# {1 w% N9 l6 `8 X
* y! d4 `$ G* [) g R9 ] L( R
& S+ v! C0 Z" X
这里我们很明显可以看到它有12个接口,这里再详细介绍一下如何使用接口:
4 R/ c+ v, |6 [2 R6 X
. A- k$ W0 W1 D6 G8 O/ ?+ u* fV+:连接电源正极(注意电压在9V~32V之间即可,过大的话你懂得), u8 j0 \7 R% A! k0 [
# S3 k7 Y- v; a+ s0 M
GND:连接电源负极
" S# s' u2 j( F) [
5 f) B) ?& z1 e+ L7 I- WA+:连接电机绕组A+相' ]+ P$ G7 ^& u* r$ Y2 l( r
g9 O1 }/ ]) vA- : 连接电机绕组A-相% v3 j5 H1 G5 l, x, s' g. b
5 Y, Z% _# m9 G, U, PB+:连接电机绕组B+相5 c b1 N+ t) b; S" V8 G. O$ U- ^5 {
* T% w1 }, a8 c) \; U1 V
B- : 连接电机绕组B-相4 M3 T r% e$ Q% B" W# u
* i2 y% q( ~% e6 g2 Z0 e+ r! eCP+:脉冲信号输入正 ( PUL+ )(取决于共阴、共阳接法再来接线,共阴的话CP-接地,CP+接脉冲信号即定时器PWM输出)( C+ G' w" E; ^9 K
0 i* }% H" P8 Q4 D5 z- R& \
CP-:脉冲信号输入负 ( PUL-)
+ J; ]2 m" `- e7 t8 i* G3 F5 ]0 Q0 y8 |
DIR+:电机正、反转控制正(同样取决于共阴共阳接法). ^1 j4 K. e5 p' ^
) R0 c0 u6 O5 W, a# n8 U$ LDIR-:电机正、反转控制负0 Z3 y: `0 g( n9 G
% |- D& s; Z# i, E4 L6 l- eEN+:电机脱机控制正(可以不接)
- ]4 T" n) }8 O' @ ^# x$ L/ U& O# j
EN-:电机脱机控制负* C0 I" r, D& x
- q$ e7 l$ G! b( j, ~: N" |' x; k二、接线问题+ |; k7 y1 s% f& q! [5 }# X/ |; Z
上面到这可能对它的接线有了一个想法了,那么具体如何接线呢?嘿嘿,这里有共阴和共阳的常见的两种接法,具体参照下图: {/ L- ~' O+ N5 i3 h6 F& \9 q
3 [4 \7 P3 _3 c$ J4 r) ?+ S- S
; m5 W$ d2 n6 p6 ^! a
f7 }3 _3 D6 B* ]1 o D' g: _
7 P+ @& f4 h- S
4 J6 Z: \3 A V V 这里我采用了共阴极的接法0 T* X& r' V8 K8 q5 o( j8 Q
7 Y* d$ J5 i8 q6 @那么我的接线:
u0 t5 ~0 ]1 h, S' |' w7 g, F1 C- R9 l- }" U
DIR+:PA8(随便一个端口即可)
9 l# Y! |9 u) L d: K; W
" W; f! U* M/ s# ?+ c1 f; jDIR-:GND1 K+ a$ e. E, a* U4 _
' b: V1 g: Q5 F6 ~# ^2 P g0 U
CP+:PA1(TIM2通道2)
9 M# {) ?1 V# V( j" r9 R. @9 d8 e2 @! K* l# G3 F
CP-:GND
/ V) S# a1 x5 x0 g, Z; n+ A# o' s$ _* d+ d, D4 G& h& w/ K/ l
ENA不接5 N* z/ ~5 ~% Q* p
- U0 X8 D4 |7 D: z
三、主要代码' y* i+ O. Q3 O
这里的代码搬运后修改一些的,即可上手即可用
% V3 O2 V4 t6 u6 e8 c" ?6 a% W* |' Z7 j, Y3 e
主函数
) u t" l# N' \( q- ^0 r' U9 ~$ E# Y+ I, v: O
- #include "stm32f10x.h"
0 ~% @6 R" k" a' q+ a( k3 ?( ?5 `0 o - #include "sys.h"+ a* U. q- S! N3 T8 o
- #include "usart.h"
, ~+ q. ^, l0 d6 W9 e# v' B - #include "delay.h"0 `+ c% Y( {' p9 G% X; t) `" y
- #include "key.h"
2 g% m4 b; J* W4 i9 m - #include "led.h" 8 D* L) ] ]7 Q1 D' E1 w0 l: V
- #include "usmart.h"
d+ P# ~' c; H& U+ a) T# t. T - #include "driver.h"- n h$ {" v3 n9 k- q. `
+ n8 h9 H7 ^$ t! t; J* l% L- //共阴
9 L( u: B. m6 O6 |9 X3 E - /*1 g: R) I( M; k' w6 m/ Z: Y
- CP+->PA.1 CP-接GND
7 o& I* C0 _8 W5 @9 G7 S - DIR+->PA.8 DIR-接GND
) v9 h) Z' j; _, G, |0 y& F - */0 E, Y4 O, {& m7 l& D
. Q* r. s( `, H1 p- int main(void)
* W ^; r5 D7 \3 ^# u. y - {
. j2 d. | j& i* Z3 I - delay_init();
' E! x4 ^4 g! ?4 @ - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 6 R, b; I+ D" S! C# F/ G3 I+ M# j0 J
- uart_init(115200);
: W4 M Z% k# \$ e) Q - KEY_Init();
- G/ h6 ]- w( C4 K" K - Driver_Init();
: E' B7 W5 q! A( D- B( S6 ~: ~' v - TIM2_Init(999,72-1);
$ G7 c! C( D+ k% D7 k6 n O: N - while(1) $ l, g9 f4 [/ Y; Z- f1 f1 h) s+ i
- {
- m2 d+ a; S/ |2 s - Locate_Rle2(500,CW);
3 I% f( P' ?2 D+ W* ?' b - delay_ms(5000);
* `% Q! }1 T! ]+ C, C' l - delay_ms(5000);2 O2 [- F) y+ a4 r/ k
- delay_ms(5000);1 ]9 d* ~3 p9 e, \: X$ H5 I( @
- Locate_Rle2(500,CCW);1 O. _: _1 M9 [3 h/ Y p: g, e' H
- delay_ms(5000);
7 ]5 g* N& K4 u+ w% k - delay_ms(5000);* V6 _3 p6 r8 L( |+ E9 R7 M2 c
- delay_ms(5000);& m1 l$ i3 a% [2 E7 o Y. b& \
- }5 I3 W6 j3 D! a& `, m
- $ A; Z3 C* b$ P+ e' @, X8 J/ B
- }
复制代码 ) }+ V& V3 S/ ?/ `# h* |$ B
定时器函数:
/ j6 t! j9 G5 `- u$ m" a5 s
: p- ]8 |3 J/ k1 D4 \; T- #include "stm32f10x.h"$ G' H' O0 g4 p
- #include "driver.h"
$ E6 B( Y( l& j7 [, l0 l - #include "delay.h"
& b% U0 h1 P3 g6 v5 p - #include "usart.h"; u" s* K- [+ g8 b
( Q: R/ _9 ^$ c$ s0 G0 ?3 Z! o- long current_pos[2]={0,0};
2 D) q+ y$ ]9 }2 S W! @ - int motor_dir2=0;( }" t; b4 }/ k2 A
- u8 count[2]={0,0};
3 _/ j4 s1 m5 ?5 B$ `2 B0 W2 Q: i
' ?: ^! {) ~$ z! z- void Driver_Init(void)3 c: q& T9 ]# g+ I q+ y
- {" F: Q1 m' P$ F$ F5 `
- GPIO_InitTypeDef GPIO_InitStructure;
. u( K( r- \4 H3 }) w6 u8 k, s( U+ y
$ v4 _# m+ |+ f9 P- O" d7 z- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
+ B8 s' U; f* ~2 Y3 q- c - 9 m$ y" I, T$ \+ g
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
; t7 _3 c# ~6 W4 p5 k! b, D! C* q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
+ a9 ]- [/ n4 t/ e$ \' k' F - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; $ u* p- a* \9 W4 B. Q/ t9 m5 e$ i
- GPIO_Init(GPIOA, &GPIO_InitStructure);
9 y$ F; m3 [( }1 K8 k( u - GPIO_SetBits(GPIOA,GPIO_Pin_8);
7 K) a9 p3 Z Z$ N - }
; b! N7 f. {* ]( j6 S1 v8 l - # P. J; d1 F3 K: w
: H, K5 ]% ~: }! i% W7 F- void TIM2_Init(u16 arr,u16 psc)
, I* e6 F' w9 h - {
" [. d% O. t9 o1 F) e - GPIO_InitTypeDef GPIO_InitStructure;
3 ?. a& I1 z1 x' d, @! }3 L# M" t - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;& F6 \* ~: t% T3 Z& K8 ]; P
- TIM_OCInitTypeDef TIM_OCInitStructure;
: U, J5 z0 y" ]9 s3 K+ l - NVIC_InitTypeDef NVIC_InitStructure;
/ _/ g; P- \7 ?7 T& u% W& R2 a1 h3 n9 u - : s$ A5 F6 O6 x- r4 @' L
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
7 G8 h8 s+ P0 o9 | - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
* h; W+ K7 G0 V4 L
3 @# ~5 A/ S( {: \8 b- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2_CH2) q* {8 ?& B& {
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
9 L- ^8 k; Q+ u3 A! e0 Q* h# z - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;. \& }: l2 P; [) q! u
- GPIO_Init(GPIOA, &GPIO_InitStructure);% \. D( y( ?( w
-
" i+ y n, Y: x6 c( o' H$ ~( { - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
3 z' u; L' Y! \& _ - ( p% w( x2 ?; e- g
- TIM_TimeBaseStructure.TIM_Period = arr;
9 Y8 ]) [4 G2 y- u2 l7 H W/ V/ E - TIM_TimeBaseStructure.TIM_Prescaler =psc; 0 T! R6 i g5 ]* v, p6 o% Q; q( K
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
& M' ^4 W$ T& N% t8 x" E) N - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; + e; h8 `; J- C- o e4 e
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); a Q: J# J4 r3 _9 Q* g
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update); " k& v' x1 a# f# ]) o* x% N" k
- / y" Z! \1 k$ I6 |0 p
- TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Regular);
& S6 D& v8 X* D8 O5 J! V0 j - TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single);
! i; Q: ?) y* l2 N# a+ q( w9 X - TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 7 F: R, g! O% k; i: x' v& v0 B
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- i( G1 C- d; `! | ~ - TIM_OCInitStructure.TIM_Pulse = arr>>1;
7 n/ @4 @) a `; W - TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
% Q5 j* z4 s; Z$ b# | B2 L1 D - TIM_OC2Init(TIM2, &TIM_OCInitStructure);
( d2 V' D- C3 C: s$ \9 l
5 q$ ~- W( ]; p: {7 `- TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); ! n8 ?+ h- e, k' M* s. w4 e
- TIM_ARRPreloadConfig(TIM2, ENABLE);
) s5 f( P# C r - 1 S" @! T5 Y& m: i7 N. ^9 s: ?5 ]
- TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);
) e! H; m/ X7 _% Y" _! b0 R8 r - - l h4 A. b! [: |* N9 k
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
4 Q$ B; i1 e4 G( a2 V- I - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
' A% ?( ^ T# k$ h7 C - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; ; N0 L5 p1 R$ x! T
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; , n9 p2 d; u( E1 `6 ^
- NVIC_Init(&NVIC_InitStructure);
* \8 c5 f0 P2 S( k& q - 3 ?0 p" |5 f& ]. K$ \
- TIM_ClearITPendingBit(TIM2, TIM_IT_Update); , K9 a2 r n( Q
- TIM_Cmd(TIM2, DISABLE); ! k% m" D! C2 m5 |2 V+ J3 D
- }
2 `# Y, F. A4 j7 m - /******* TIM2*********/" B' x& _9 n# k1 s: ^/ Q9 E! u
- void TIM2_IRQHandler(void)5 Z" ]0 z4 x. B* f5 \: l g- z7 w
- {$ f: x9 j9 _9 U* E' }% ]
- if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)!=RESET)
' u3 x8 k& M( B, V - {
& ~! H5 t t' u - TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update); $ s0 Z+ |- E9 Y/ J( M$ S2 e
- count[0]++; ) T# I0 I: o+ J+ h, e2 u8 T( G
- TIM_GenerateEvent(TIM2,TIM_EventSource_Update);
* u1 P! V0 ~# s$ r9 l -
7 M! m8 ~; M; t0 f - TIM_Cmd(TIM2, ENABLE); ! Z/ _& O% b" t! H/ q/ x5 r+ N
- H/ h# a& B: {- if(count[0]==200)
! l3 A2 v$ m% L+ G' j3 [ - {# |& |+ @; p. u; s
- if(motor_dir2==CW)
. B0 W# }0 ?! N& |6 J* Y. o# i$ s - current_pos[0]+=count[0];
/ p0 M0 }9 n" k* A% S - else + [9 \2 O, @# }' N6 h% Z, J5 l
- current_pos[0]-=count[0];
2 {9 ?) P5 R& J! k Q - TIM_Cmd(TIM2, DISABLE); 3 L# _: \- m7 S ] j
- printf("motor2µ±Ç°Î»ÖÃ=%ld\r\n",current_pos[0]);: j. z6 G1 e% t5 [
- count[0]=0;
' G; v2 n4 _; i1 ]- J) d8 y0 v - }
5 M( B) Q* A5 ^( f1 S - ! K) P3 a1 S H: q7 j5 t
- }
& |" |0 K, ?4 o0 O' K - }
" I& G$ ]% }2 R0 @ - . Q1 u) z3 E+ z; J4 b9 O
- void TIM2_Startup(u32 frequency) ) R9 `/ r+ d5 g
- {
3 |! J! g5 U& B, | - u16 temp_arr=1000000/frequency-1; 0 ~- q( O% H2 y. ]' l
- TIM_SetAutoreload(TIM2,temp_arr);* ?0 f9 |% A; l$ i! i
- TIM_SetCompare2(TIM2,temp_arr>>1); 7 ^1 C* I5 p/ ~* x) H2 f' @: w; _; |% `
-
1 U( {0 B+ I( o) Q# f" G - TIM_SetCounter(TIM2,0);+ o, s% ~ P7 C- t$ p" m) ]1 U
- TIM_Cmd(TIM2, ENABLE); ; a: T: E1 C: q. }/ [
- }) H6 M4 T, N6 X, y7 ^+ [# y
4 e; Y/ v5 {1 k( _+ d$ U, |% ]
2 G5 G* `; c4 l$ X5 \9 \- void Locate_Rle2(u32 frequency,DIR_Type dir) # v* `3 b9 D0 T
- {1 a* u" V$ f5 m
-
1 k0 t+ d8 O2 [ - if(TIM2->CR1&0x01)
* f: _& @+ c7 g' d6 F' x d - {1 [. P0 ^* _, q1 A4 a7 w2 @
- printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
" n. M0 y' x1 r1 L" y0 Z3 `3 X! ^ - return;. v+ L% ^$ d! j7 Z d
- }
0 Z. z& A* |( T- Y$ J0 ?1 P - if((frequency<20)||(frequency>100000))
3 E9 T3 V% R8 H+ v: [# z7 ]2 ~ - {+ }- u8 H- X8 S( v6 G
- printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");% S5 l- @% J* Q% D) Y u, u
- return;
- _ c5 }, V: c8 A2 K* h2 d. y6 o - }( I+ ^: r, d7 O' P. D
- motor_dir2=dir;
& E9 w9 Z- o7 {7 T -
6 j. C+ U! V( S - DRIVER_DIR2=motor_dir2;
7 O; T& M! u. G! v) _# u) O - TIM2_Startup(frequency);
* c. S4 V! M2 o" B5 ?- q2 ? - }
* N4 ]) S# y" t' Q4 N
复制代码 + {' Y* E0 ^( L/ L6 t
到这里你就会发现其实原理还是相当简单的,剩下的也不再深入了,希望能够对大家帮助哈哈
; t: T& I& w" \, @
6 P* [0 x& Y- a; Y5 ~2 F实现目的:
3 K/ ?( t1 _: X" G! `5 _0 @, ]# q: U2 }1 [
该程序就是实现正转后隔一会再反转,大家可以根据自己需求设置到自己想要的转动情况,同时要让他停下来,只需要在自己需要的地方设置一个TIM_SetCompare2(TIM2,0)即可停下,可以自由设置。) G: T/ ?7 N, z! I8 S, B) g
/ C8 Q; s' C7 h- D% q四、总结
2 [8 V- F2 f$ n# v4 E& U) ?; J今天关于步进电机就暂且介绍到这里,后面有需要会再特别介绍一下,文章写得还是比较简单,相信对于你还是可以很轻松入手的
, [0 W% Y" x3 | c& i7 z. P/ v( D# w" |4 u* ^4 P2 e
& g5 O1 [. {6 ~. v. p
|