一、舵机的“自白”. {- v) ?! o3 W) e% K
我(舵机)是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。
3 ?) @7 k* k1 Z2 V- y( x
8 a+ O5 G: Y1 k8 ^, j那么问题来了?我们用舵机来干嘛呢,当然是控制方向了,如今,基本上飞机或者智能车又或是机器人等等都会用到舵机这个东西,所以说,认识舵机,并且运用舵机就成为我们必不可少的知识学习了,下面附图:
" d% D; y; ?' ?& {* w6 i, G/ p7 B: t& q( u8 C- @- i' V0 a C; u! D0 d
. `9 |6 L5 o, @2 y+ v: R
$ z( D9 i8 J8 m7 z
这里我用的是S3003舵机,其他类型的舵机应该也是大同小异。
% y1 V/ M9 z6 {3 g- B n! { J
& P0 M- ?+ k) B, R其中,有三条线,一条接电源(5V即可),一条接地,最后一条接控制(即单片机输出的PWM控制),下面会给上具体实现代码,总的来说跟上一讲区别不大,主要就是PWM周期输出控制,利用 TIM_SetComparex() 函数来设置占空比实现,但是多出的是计算问题,因为舵机有对应角度的时间计算,下面具体讲解:2 i3 A+ U8 g8 Q$ B5 ]
3 Q- \ D" A) o' i6 s E3 s舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度为例,的其控制关系是这样的:3 ^5 w9 B3 R, g; o* Q2 P6 T1 Y% `
/ }; F& O& ~1 r7 J9 l2 c! J0 z# a 0.5ms--------------0度;" M1 q a( K! U" e1 W, H
! f& G2 l. }, b9 Q% o" | B' ? 1.0ms------------45度;
/ _+ R$ m# H) l5 s! a1 z& Y4 C/ Q9 O) T* J# S5 Q
1.5ms------------90度;% L: g0 Q g$ N. S( i* X
1 U, u5 p1 @- f3 g- Z
2.0ms-----------135度;. F7 j! o& q; s) Y
6 B. q5 w" \. o 2.5ms-----------180度;
; E0 p8 _' M' P. C4 T4 `( m! Q* C5 s$ J
基本上,我们学生党所需要的舵机的控制角度对应就是上述关系了,至于360度舵机这里简单提一下,主要是我这个舵机做不到(哈哈哈,这舵机180°的)
; Q% H& P# Q% o' w7 E4 f4 ]5 x! E c4 `: G' c0 O& V
这里讲一下360°舵机的 9 g0 u' O# k j# j' J6 v
% P# ?' i1 o/ l" r" Y2 j4 v% K5 J
0.5ms--------------0度;正向持续转(最大速度)
2 I3 o/ E' `. }! x# W& n3 z. ~# H( z( V8 Z& f7 N0 @
1.5ms------------90度;停止转动,速度无
' @9 q$ q9 S8 }$ q& N' A% P3 c1 ~: X5 w# A5 n7 D# Y) \
2.5ms-----------180度;逆向持续转(最大速度)
8 }7 v% W2 B- n6 S, I0 L; e; z" s
4 R1 ?- _9 M2 F( ?调整PWM周期即可改变转动速度和方向。 6 h7 y ^* ]7 \9 ~& e
( \, [& D6 N3 ^9 i7 T
言归正传,到了这里基本上对控制舵机角度其实有了一定概念了,下面就直接附上代码部分了
9 y' N1 r$ Z: E' V# B
/ r3 S, S% B& H0 x二、代码部分' c7 ?; G5 w8 R( _3 k
- #include "sys.h"
) \! Z n- P2 O. o% W - #include "duoji.h") Y9 [7 ?/ l7 S3 M6 u# ^! v: A
- 6 w( F; M! l. _8 r8 I" u! k" S" a- `
- void duoji_Pwm_Init()
, l. T3 C7 H0 D# G% |7 |4 p" V0 j - {, W5 x; q0 o$ E5 O
- GPIO_InitTypeDef GPIO_InitTypeStruce;
( g2 a! k; d% V4 b - TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStruce;& p: {" [$ R3 d k R0 e/ X+ W
- TIM_OCInitTypeDef TIM_OCInitTypeStruce;
8 M1 b5 m7 \, y* a' D: T - & M- p; M" U7 R, G2 J: Z' \: f. l& R4 k
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);, k' p) R7 {3 l) t
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
$ y* j2 Y: W( C: b4 F - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);8 j5 l: z. y$ m. w
- # `* f' ?, ?9 v& d1 i
- GPIO_InitTypeStruce.GPIO_Mode=GPIO_Mode_AF_PP;
7 S! S+ E* {- S' g0 ^8 k - GPIO_InitTypeStruce.GPIO_Pin=GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9;//这里是我之前的代码,主要是控制到4个舵机,这里大家只用一个输出口即可
7 {9 S9 z# K; n- `: p( g - GPIO_InitTypeStruce.GPIO_Speed=GPIO_Speed_50MHz;2 F: t+ w) u: [/ g
- " F# u8 Q0 \1 F1 _6 { }' Z
- TIM_TimeBaseInitTypeStruce.TIM_Period=1999;//这里是自动重装值设置
8 f9 C- M5 [% w$ {% X8 ?2 t - TIM_TimeBaseInitTypeStruce.TIM_Prescaler=719;//这里是预分频系数
& y; @" Y& [9 U7 {0 t: i' U" q( u - TIM_TimeBaseInitTypeStruce.TIM_ClockDivision=0;# u: F+ ]; m2 @8 ?" K
- TIM_TimeBaseInitTypeStruce.TIM_CounterMode=TIM_CounterMode_Up;5 ?! ]0 D% d$ p* c3 `9 `
- * @, H, Q. a- y: L* q) `0 f
- TIM_OCInitTypeStruce.TIM_OCMode=TIM_OCMode_PWM1;& b1 X% o( }4 Q2 U4 I
- TIM_OCInitTypeStruce.TIM_OutputState=TIM_OutputState_Enable;- U z% N1 F5 i: g, V% J! C- Q' H
- TIM_OCInitTypeStruce.TIM_OCPolarity=TIM_OCPolarity_High;5 n# r4 |$ Q* l- K' t$ Q5 C
- 1 ^: o, m! B0 V$ z* E' ?
- GPIO_Init(GPIOB,&GPIO_InitTypeStruce);* h0 _! A, Y/ P9 Q
- TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitTypeStruce);
! @+ B# f& d4 l5 v - TIM_OC1Init(TIM4,&TIM_OCInitTypeStruce);
2 t7 I2 P7 [& j) R. ^ - //TIM_OC2Init(TIM4,&TIM_OCInitTypeStruce);//这些是TIM4其他通道初始化, ]6 e' f& f( ~
- //TIM_OC3Init(TIM4,&TIM_OCInitTypeStruce);
, [6 {. }4 C, f4 x* i G! h7 P - //TIM_OC4Init(TIM4,&TIM_OCInitTypeStruce);
# G' I P- ^2 j, K6 ~ - 2 r7 ~, W7 }4 V5 L
- TIM_OC1PreloadConfig(TIM4,TIM_OCPreload_Enable);3 k- H: l1 i6 K. w4 p7 D
- //TIM_OC2PreloadConfig(TIM4,TIM_OCPreload_Enable);
- A: e. r3 a4 f4 h+ B' p - //TIM_OC3PreloadConfig(TIM4,TIM_OCPreload_Enable);
& H6 q( d+ \$ D4 T' Y% S$ j- k - //TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);0 `3 p9 ^" N9 K4 N& o7 \+ j/ ?
-
+ f- Z5 y. H% _" `' Z- f - TIM_Cmd(TIM4,ENABLE);
, H5 U& t# c: e -
2 V) f% A* t5 k5 O - }
复制代码 8 g* J# w8 t$ x9 @
主函数部分
/ P9 V4 d( f% C! v- w; q: _# I" u' a' e. C( [4 ^1 r5 K
- #include "led.h"
: s' W, R9 D) c6 \ - #include "delay.h"
$ U# |1 m! D. ^ - #include "key.h"
% w9 g8 h* f! `7 a( f0 U9 t - #include "sys.h"
1 o' P! ?% l( u- z - #include "usart.h") `9 p0 r) ~$ V6 S- \
- #include "duoji.h"9 q: A, O2 ]" ^. c# K0 c
- 5 I4 |$ z6 z% v: l
2 j6 m6 M: l3 c- int main() ^* S! Q) ?# }1 L
- {
3 q( ~# n3 Z. r; @- o" N - 4 o/ o: }% X! z6 H2 }
- delay_init();
& t- t8 r0 E& j - NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
' ^5 T4 s' \7 J- N; J2 y5 q5 B2 b - uart_init(115200); //
8 x/ y l6 M1 Z3 J7 n# } v - LED_Init(); //% L& {* {2 u' n* k! |
- KEY_Init(); //# k$ @, E- i; E$ I
- duoji_Pwm_Init();/ @4 R7 ~ L" P
- while(1)- R7 H, m& z$ N7 A B0 B4 B
- {/ V! F( j2 m. S' r) k5 z
- LED0 = !LED0; 1 S: N2 ]# z: S% f% x4 B( C2 u
. r& @2 L! G/ {" N; K3 r0 A- TIM_SetCompare1(TIM4,50);//这里设置占空比改变角度,用TIM4定时器,可以自己更换4 C6 B! m. J& b" c% l8 |
- TIM_SetCompare2(TIM4,50);
6 c$ \) v8 b$ T/ b. E - delay_ms(5000);
; Y) h# T( U- K7 L! V7 c - delay_ms(5000);
8 Q) F6 |5 t3 f) U* i" K) d - TIM_SetCompare1(TIM4,250);4 N: {3 ?# ?% u, n+ s
- TIM_SetCompare2(TIM4,250);3 m0 S4 A7 g$ U Y0 _
- delay_ms(5000);1 K/ l+ R+ L) r4 {$ g) z( F
- delay_ms(5000);
$ w8 T" u0 {" q9 y, s0 p6 B -
7 H6 g9 x1 }: n7 V/ g4 } - }; y' a( V( v: E- k% \3 q4 p. ~
-
6 B& B4 {% L. ?' @ - }
复制代码 6 S' S7 [/ o" l: `
这里的代码是其他地方用的,拿来简单修改一下而已,基本上就是这样了。" G2 {' B+ E$ a
7 N( F2 d d6 U% Q' r" @5 d三、如何计算得到该要控制的角度
: ?3 T. l( L) _, r这里直接上纸描述,字丑谅解哈哈哈6 u2 z( A$ S9 g! o! e. R
0 W, v& T' U% s W( d, |
1 \0 n# Y5 X: f6 ?; J! d' ?2 {6 q8 d2 C6 A
其中的arr和psc可以自己设置,再计算出相应角度的占空比值即可。大家可以自己调试一番,定会有所收获。# Z/ W9 n$ d& o( v6 c
# q/ r* P+ C4 ]/ ]. @
2 p: g: ?# y. r- Q7 t
|