一、关于步进电机那点事
9 t7 X& d5 A/ x) f1 C这次使用的是二相步进电机,博客上也有许多关于步进电机的博文啊,质量也是参差不齐,今天就给大家仔细的介绍一下该电机,我主要还是继承以往的风格,资料方面我也讲的少,主要还是侧重实操方向,希望能够带给大家帮助. H: x: m: g$ k+ N. W
2 q- D( J! p3 p: Z! j4 u5 \( w m下面是图:
; f* n( M/ M$ a- ~/ {% Q* n, z* v- j: s9 \7 C4 f! G a1 ^0 h
) A6 `! K' ?# r0 G7 A
; `7 T1 {' s% V, T首先要认识一下步进电机上的几条线:9 Y+ Q9 u4 }. {9 O. y
# |: U- N6 V: A w! P0 q
四条线(红、蓝、绿、黑)7 Q1 A; W5 R c- U6 g( }5 R4 L u% ]
3 q5 B8 g) _, e) X5 x+ e正常来说对应A+、A-、B+、B-,在电机上基本上也都会标明代表含义,其实步进电机的原理其实都差不多,主要就是学会使用和了解原理就基本上达到我们的目的了,如果想要深入学习,那可以再继续研究······: {7 G* l w L. Q$ M4 J4 u& B0 w/ `
% b6 o$ B$ ]1 m1 c1 m
那么怎么使用呢?首先就要搭配一款步进电机的驱动器了,网上随便都可以买到,如图:% A/ C. f0 g# z6 T5 a$ u9 m1 g
( g6 }7 x! i5 g# u( _; `
9 s# c9 T2 R1 Q5 `7 s) i, X2 B1 O8 ^$ j0 b) v& i# f& G. m
这里我们很明显可以看到它有12个接口,这里再详细介绍一下如何使用接口:
9 {9 }$ b5 T( P, O3 Y
5 v: S' v9 A' x( d7 W6 ZV+:连接电源正极(注意电压在9V~32V之间即可,过大的话你懂得)( S5 g' O% k: K L
$ e2 H; J {, j) ^: D
GND:连接电源负极 p: k- f% j$ C
$ o0 Z/ `2 L8 l) TA+:连接电机绕组A+相
5 D2 Y! y% w# B5 M7 H$ P$ u
5 C" O( Z! R) u6 eA- : 连接电机绕组A-相" ~% \9 [) T. i$ p2 u# W+ D7 C
6 k! f/ c# O% D. X- [. D
B+:连接电机绕组B+相
: U) q* h2 d# f0 w+ C& U: u& W/ e' x( G* t, m% i
B- : 连接电机绕组B-相
% W: t8 W8 ]5 H3 g1 B. }
4 J& N: o X6 z: f1 C2 X% QCP+:脉冲信号输入正 ( PUL+ )(取决于共阴、共阳接法再来接线,共阴的话CP-接地,CP+接脉冲信号即定时器PWM输出)
, g9 }8 }/ @" v+ G# k+ z$ k6 o! i( S
CP-:脉冲信号输入负 ( PUL-)( }- {( |" `* D2 \7 v6 [
t( i; }: X, ~! r8 ] R2 QDIR+:电机正、反转控制正(同样取决于共阴共阳接法)( d% D: |. W; H% x8 r" v9 S
) g3 z' {" c; R4 h; |% P& iDIR-:电机正、反转控制负' }9 [* \% y$ ^
0 A( F3 T9 E; J4 D7 r
EN+:电机脱机控制正(可以不接)
/ q6 s- J/ z0 E3 A5 f. ]/ _+ O/ L- P3 U2 N4 p* ?; y. j
EN-:电机脱机控制负( c) ?; `$ f& ? M j
+ Y l: X, E7 g. H
二、接线问题
: t( L; u: k! ~ S+ P8 y: r) V" p上面到这可能对它的接线有了一个想法了,那么具体如何接线呢?嘿嘿,这里有共阴和共阳的常见的两种接法,具体参照下图:
9 g9 |# M/ L1 h. B2 a; Z- r# M
" L, `; S6 _& G& d: ?& ~
1 A& p" e" r! o3 E9 \. I0 S; Z$ J
; q# w; G! Y! a$ v8 {
/ ^8 I* @8 _& ~2 |1 \& L# n$ A
! Q2 r8 W7 l( [: B 这里我采用了共阴极的接法
, d# a/ l. a7 j4 _$ t4 u" C! d1 C) @
那么我的接线:. {6 l1 v* X7 K) K0 H* w: ]
9 k# n# k0 h' x5 U5 k1 t) b7 L/ ~DIR+:PA8(随便一个端口即可)
8 Y1 A( z. i( H7 P: I P# S& Q0 I% H7 f! p4 L& L
DIR-:GND
0 J6 [' P% l* l! {4 X" P K5 Y" t
$ t$ Z5 C- \' J' V* }CP+:PA1(TIM2通道2)6 ]3 g$ A3 O! o: U: e
8 ~7 H d* h2 I. i8 j, O
CP-:GND
% E3 {9 B0 h* i( L" n
+ a8 D9 L/ q8 n+ `ENA不接
( w% h+ V$ n- x3 D" `. q) G+ ]* k0 W- Q9 _5 L! T
三、主要代码
5 O w, p. j* y% X0 R& A9 R这里的代码搬运后修改一些的,即可上手即可用$ N8 n) @' ? ?- M& e
( b6 h1 f: x e
主函数9 _' Y* `) d* N" o+ |
3 c% ~8 S3 {( F5 v3 B) j4 Z) ^) g- #include "stm32f10x.h"9 u9 D* x6 W' h
- #include "sys.h"
/ i4 M& X" S6 j o - #include "usart.h"
! M8 |! A* e2 l8 e8 T n7 l6 n - #include "delay.h"
Y3 o4 O. y& l' H8 \ - #include "key.h"8 g+ q. R" S4 l# m6 `
- #include "led.h"
3 k. W0 G! c- j" e5 n2 C8 r' Q& Y - #include "usmart.h"
$ q/ f+ @( l7 Q4 w - #include "driver.h". D" G4 d/ c6 P$ Y% L4 h1 \; T
7 |: Q( Y- {) L3 J3 H6 t e- //共阴, x9 v* W2 r' D* d
- /*
9 w; Z6 t1 q' G - CP+->PA.1 CP-接GND
- {# X3 A2 N" i9 V/ J" \/ d - DIR+->PA.8 DIR-接GND
# }5 Z3 u6 {* P0 \" k - */
- A ^% ]! \+ z. C
* ~" b" \: \, p- int main(void)
2 ^* U( r2 i6 j T7 N4 X8 w - {
0 e7 |( Y; ^6 s1 K* ^0 a+ K L5 z - delay_init();
' N4 ?2 l" q' B7 w7 \ X$ G - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
, a& p. H1 g0 Q - uart_init(115200); 5 P d7 V$ d3 g! H( t; u r
- KEY_Init();
# i' n$ \; K2 u+ G9 j5 ~" o/ [+ K - Driver_Init();
5 |. H4 N1 \8 ?! P0 _* K# q- Z - TIM2_Init(999,72-1);
4 Q6 P4 g+ o7 e# g. }1 k1 i; t - while(1) 2 l, d& d! \* p: G( e
- { * R5 F; n- [( _3 ]7 n' H
- Locate_Rle2(500,CW);- X5 X8 t8 [- t# a: S# W0 q
- delay_ms(5000);, m' C8 z* W b4 g0 E/ Q
- delay_ms(5000);3 q4 p4 `& b& V; |, @
- delay_ms(5000);
% y1 T) I8 l, f9 _* g2 m+ R - Locate_Rle2(500,CCW);/ D" Z: n1 F6 ]
- delay_ms(5000);
2 ~. f9 e( `, K3 O8 T - delay_ms(5000);
, p: D) ]% _0 @0 L4 ?) j0 C - delay_ms(5000);0 H$ l! t3 r# D# E& E
- }
3 Y3 e- F1 ~- H# n( r - ( l; ~% B+ J! [7 q" G
- }
复制代码 3 F8 g3 ^1 c9 u6 i- Y: L
定时器函数:8 a8 j2 ~7 s8 L# h6 W& K, K" v% t
. O: [$ ^) z; |8 e$ B' R- #include "stm32f10x.h"0 Z, s: Q! @/ u- G
- #include "driver.h"
1 `! V4 O2 b- D2 Y! [: P4 s' V' z - #include "delay.h"
u, ~( ]( j9 O$ Z3 Z4 H+ ` - #include "usart.h"+ Z* i$ @3 n0 ?, e
$ |: @' b6 P* q3 H: }) x- long current_pos[2]={0,0};
9 w. m* w% }8 f, ~* l/ X: [ - int motor_dir2=0;4 E/ h0 V1 i9 M7 ~7 |
- u8 count[2]={0,0};( }6 F* S& A D% f5 ~
3 P+ H: f3 Z8 C% o5 p- void Driver_Init(void)0 }6 R8 z1 f8 t6 P* U: \
- {
0 ~# E7 y% L- V - GPIO_InitTypeDef GPIO_InitStructure;2 A( p. \, `' Q
5 r3 a9 `2 M$ D# k- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 8 T- d! Q) g/ M8 I4 G
- 0 j* }% j" O9 U6 ?: {. w
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; $ O6 O# V8 f# m2 v
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 9 H4 b# o3 K+ _+ ~+ T# |) ` P: O( K0 |
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
; h0 f3 A) s T! n9 ?5 ] - GPIO_Init(GPIOA, &GPIO_InitStructure);
0 d3 u. D* n3 `( w- i9 o( v - GPIO_SetBits(GPIOA,GPIO_Pin_8);
/ [$ d# i. o# N& l L - }
/ W: o* k8 P2 S* |& v - % Y* h) C8 C5 R+ b+ q2 X
- 8 R" W6 t* m, _; f1 z4 _
- void TIM2_Init(u16 arr,u16 psc)) W( K) W" M, I5 ?+ e
- { 3 Z) t* v% I0 a3 @/ X7 p5 F2 i3 l- i% q' q
- GPIO_InitTypeDef GPIO_InitStructure;1 _( R2 o0 D3 g& U# F
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
7 O9 z* J" T/ ?, N& [$ D - TIM_OCInitTypeDef TIM_OCInitStructure;
4 S3 J7 O1 N* e6 \' j. | - NVIC_InitTypeDef NVIC_InitStructure;
4 c2 m9 A3 z. T) S' a: a/ b4 a% y - 2 ^& c2 F: v. E! i5 h
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 3 W m d% k" ]* ~3 j( t' w
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); # A9 q/ S# }5 f }. _ V* A
0 E' c! `3 A$ f+ h% ^$ O7 \" ~9 \2 _- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2_CH2
0 y' j/ ~8 N& s5 h - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
; l* [) L& O4 g, t; O - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
! z- V6 y6 x) l" d9 f% w - GPIO_Init(GPIOA, &GPIO_InitStructure);
4 G8 a; k) H2 k5 L8 f - # N/ u9 d1 U4 A. n& y5 U* g
- TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
% l. l, _+ X0 C5 }+ F2 g -
- S. V; ^0 s: Y# ~ - TIM_TimeBaseStructure.TIM_Period = arr;
! t1 {1 p+ d) H# m - TIM_TimeBaseStructure.TIM_Prescaler =psc; / ?5 B: j9 }2 T9 B8 C" N
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
8 v( S- p8 K0 r9 g" C0 G! @ - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; 4 q5 }6 a) t6 I4 J7 j/ n& @6 w
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); . |! u; ]$ y2 t; C
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
4 ^1 W: ^1 L9 u8 ~- o1 ^* u - m) f/ S. |4 ~5 i% J6 G6 \% z
- TIM_UpdateRequestConfig(TIM2,TIM_UpdateSource_Regular); 3 o- Z8 M% h9 R3 d8 S
- TIM_SelectOnePulseMode(TIM2,TIM_OPMode_Single); 2 h" N | y' ^1 E O2 N' {( U( F% q% f
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; / Y0 \- V( o1 v: ^. W2 T; Y
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
1 x& O2 W+ m9 c - TIM_OCInitStructure.TIM_Pulse = arr>>1; & h% ]2 Y. o ~5 m# P
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; / T" L4 B2 e' c
- TIM_OC2Init(TIM2, &TIM_OCInitStructure); ( n7 O$ ~1 _/ [8 S; l
- ) E0 G W, l: M7 o
- TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); 5 L. U/ }8 `# i# z( r# v
- TIM_ARRPreloadConfig(TIM2, ENABLE); ; M- J+ G4 K b. C
-
' ~* U; T$ a2 y& i' z - TIM_ITConfig(TIM2, TIM_IT_Update ,ENABLE);
9 s( p' D+ v: v
0 Z4 i2 L: z9 h. w* ~, j& S. a- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; $ Q% }# b ^) Z9 z5 l
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; / \- A! `( ?/ ]
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
+ f ], A- E5 H# w2 V" E- c; S - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 8 e" B4 H. Q" b* b6 Z
- NVIC_Init(&NVIC_InitStructure);
1 B5 l6 v! T/ c: V -
9 N/ }* i+ K6 h4 r# s - TIM_ClearITPendingBit(TIM2, TIM_IT_Update); 4 Q1 ~- u% w! `" S! V! F H
- TIM_Cmd(TIM2, DISABLE);
2 y! i8 q" w0 Q* o3 A - }
# |" x0 R8 U& C8 j - /******* TIM2*********/' [9 ?$ h+ i0 x9 ?
- void TIM2_IRQHandler(void)
2 {) s0 H! \# ^# z& D% g& M; T - {
" G6 X V: _+ I4 M - if(TIM_GetITStatus(TIM2,TIM_FLAG_Update)!=RESET)& b- b2 ]8 n3 X7 D
- {
9 n! G7 U+ X2 m" ]6 M; y - TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);
3 H8 `1 t+ r$ d1 q* S9 y0 U5 y - count[0]++;
$ j( I# E/ N5 n - TIM_GenerateEvent(TIM2,TIM_EventSource_Update);
' l5 d8 z6 K1 A" x -
! Z& W# R2 p* o - TIM_Cmd(TIM2, ENABLE); " a9 k6 {* z0 V. @/ Q5 D2 t8 ^
- " ]* U F% m* j1 G+ N
- if(count[0]==200)2 `6 N2 \ D0 I: F2 M4 A) Z5 F
- {- S$ p6 K& X# j$ s) Z3 p: L
- if(motor_dir2==CW) ' ~) t) O; ]8 {0 {1 \( D+ r
- current_pos[0]+=count[0];
6 W" K0 n9 Y4 P# C' M' | - else
, r( I8 z2 m X! b, ]9 c) P3 s - current_pos[0]-=count[0];2 n: x6 k2 A. ^+ k
- TIM_Cmd(TIM2, DISABLE); / M5 d; n, \+ \5 k6 g
- printf("motor2µ±Ç°Î»ÖÃ=%ld\r\n",current_pos[0]);" f/ e+ _, D& D* G f
- count[0]=0;
O! i! f) ^. u+ @* I1 o - }
2 Z9 p0 p9 X! g4 A/ [ -
$ e. P3 J% h, M* p: Y - }4 g" T- N! j& Z) ~3 Q; e
- }
# M" w% Y( O! Y; @8 s) d
' a, Y% `$ z2 y- void TIM2_Startup(u32 frequency) 1 X3 G9 c3 i3 S3 Q( h
- {
; W7 D1 o& ~1 s! ` - u16 temp_arr=1000000/frequency-1; 9 u8 Q. X$ K0 e2 Z# p
- TIM_SetAutoreload(TIM2,temp_arr);* o. {! D8 v2 q, D0 ^+ P% O1 m
- TIM_SetCompare2(TIM2,temp_arr>>1); 2 a! V+ J R+ c- S* {2 U
-
^( p6 q% ?& d# a# O0 q, P" ?, J - TIM_SetCounter(TIM2,0);; p7 q3 Y% i7 p) u. @
- TIM_Cmd(TIM2, ENABLE); ; [! ^4 D2 Q% q. a
- }& W$ p1 C' [* O. v
# C* d/ [% d0 s- ?8 ~
' w( A3 I7 p# F; d& A& {7 w0 w6 p- void Locate_Rle2(u32 frequency,DIR_Type dir)
" |5 `# j5 e$ \. Z9 ~& A! O0 _ - {
% K& S) `! p- E! G4 |5 w - ! y- j( l) ?/ j8 \) [9 Q+ Y! `) W
- if(TIM2->CR1&0x01)
6 B! b# N8 l8 O1 R - {
& r# Y: i7 k+ s' V$ e: b0 D - printf("\r\nThe last time pulses is not send finished,wait please!\r\n");
$ H3 Q- M3 C& m( Z - return;. s% w! u+ d, j- {
- }% \4 d5 c' p0 o( K# B* n& X% e
- if((frequency<20)||(frequency>100000))
. a3 X, v, H* {: w+ S( ~ - {2 g- A$ b- S' s) w. T
- printf("\r\nThe frequency is out of range! please reset it!!(range:20Hz~100KHz)\r\n");( X' `2 c# w9 X) @
- return;7 G/ Z! X! m+ }( f/ u- j0 B0 k
- }
7 J/ E J% G+ [" V# p9 ~% t - motor_dir2=dir;2 f" r. d$ {2 T9 p' q) ?
- ' t5 k+ u) \0 J) a
- DRIVER_DIR2=motor_dir2;
8 u+ e' I$ B% T! U5 V% W7 A; e2 s - TIM2_Startup(frequency);
; T$ n- c7 q0 R6 w - }0 l) o" E3 a) U; l) p. X/ y
复制代码 # P) `0 V# a6 ]5 P8 m7 ~
到这里你就会发现其实原理还是相当简单的,剩下的也不再深入了,希望能够对大家帮助哈哈
5 q/ e( n- y: H, ^
; R& {. ]( v" u0 f5 `实现目的:/ J2 y( t$ F' ]1 H- D: z
: G1 x8 M, y2 p. y& ?该程序就是实现正转后隔一会再反转,大家可以根据自己需求设置到自己想要的转动情况,同时要让他停下来,只需要在自己需要的地方设置一个TIM_SetCompare2(TIM2,0)即可停下,可以自由设置。
8 f9 Z: @' i8 ]/ P9 Z( R
3 `; C0 ^- i3 N. p4 F; m, P四、总结: n1 x5 j& ?; U: `( i+ F
今天关于步进电机就暂且介绍到这里,后面有需要会再特别介绍一下,文章写得还是比较简单,相信对于你还是可以很轻松入手的
2 h& U3 u3 P0 [6 E% u3 m) I
1 `4 b# [2 g/ w+ N' F9 n) ?/ o- y
7 U% v$ @# M% u* m/ z: T |