一、舵机的“自白”+ \7 C/ d" x0 M. d7 y
我(舵机)是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。: B2 o- M1 ^) X& [" j- j& B
& a$ a. y/ M& D' i* I I$ }1 ?: t那么问题来了?我们用舵机来干嘛呢,当然是控制方向了,如今,基本上飞机或者智能车又或是机器人等等都会用到舵机这个东西,所以说,认识舵机,并且运用舵机就成为我们必不可少的知识学习了,下面附图:; I/ `; c/ d% i1 Q6 J1 Z. G1 d: q4 y
0 @7 f, |/ @1 w! C: o7 E$ I7 a
2 f' |& o* ?9 K8 R, q
. q: B1 {" @8 Q, X这里我用的是S3003舵机,其他类型的舵机应该也是大同小异。 , W6 s2 M- Z- h7 ]* E- }& @* U
, V: H3 Z7 \/ Y# q) q
其中,有三条线,一条接电源(5V即可),一条接地,最后一条接控制(即单片机输出的PWM控制),下面会给上具体实现代码,总的来说跟上一讲区别不大,主要就是PWM周期输出控制,利用 TIM_SetComparex() 函数来设置占空比实现,但是多出的是计算问题,因为舵机有对应角度的时间计算,下面具体讲解:
/ _' V6 Q5 ?6 z3 ]6 n% s3 x& @% t; Z& ]" E% g+ Q/ P
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度为例,的其控制关系是这样的: S% V8 ]9 c4 N9 y( U
/ {7 g" @0 D& f' _
0.5ms--------------0度;+ {. Y+ s; A9 u$ ^, `6 n5 `1 V
, d1 M1 C# k" S- @! e( Z 1.0ms------------45度;
- M, T( W& d/ q* U2 i0 ]
. C# K( P G4 h) T$ l; w8 W 1.5ms------------90度;
+ l9 k4 Q' w* j, c8 y
& x' I2 Z: q6 c7 Y E5 j; V2 C/ p 2.0ms-----------135度;$ v; }4 S$ f7 x3 D& x
3 n# V& S, l; T$ y 2.5ms-----------180度;
, W* W( J* \) W5 z5 c2 d. N) m" L6 c g/ }' n+ }
基本上,我们学生党所需要的舵机的控制角度对应就是上述关系了,至于360度舵机这里简单提一下,主要是我这个舵机做不到(哈哈哈,这舵机180°的)
* u& f% o% N% Z/ f- |, u- H
+ F9 }2 O) F' W9 V3 W& ]7 y这里讲一下360°舵机的 & I& s8 ~- ?2 s' g$ H
1 I, G: V1 y; S$ N 0.5ms--------------0度;正向持续转(最大速度), d8 k+ p% e" u9 D Q5 \# c" j
2 `) O* {9 N) K. u
1.5ms------------90度;停止转动,速度无$ |- m7 d6 x5 d
; A4 w7 X, M; [2 `" Y$ E- \4 w: Z& X4 I7 Q
2.5ms-----------180度;逆向持续转(最大速度)
8 {5 X+ y% P/ `
$ ?+ P( t' w+ @5 e# A/ b8 F调整PWM周期即可改变转动速度和方向。
5 p9 H, R; ~4 J" W0 @1 F$ `7 Y9 h& N+ u- x
言归正传,到了这里基本上对控制舵机角度其实有了一定概念了,下面就直接附上代码部分了! n& T" w3 Z% {3 x
' Y" |! k- W- F! l4 L8 C* [二、代码部分/ W) I0 M/ j: y. d- i- T+ g/ D
- #include "sys.h"
9 I& A( [2 U9 d3 W; p- L6 z, K; F - #include "duoji.h"
4 D5 a. K/ k B( I: D- [
9 V" x: c: h+ g& B) z- void duoji_Pwm_Init()5 e6 ?5 t* ^7 V, g5 H6 f5 \9 }
- {; {5 i9 ?3 b* p, {) i% h0 b D
- GPIO_InitTypeDef GPIO_InitTypeStruce;6 J, h3 J, d7 F
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruce;7 S/ i- a! J# i. n. Y
- TIM_OCInitTypeDef TIM_OCInitTypeStruce;
5 W, O1 Y, u- F& i! ]7 j -
8 _9 u. K# D: Z; x3 c - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
/ f, d7 a: s+ Z2 U - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
3 ?( q/ B3 H( }! ^ - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
: R8 k+ U M% w- {6 X - ; j1 [3 g5 J* v2 [; s
- GPIO_InitTypeStruce.GPIO_Mode=GPIO_Mode_AF_PP;
2 }4 J2 A6 I+ [3 Y, W( A: F - GPIO_InitTypeStruce.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//这里是我之前的代码,主要是控制到4个舵机,这里大家只用一个输出口即可& p: ]) ]2 [; ?/ @
- GPIO_InitTypeStruce.GPIO_Speed=GPIO_Speed_50MHz;
0 j$ B3 b" j& z8 I- W" {& |1 D - ' d. ~# M/ c" W" h) t3 Y1 A
- TIM_TimeBaseInitTypeStruce.TIM_Period=1999;//这里是自动重装值设置2 D% E- Q' n) E4 j) P. J
- TIM_TimeBaseInitTypeStruce.TIM_Prescaler=719;//这里是预分频系数
8 g! q+ J C! z( U+ F - TIM_TimeBaseInitTypeStruce.TIM_ClockDivision=0;# u+ w3 K8 M: A; S5 o" q/ q! _
- TIM_TimeBaseInitTypeStruce.TIM_CounterMode=TIM_CounterMode_Up;
- f8 K3 L3 E5 s) @# |3 E -
) f5 c$ ]; l( h! U: e6 S. D4 h - TIM_OCInitTypeStruce.TIM_OCMode=TIM_OCMode_PWM1;+ J. |$ i8 W& `8 Q$ \
- TIM_OCInitTypeStruce.TIM_OutputState=TIM_OutputState_Enable;
h* n: J- g2 y - TIM_OCInitTypeStruce.TIM_OCPolarity=TIM_OCPolarity_High;
; D: G" Q0 e+ v" M) A -
( m/ B' l% z' h - GPIO_Init(GPIOB,&GPIO_InitTypeStruce);7 ?4 V( d9 E& b H
- TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeStruce);7 ]# }( o( i$ k+ _/ | @" l1 C: g
- TIM_OC1Init(TIM4,&TIM_OCInitTypeStruce);
9 l) j; I9 n3 s: l7 C - //TIM_OC2Init(TIM4,&TIM_OCInitTypeStruce);//这些是TIM4其他通道初始化
" V/ Q$ k8 h- u2 k; Z A - //TIM_OC3Init(TIM4,&TIM_OCInitTypeStruce);
- [' E/ u) Z( X5 x - //TIM_OC4Init(TIM4,&TIM_OCInitTypeStruce);
0 a5 A4 |' |" d1 ~4 I7 i5 I -
- l# q$ f; K& P0 F/ J - TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);# \ ~1 V) `$ F
- //TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);! _8 \2 d; I8 t- a% v* L
- //TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
% C, X" d4 {7 f6 P0 H1 c - //TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);. X0 f3 E2 e# Z
-
4 I5 m+ Y4 j4 Z& p! {' N - TIM_Cmd(TIM4,ENABLE);1 p9 r: s+ [, t
- D7 z [4 W. m5 `! r7 V; x- U
- }
复制代码
7 J: w& P1 t" \主函数部分
# V: {, O* C: O" @ R( F7 r3 s `5 \+ ?' c4 H \/ Y4 `
- #include "led.h"2 d( l V) h3 d d0 D; Q
- #include "delay.h", ^4 ^: x0 K! o4 k8 S: P3 i
- #include "key.h"
6 S3 E) g- F* N2 ^, _( H - #include "sys.h" t% h7 H- f* T# K- H/ `
- #include "usart.h"
8 g6 q& C9 q6 T, X' g4 g - #include "duoji.h". N4 f7 D" ]. ^
: a3 K9 j+ A1 w6 t# w0 A4 y- 8 s, m" }: k7 D
- int main()1 G9 e3 ]6 _- t6 X9 A5 ]
- {; c" Z! c& c! x% M/ n% d2 Q. j
( j) t% V: o% x0 [- delay_init(); + ]% l% U! D; W% }% }/ O5 X5 y
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); / z( |5 r0 [1 J; _+ C3 P( v
- uart_init(115200); //' u h- R1 n4 L q2 u+ \0 H( P2 M
- LED_Init(); //
/ V5 S' x3 G, w& E1 h/ ^ - KEY_Init(); //
' }( i! P% _6 ^7 C - duoji_Pwm_Init();
# n; _, K. _: x/ U9 h( R - while(1)3 u7 v8 G2 ?8 h7 z
- {
3 n" z/ d4 D" O; ]. `9 U - LED0 = !LED0;
1 [9 G/ M8 m9 c$ ~' C
7 ?$ E7 h" A$ m% B3 \0 D- TIM_SetCompare1(TIM4,50);//这里设置占空比改变角度,用TIM4定时器,可以自己更换
6 A: }+ a" d, v$ k( v+ B - TIM_SetCompare2(TIM4,50);, v- m9 e% J1 T
- delay_ms(5000);2 C- i3 Z8 y# b( |4 [8 T% l3 @
- delay_ms(5000);
. @) B1 W5 W. `; G; j, { - TIM_SetCompare1(TIM4,250);
2 z; ]3 n! C) A2 } - TIM_SetCompare2(TIM4,250);5 ~6 u1 K) D; J6 U' x# I
- delay_ms(5000);
0 \& h0 w' b& o+ w - delay_ms(5000);# y0 @, k" _9 J
-
' y ~( |9 N( X" f" p6 H - }
4 U& a! V% {1 p2 g9 N- x9 S. x -
: ]: k; Z# A& h. B$ `* ^( N. z ~ - }
复制代码
* P" z( L) k0 a. e. b9 f$ _. f( l这里的代码是其他地方用的,拿来简单修改一下而已,基本上就是这样了。0 u7 t# D9 I$ j
$ O# r! _4 p1 w* d- ]三、如何计算得到该要控制的角度
5 e1 X- o# U: K& {4 o这里直接上纸描述,字丑谅解哈哈哈8 n5 v" Y, a5 |+ T7 K
' }9 r3 f: s. k# P' ~
6 d2 r7 a% F, M3 n
. I7 T7 d% h9 [2 o$ W7 c 其中的arr和psc可以自己设置,再计算出相应角度的占空比值即可。大家可以自己调试一番,定会有所收获。. N. S# Y) ]# H! n
& b& I. Y- y1 H& h
& Z2 x5 T% l" Z7 ~* a
|