一、舵机的“自白”$ g; x c: d4 @# E& ]% s
我(舵机)是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
( s/ a: b+ }$ `1 e: r: w. e$ S. \$ x, k4 H7 \4 [6 |; P. D- v( h
那么问题来了?我们用舵机来干嘛呢,当然是控制方向了,如今,基本上飞机或者智能车又或是机器人等等都会用到舵机这个东西,所以说,认识舵机,并且运用舵机就成为我们必不可少的知识学习了,下面附图:
; d' \; _6 j9 @; t
; x5 A* H' F$ c, L1 [$ }" v; @5 K- N+ q
# K( C% a! P l% q1 O0 g! ?$ a0 U8 r" Y7 X, e+ ~; R, x
这里我用的是S3003舵机,其他类型的舵机应该也是大同小异。
# u( I- B: j" g% K: c
2 L1 U: t0 L: x其中,有三条线,一条接电源(5V即可),一条接地,最后一条接控制(即单片机输出的PWM控制),下面会给上具体实现代码,总的来说跟上一讲区别不大,主要就是PWM周期输出控制,利用 TIM_SetComparex() 函数来设置占空比实现,但是多出的是计算问题,因为舵机有对应角度的时间计算,下面具体讲解:% P6 T z9 A/ x# E8 t
3 c2 q8 L- ^" C+ f舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度为例,的其控制关系是这样的:
. c6 L. W. v& T# l! C1 l3 }& H* e3 n8 D8 o: t/ d7 M: v9 ?
0.5ms--------------0度;
; A: `6 J* L/ ^8 B8 w+ E( b( O5 c% Y4 o+ |
1.0ms------------45度;
! O) e7 D) S5 d, U: b3 d' q9 Q+ p8 C5 l
1.5ms------------90度;
7 Q7 Z7 ~) ~2 P/ P4 U. L+ R0 ~0 z/ O! H0 X( Q$ H
2.0ms-----------135度;
) |) X1 f }9 j1 ?& V; o" a0 i7 B8 ?' `
2.5ms-----------180度;/ A7 t& U/ `( H
4 w3 {" Z& q7 V/ x& Q7 r& G基本上,我们学生党所需要的舵机的控制角度对应就是上述关系了,至于360度舵机这里简单提一下,主要是我这个舵机做不到(哈哈哈,这舵机180°的)
2 D5 M% o d7 Z; b7 h# Y/ @ ^" G( g5 P9 b, k3 s) T* G( A+ e
这里讲一下360°舵机的 ' W5 u: C) H- X2 ]) a- W
+ p9 s+ s, @+ u! s2 V% m, ]
0.5ms--------------0度;正向持续转(最大速度)
3 y6 b3 {8 p4 H% E# l" M, ?( T& D$ W5 y2 b% r7 D5 U0 `
1.5ms------------90度;停止转动,速度无
9 U, y- t) s6 Z% L/ z& j. g6 C: t* W$ e. M( s
2.5ms-----------180度;逆向持续转(最大速度)
7 o# t5 ~! U3 |4 E# q3 D$ A5 t9 ?# o
调整PWM周期即可改变转动速度和方向。 ) Z X' `# V* x+ Y% g# {
5 e; s! h9 y7 N; H言归正传,到了这里基本上对控制舵机角度其实有了一定概念了,下面就直接附上代码部分了: L. C: r% l4 [6 }+ @; g
" J7 u" n; ` s M+ z3 u
二、代码部分
2 c! H# L; a9 W+ c- #include "sys.h"
6 X7 j0 Z7 u, w% s9 O - #include "duoji.h"8 L# o3 ?* G4 w' X# ? \& ?6 o$ o
' ~3 W4 B- ~- Y- void duoji_Pwm_Init()
* ?3 X0 H/ n" ~2 H - {/ n" Z, N; \; q: X8 ^: d. i
- GPIO_InitTypeDef GPIO_InitTypeStruce;: |! `$ V: [# i9 Q
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruce;
" m1 l k: z( J$ \1 J* V; Z - TIM_OCInitTypeDef TIM_OCInitTypeStruce;+ n& ]+ z2 L4 v8 |. d1 \6 O/ y Y
-
- a( h& h/ [- @( E - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
6 ~0 z+ v0 v& x - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);1 N6 q5 I) Y+ K9 I3 q
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
7 f: x* h7 ^4 v" K! n9 Y5 I -
8 I/ `( Q# S( F - GPIO_InitTypeStruce.GPIO_Mode=GPIO_Mode_AF_PP;/ l0 R! J: `* I) E$ f/ v. D
- GPIO_InitTypeStruce.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//这里是我之前的代码,主要是控制到4个舵机,这里大家只用一个输出口即可$ y. I, J# E8 I0 L: j8 O4 n$ L# n
- GPIO_InitTypeStruce.GPIO_Speed=GPIO_Speed_50MHz;4 V9 T6 W4 c; K( R
-
$ X& `: H0 q6 U z% L: F% | - TIM_TimeBaseInitTypeStruce.TIM_Period=1999;//这里是自动重装值设置
0 P& A j: y6 X' H - TIM_TimeBaseInitTypeStruce.TIM_Prescaler=719;//这里是预分频系数
( @& Z1 x: p( T8 J1 X$ d - TIM_TimeBaseInitTypeStruce.TIM_ClockDivision=0;) K4 W; [5 S6 ]! S
- TIM_TimeBaseInitTypeStruce.TIM_CounterMode=TIM_CounterMode_Up;3 O8 x. I+ J/ U/ v4 z
- 6 X) i* [7 L/ a& Z# }
- TIM_OCInitTypeStruce.TIM_OCMode=TIM_OCMode_PWM1;7 A1 u7 n+ W% ~: ^
- TIM_OCInitTypeStruce.TIM_OutputState=TIM_OutputState_Enable;4 b" Q7 P5 x. ^
- TIM_OCInitTypeStruce.TIM_OCPolarity=TIM_OCPolarity_High;
n1 m( b3 h. K6 A6 U/ Q - , Q4 u5 N6 U, e, _1 g; g
- GPIO_Init(GPIOB,&GPIO_InitTypeStruce);( E+ w$ Q" O/ }- a a3 b
- TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeStruce);, C6 G( b+ }, O4 O, ~& k
- TIM_OC1Init(TIM4,&TIM_OCInitTypeStruce);, q: U" {( s# @/ e+ l
- //TIM_OC2Init(TIM4,&TIM_OCInitTypeStruce);//这些是TIM4其他通道初始化
9 W3 |' }( z5 J- f- \ - //TIM_OC3Init(TIM4,&TIM_OCInitTypeStruce);5 S# a5 G! g# q" v# a C) u
- //TIM_OC4Init(TIM4,&TIM_OCInitTypeStruce);
( l( y: x; b4 p% C - " t( k# V& W& F) l+ h& m3 R
- TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);- \. `- n4 E4 v& o) f
- //TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);+ \# F' D+ W4 F( K8 ?
- //TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);; c& K( V* B7 i
- //TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);. }5 G6 M0 d* |+ a1 @: b' t
- + d y! [0 D2 e5 s, Z' K0 K
- TIM_Cmd(TIM4,ENABLE);2 _3 O$ R- v. j% I1 o- ^
-
5 C7 P- } z9 N/ w1 ` - }
复制代码 0 h \/ P% K6 x& d% k
主函数部分, b8 L- W: l8 e7 v/ D& `3 R
- K6 r5 g# e! ?2 b8 H% {" k( L- #include "led.h"
/ Q) t6 w, i! }: I9 W - #include "delay.h"
3 |: o( R: t' Z2 V/ ~" i! `! C - #include "key.h"- h9 o3 t3 t+ D5 y, {
- #include "sys.h"3 ^# ?! a% o& |: H5 f+ M: r8 A
- #include "usart.h"
7 F2 y7 t6 A/ ]- Y: E( B, } - #include "duoji.h"" d/ p" E' c% J4 l8 }6 p* P M
- + \2 X" b2 x' D- W1 o+ G8 G. C7 k1 z
1 G1 g0 E2 K2 `: t- int main()- U k8 [ R0 H
- {( r# g$ a) m) X* \. J% r
+ H$ B) q* }5 s F& W9 K' U- delay_init();
. Z: \8 Q) Z! E1 s1 p2 ` - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 4 r! M; n0 p; z. |6 z
- uart_init(115200); //
2 [& {; _2 l. [& B - LED_Init(); //
5 c$ p3 o" m: Y+ j - KEY_Init(); //
- m& G0 l" @# P7 a& h" S: w - duoji_Pwm_Init();
, V# |0 k# N7 G% p/ C* L - while(1)+ _6 J1 R9 N; S0 k, B ]
- {
. I: j- v6 U: O' |+ q+ H - LED0 = !LED0; % Z, p9 F" C( F! t. g
( I5 J1 k7 p [) J/ d- _6 ~- TIM_SetCompare1(TIM4,50);//这里设置占空比改变角度,用TIM4定时器,可以自己更换
( I5 C: n# c( U: [ - TIM_SetCompare2(TIM4,50);" Y: h- [+ ?, O: j
- delay_ms(5000);# ~$ U3 P. F1 D) G3 F O
- delay_ms(5000);# f, l: `, v' r- _7 W! {
- TIM_SetCompare1(TIM4,250);
4 t K( y/ T# P8 s- ^# O3 k - TIM_SetCompare2(TIM4,250);
" ?" ^* o8 ~3 H - delay_ms(5000);3 B2 Q6 E; j0 k6 b/ V
- delay_ms(5000);/ o0 {% m* w* _5 @0 @% o
-
; |4 P; L' \% g8 o - }) |5 L4 K% W( a
- $ C1 `/ U# t* }" d5 C
- }
复制代码 + ^% r: ]% n: H; s+ r/ z
这里的代码是其他地方用的,拿来简单修改一下而已,基本上就是这样了。
$ N& g, [. k q
' [& ~' O' b7 R& w3 b: T. [* a: _三、如何计算得到该要控制的角度: g" Z4 O( q3 m1 f% s6 E% y/ B
这里直接上纸描述,字丑谅解哈哈哈8 y& H( b6 v) R
4 ]- N; P- F2 Z l& k$ \& q
, U, i) z! v( k1 R) c7 S3 g* r; L p9 H' K2 j
其中的arr和psc可以自己设置,再计算出相应角度的占空比值即可。大家可以自己调试一番,定会有所收获。1 Q/ t3 f9 q& k- T
5 Q9 o0 w7 s: T5 C) z* h' a0 S( n" R/ B) @7 L: t. V2 D E
|