1. 材料介绍% O+ N( y1 w. Z9 Z
STM32F103VET6开发板,此处我使用的是野火的指南者,不过F103系列的应该都是可以通用的,具体大家可以自行参考相对应开发板的用户手册。: q" n% ^4 @+ |' V9 L, E9 n
SG90舵机一个。我使用的是180°旋转的,实际上在某宝购买的时候360°、180°、90°的SG90都叫这个名字,如果你真的不懂的话,选购之前最好是问问客服可以旋转多少度。
; R. R- @' g! y' j" j/ D杜邦线若干。
0 I1 r8 r `. j' r8 Z, m$ a
+ F$ Q2 A R# L' s# O
9 B1 ? ]2 C# ]2.接线方法0 u& `6 M, F; w! M6 A+ K# v5 k
主要是SG90舵机的三根线,我使用的这款舵机红线接5V(3.3V带不动舵机),棕色接GND,黄色线接开发板的PC6." L% _. x; T5 T
9 T6 K7 D7 B& m( {) h" R. i- J0 b5 u+ e, }% Y6 b( X
1 A4 Y- Y. A0 a5 B1 h' r5 C! v. @; l$ ~9 T, S5 R2 q
3.舵机控制原理* U( r6 i% r2 m3 L
控制信号
+ `: W( ?! e) T3 B+ D4 F舵机的控制信号为PC6输出的PWM信号,周期为20ms,其中脉冲宽度从0.5ms~2.5ms,对应舵盘的0°到180°,呈线性变化。9 Z/ w8 V4 J5 }
也就是说,给舵机提供一定的脉宽,它的输出轴就会保持在一个与之对应的角度上,直到下一个不同的脉宽出现,转到新的对应角度。
% a* ^7 L( c5 l& S3 l2 Q& v
+ B" c! Y9 h2 ^# S0 |3 Z7 |0 T
7 N; d, U8 A$ u+ D( T9 X2 e反馈信号
; t+ o7 B) Z% v% K舵机接收来自信号线的控制信号,电机在转动时,会带动反馈电位计的转动,电位计将输出一个电压信号到舵机控制板,进行反馈,该信号与控制信号进行比较,从而调整转动方向与速度,直到反馈信号与控制信号相同。
: {# ]% k& K) W% x2 z$ Q
$ \% a1 n6 {) T6 e
. Y0 s w+ s6 @1 u9 M: a代码部分% k" N+ X! r4 Y; y
- <font face="微软雅黑" size="3">#include "stm32f10x.h"
% S2 i) s) Y* p- f9 U; L8 Y - void pwm_init(void);" i0 r5 R, X. W+ I& R2 D2 T. {
- void delay(uint32_t x);; d3 ~2 e6 y6 J7 F- [% K
- int main()
$ O( p; q- V( k- {4 o - {
" g# Y; @& a& [5 N9 ?8 p5 N: c& B: T - pwm_init(); //PWM初始化: `3 Z7 H) @" D* [+ C" D
- while(1)$ C% B. B/ D8 i) J1 X
- {3 W$ C8 O: h0 e- J/ B
- TIM_SetCompare1(TIM3, 195);//0度0 q7 e# W# {# ?7 `, Z2 |
- delay(10000000);
5 U* j# Z" \. Z# W - TIM_SetCompare1(TIM3, 190);//45度6 l- F( l/ ~1 i" j% q; `& r
- delay(10000000);
7 F0 O! n7 \- {6 | - TIM_SetCompare1(TIM3, 185);//90度: O9 b$ G1 l) u G# Z& Z1 d
- delay(10000000);
# O3 n2 e- }/ U) M) q - TIM_SetCompare1(TIM3, 180);//135度
" j# d/ ^8 h0 H% F - delay(10000000);
, `0 H6 L3 S% g. y/ s( N - TIM_SetCompare1(TIM3, 177);//比180度旋转的稍微小一点,因为舵机旋转到180度之后可能会卡一下,详细原因可以自行查找; {) C4 D1 ]3 c9 h8 p
- delay(10000000); 5 b8 |4 G0 k: k _0 o
- // TIM_SetCompare1(TIM3, 175);//180度
2 Y- ?# g. _1 Q4 `) Z - // delay(10000000);
$ x. N, R. l& U7 ] - }
2 [( O; W# h- l |+ b0 Z( n - }
6 F$ m; o' L3 Y( f) S8 L1 d: O
( [4 Q) f& S' v$ M: z6 A/ P- ( D7 t+ t, N0 \5 h* a2 M7 V
- void pwm_init() I2 b! J+ ^5 {! a9 d( K
- {' G/ [) l' j& B" p7 I: t+ }: T$ Q
- GPIO_InitTypeDef GPIO_InitStructure; //声明初始化GPIO的结构体变量, t( G9 v6 E1 l2 e- x5 W- L' T
3 Y5 ^. k/ K6 G- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;//声明初始化定时器的结构体变量
7 ~/ j0 H# m: A4 a3 x/ B9 s
+ Q; O/ q6 e0 T$ j& Y3 @/ J" q. B- TIM_OCInitTypeDef TIM_OCInitStructure;//根据TIM_OCInitStruct中指定的参数初始化外设TIMx
- I& `, R" S x, K( o4 d - ( l3 l% M$ _' A3 H$ o
- //开启时钟
, R; J9 J y, V9 ^/ l$ y6 V+ M - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
3 A/ m, J* D3 Z: k3 o3 J3 h - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);, l8 ?: }& K2 R4 a/ o7 Y
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
: W) i+ H( [3 N$ n+ h& |# E% M
2 c _$ ^6 ~% {% ]( Y: {- // 配置GPIO的模式和IO口& o7 A4 S& d9 F/ u! S
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;// PC6 n5 `! M" j" Q4 ^! B' g' F7 H
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- l2 t3 v! v9 `4 b' n - GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出
; N' t1 x$ J; Y# p0 f" }, E - GPIO_Init(GPIOC,&GPIO_InitStructure);; K' N8 j0 h% i2 @2 C( I9 k* \6 m
- % q( \; ?' i' U0 n7 Z6 t
- //TIM3定时器初始化! T& E: s4 V% @
- TIM_TimeBaseInitStructure.TIM_Period = 199; //PWM 频率=72000/(199+1)=36Khz//设置自动重装载寄存器周期的值
* w. |7 H; k9 m& x - TIM_TimeBaseInitStructure.TIM_Prescaler = 7199;//设置用来作为TIMx时钟频率预分频值- i5 N& ~6 m! J
- TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;//设置时钟分割:TDTS = Tck_tim
7 ~6 I# P5 @- z* U2 C - TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式' H+ S$ B4 {. ^+ O/ p$ X' W
- TIM_TimeBaseInit(TIM3, & TIM_TimeBaseInitStructure);
" j. F a6 B4 U% c
6 J: }% g& V1 F- GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);//改变指定管脚的映射 规则在F103参考手册里。! v) L2 { }+ T8 J6 t, V8 S
9 X) ^( ]- ^. I# ^# ~3 |+ ~5 D- //PWM初始化
3 X2 l0 V7 d+ t8 Q - TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;
# { H9 @+ g; n, x5 g - TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//PWM输出使能
( E& z' p& o, X) k, k X9 } - TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
! k+ W/ n% S# e$ h# I! ]; K - 9 l' M+ ?9 V+ n( o1 l* U1 O
- TIM_OC1Init(TIM3,&TIM_OCInitStructure);: \+ o$ f- P3 E |" e* C& ?. r) c0 s
- TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的预装载寄存器3 C, V7 s2 k! ?4 N! I
- TIM_Cmd(TIM3,ENABLE);//使能或者失能TIMx外设/ {% |: [. M3 X1 i8 f" U
- }' ]5 I) e+ z" B6 z
- - o" W0 @/ i. G# [( o
- void delay(uint32_t x)
$ }) y( v; }1 P% _ d6 H - {) U0 ]" J$ D0 [0 m* p+ N$ a9 z
- while(x--);
?: Z x, x- C- w2 k% G0 ~; _$ q$ q- F - }
7 }; c& v" r# L3 |& s3 ` - </font>
复制代码 0 {' I5 q0 p& n# T
! C; o$ |. S6 t
|