一、舵机的“自白”
7 W/ P- I8 w' R我(舵机)是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
" i; N9 N; G. L4 N' b8 S% m `" D# j5 Q; A) l( b
那么问题来了?我们用舵机来干嘛呢,当然是控制方向了,如今,基本上飞机或者智能车又或是机器人等等都会用到舵机这个东西,所以说,认识舵机,并且运用舵机就成为我们必不可少的知识学习了,下面附图:
9 I( d+ x& J$ f, A! Y% \
9 b3 b- {4 t+ U( ~; N" V
- }- h/ e+ C! f& {
, p2 ~ i1 j# F9 ~! d' a: F8 [) ]这里我用的是S3003舵机,其他类型的舵机应该也是大同小异。
; `& `: D& L$ u. U7 L g# x# m3 N! k T8 q) K* V2 n X- T: t
其中,有三条线,一条接电源(5V即可),一条接地,最后一条接控制(即单片机输出的PWM控制),下面会给上具体实现代码,总的来说跟上一讲区别不大,主要就是PWM周期输出控制,利用 TIM_SetComparex() 函数来设置占空比实现,但是多出的是计算问题,因为舵机有对应角度的时间计算,下面具体讲解:. S5 K( R" n e* u. `1 H
# Y/ w6 X- n) R) G) L l2 _
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度为例,的其控制关系是这样的:7 w5 P" r; E! b J: K g5 n6 q
( g2 w( j( d4 u" E4 _
0.5ms--------------0度;
9 O0 H2 t9 G! |8 q% Y% v7 f
& @6 i/ e4 V* f& A& x4 f- m 1.0ms------------45度; o+ k- ^" Z7 k5 o- B1 J
9 z& U( @# `; O" I7 @7 T% G 1.5ms------------90度;/ e; x% X3 v/ W$ T
9 f) G" y* n7 X* |& u
2.0ms-----------135度;. n$ R! c5 Q* G# `1 B
. x( t0 v4 `+ K% [% q. d6 _& P
2.5ms-----------180度;
& m: X1 e/ S2 d M
4 Y) ^& S0 I" X6 w8 U" T基本上,我们学生党所需要的舵机的控制角度对应就是上述关系了,至于360度舵机这里简单提一下,主要是我这个舵机做不到(哈哈哈,这舵机180°的)
! P+ q! B. u2 J0 o% M. _- Q/ q/ ]7 S C: g% d
这里讲一下360°舵机的 ' y" z! F/ k* E& n
, B5 | J; z$ {1 | 0.5ms--------------0度;正向持续转(最大速度)
9 d1 N9 ?2 {! l) m+ }9 {" D4 g( E) }. U% G0 f5 ^( r1 |. f& \
1.5ms------------90度;停止转动,速度无
/ ^8 Z" j( D. u! @ y* {) a3 Q1 s+ m
2.5ms-----------180度;逆向持续转(最大速度)8 F, e, q9 J) I# Y, D2 r! q
5 n8 p- U* T) T9 y" ^& z
调整PWM周期即可改变转动速度和方向。
4 g3 m3 Q F; e% S* y6 I" b) G1 y! r+ p, U. L% a
言归正传,到了这里基本上对控制舵机角度其实有了一定概念了,下面就直接附上代码部分了5 A3 F( C# |9 N9 B# ~
3 m: s$ T* R; ?6 t7 a* I; q# C二、代码部分$ \" P2 [* v) B. H
- #include "sys.h"
- n' c: F, p7 h0 B - #include "duoji.h"% v1 |# N6 S* P; @7 ~
" ?1 \# g! ]$ ]8 M' _- void duoji_Pwm_Init()
. E, }7 S5 R6 e5 D/ C" I( e - {
4 u6 O; @' A4 M' z - GPIO_InitTypeDef GPIO_InitTypeStruce;" }9 }' ]0 N7 u. Q7 T" D
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruce;
6 t1 Z# }7 l& e* n" O8 l - TIM_OCInitTypeDef TIM_OCInitTypeStruce;; b% i* r; c+ j) d4 E: o" V
- 2 a3 d: Z% u! u- Q! V2 h H4 q3 N
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);" ?1 [/ h/ k- S" d1 B4 T0 e
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
) u8 T: X) N) G% @ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE); i$ I" Y& \5 w1 y* B8 b
- : Q2 m/ D, Q' G- |
- GPIO_InitTypeStruce.GPIO_Mode=GPIO_Mode_AF_PP;
4 h7 [) C1 D9 F. d - GPIO_InitTypeStruce.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//这里是我之前的代码,主要是控制到4个舵机,这里大家只用一个输出口即可
1 I" i; L% N) C; d; } - GPIO_InitTypeStruce.GPIO_Speed=GPIO_Speed_50MHz;
; i) Y8 t! j4 D8 ]# i6 G -
0 A5 A! @! ?4 q! d: P2 L# \ - TIM_TimeBaseInitTypeStruce.TIM_Period=1999;//这里是自动重装值设置
# E- p/ `& \; B1 [, S$ E - TIM_TimeBaseInitTypeStruce.TIM_Prescaler=719;//这里是预分频系数
, m# ?' H: h+ n' A" y - TIM_TimeBaseInitTypeStruce.TIM_ClockDivision=0;
, S* c# ]8 y7 m; R) o$ f - TIM_TimeBaseInitTypeStruce.TIM_CounterMode=TIM_CounterMode_Up;2 J+ K) @# w) E" H. ^8 [$ b
-
6 V& v& _7 \; N7 o9 p - TIM_OCInitTypeStruce.TIM_OCMode=TIM_OCMode_PWM1;
8 d3 g7 |' U- M! e2 A1 I - TIM_OCInitTypeStruce.TIM_OutputState=TIM_OutputState_Enable;8 w3 K; e# g. i7 L& R
- TIM_OCInitTypeStruce.TIM_OCPolarity=TIM_OCPolarity_High;1 B/ \/ u0 I3 f0 p) w/ o$ Q. F
-
7 M- o4 J: U: ?% v& I: T - GPIO_Init(GPIOB,&GPIO_InitTypeStruce);
( `* Q& `* E) L( p6 f+ Z, W6 R - TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeStruce);
) o& c- l% |9 u$ Q' z% f" Y) w - TIM_OC1Init(TIM4,&TIM_OCInitTypeStruce);/ |7 t! f& P- n4 E8 w: E1 O
- //TIM_OC2Init(TIM4,&TIM_OCInitTypeStruce);//这些是TIM4其他通道初始化
) ^' g6 Y2 i$ c$ v9 K3 q1 B: X) E - //TIM_OC3Init(TIM4,&TIM_OCInitTypeStruce);
' A+ o& e3 U: S4 ^' a - //TIM_OC4Init(TIM4,&TIM_OCInitTypeStruce);; Y& _& ~; b% L( O" @& g3 X/ [
-
0 W) w1 ^* F) i4 f$ B6 W* x2 H - TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);- S! w3 S4 e% M
- //TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
" Y3 \. N9 O' R# [ - //TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
: ]0 b4 |: S2 X/ \- @. u0 w - //TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);
- ^/ F2 `% l0 R! T' I, w7 m -
/ E k e8 K6 V! A) A. u4 N' Y$ l- ^8 V - TIM_Cmd(TIM4,ENABLE);
( J9 F" b4 s9 E) w - H3 g; ^/ g4 u+ \& i/ R- L/ w
- }
复制代码
4 R( {# z, D9 b5 c7 T主函数部分7 I9 q4 }" z! ]
2 ]3 v5 I: ]- `! J
- #include "led.h"5 s& H; Q- e1 ^
- #include "delay.h"
" Q! }! n8 V. m* S - #include "key.h"
& ]- H8 ^( j* y( T F$ Y: u9 O) m - #include "sys.h"
5 B8 P6 E H) k+ y0 Q5 t1 y9 O% G D - #include "usart.h"; Z7 \2 d; ?, E m1 d: F
- #include "duoji.h"
7 Z9 K/ o: _# m5 g( f - 3 r1 k4 i$ B- f* Z, h
4 }/ {7 ~! H2 f$ M- int main()
' Y% u5 S: l, M$ F - {! n! X) q8 n; `# {
- 7 Q, R c% ~) S( s% u6 Z
- delay_init(); * D# N5 G5 ^- p9 A1 }
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
! `+ F4 r9 s0 l7 z5 E - uart_init(115200); //
4 ^: E! G5 x e: ^4 E - LED_Init(); //* g% y/ V! y/ _' M
- KEY_Init(); //0 L; f3 e& N9 J; Y' D! R' y S( x# z
- duoji_Pwm_Init();
% U9 \$ D! b& K9 x( A+ r! B5 M - while(1)
7 \/ x- b' M( V0 V - {
) u; e, \$ }$ ^+ A5 M - LED0 = !LED0;
2 _$ `, l9 a4 y- f- J- ] - 4 u3 l3 m) h4 W7 V
- TIM_SetCompare1(TIM4,50);//这里设置占空比改变角度,用TIM4定时器,可以自己更换1 i4 Z/ o b' M) _6 r
- TIM_SetCompare2(TIM4,50);
) l; @% @8 L/ i: X - delay_ms(5000);5 U+ g& [5 ~: W& S0 t+ |
- delay_ms(5000);. |0 K% H/ ]4 t6 j1 b! j+ n
- TIM_SetCompare1(TIM4,250);
# q6 z7 O4 T5 G6 ], |4 I- y - TIM_SetCompare2(TIM4,250);$ d6 p& s5 y( [( h% }7 n) ?
- delay_ms(5000);
8 r0 F2 ]# g! A8 ?- t - delay_ms(5000);
$ y w/ v! ~( ]: w- j - ; a' o5 F& u1 o. h; G" H
- }
0 p9 `: N( n- m# l6 g* a - # X) a+ w, d, H' y
- }
复制代码 & Z' f4 q6 Z; W. _, M
这里的代码是其他地方用的,拿来简单修改一下而已,基本上就是这样了。# m- t' w1 ^& L, ~. j# A
+ G, ?$ @ f& I' a/ r/ }# l) v. ?1 {! J
三、如何计算得到该要控制的角度
- ]2 g& m- i" ]4 P* i$ ]这里直接上纸描述,字丑谅解哈哈哈
: g T" t* C4 o7 N" A" V) Z" g# z1 j a( Y8 `/ q- ^
6 \; L1 B4 u; h4 h- R( J6 i' w0 Y
& w \& a; f8 o$ Z! v0 O! d 其中的arr和psc可以自己设置,再计算出相应角度的占空比值即可。大家可以自己调试一番,定会有所收获。5 P k' M7 _& b: P" s; ] z B
+ @9 e( J1 q5 \ X! F( Y M; f* ^# S+ Y0 h' c0 n+ I
|