一、SG90角度与PWM转换关系
& r0 r8 B$ R' \0 {舵机参数:f=50hz,t=20ms 根据选用的SG90参数,我们需要给出周期为20ms,其中高电平时间为 0.5ms-2.5ms的信号
9 Z4 R: u0 P, q- r8 k0.5ms-------------0度; 2.5%
0 \2 g0 I" h4 n& K/ k) H/ R1.0ms------------45度; 5.0%
9 R0 G+ i+ L; s6 E! B1.5ms------------90度; 7.5%
. w: L( W3 @. u! r& z6 Q& a2.0ms-----------135度; 10.0%
# W0 e- ?" H6 Q9 A( q; z2.5ms-----------180度; 12.5%
; M4 R8 r8 U; F# J% |) e1 I' t0 q7 `# Y5 w0 n
二、Cubemx参数配置6 m& B# e/ g3 v" R
1、时钟配置$ y- A7 H) d q9 T- `4 F& P$ S
( D/ C& k) r+ I7 U
2 Y1 }0 i3 J* l& a; V( i+ {9 {# M/ f0 C
2、定时器配置PWM输出设置
9 L4 \* H) g( P5 @4 E4 i2 \
- x" q' \! o# S4 s ^% Q- ~: W) e根据SG90的参数,我们需要设置PWM输出一个周期时间为20ms,初始值为0.5ms高电平的信号。
X- w. L9 l0 c+ [) ?. G
( s( n' F) g/ O: y计算方法:Timer定时器时钟我们设置为240Mhz,这里我们将预分频设置为239,则一个周期为240Mhz/(239+1)=1Mhz(即1us),所以20ms的周期我们需要计数20000-1=19999个填入Counter Period参数中。( [5 K( g9 W n1 ~2 ], q. d
另外,我们还需要一个默认脉冲宽度为0.5ms的,0.5/20*20000=5006 _8 C7 ]7 Z7 v/ C8 I
" Q# n4 T* h+ r7 e3 L3 }
其他设置如下图所示:
: A5 S! `7 O/ U' r- s" `
3 @' U' l) ^3 \! W$ m! g
3 ~( }7 a3 _! C9 z2 k. y2 u" Z9 O, J4 J
三、MDK代码修改与运行
2 `# U# t6 d3 w1.PWM与SG90转换角度转换函数, ]* ?, g4 e# [1 G6 d
方便实验我们将所需要的角度与PWM计数值对应关系封装成一个函数。只需要输入我们所需要的角度和相关定时器参数即可。
1 _7 m% H3 |& I代码如下(示例):- //设置SG90为参数范围内(0~180°)任意度数/ ]7 j8 [. S! `+ A
- /*
" G$ l! S6 W! j- q% @ - * htim:要设置的定时器句柄
. P2 h$ _: Y7 w& S. B$ [ - * Channel:PWM输出通道
+ S2 T! R- } ^& }% l, I - * countPeriod:pWM一个周期计数值,这里为20000
2 k5 v) [" ~9 C& O* g - * CycleTime:一个周期多少ms,这里为203 F1 p# I t/ R5 m* ]7 j
- *! Y2 b- n5 n+ e' T4 g9 P4 T
- */
- r, x$ s/ l2 @. P6 | - void Set_SG90_angle(TIM_HandleTypeDef * htim,uint32_t Channel,uint8_t angle,uint32_t countPeriod,uint32_t CycleTime)( f8 {; ^5 Q. w c. a
- {
3 d( U& o1 S* |5 c, H4 z, B - uint16_t compare_value=0;5 S Y' r8 W% T
- if(angle<=180)) J1 J$ U9 N7 K- Q4 L0 p) G$ l' @
- {
& ]4 Z1 `$ I8 k2 Y' k - //角度转化为数值, Z, h% W; x! ?, i0 K" `
- compare_value=0.5*countPeriod/CycleTime+angle*countPeriod/CycleTime/90;/ A7 m% b* t3 j Y
- __HAL_TIM_SET_COMPARE(htim, Channel, compare_value);- a5 b; e7 y5 H P: V& w g( a3 }. x
- }9 U+ k g& F8 A5 b2 K! h3 `% Z
) t' G9 `) @5 a- }
复制代码 # s1 R$ x ]; a# {4 W! O/ B
2.实验现象
3 d) H4 h# X' q* g这里在主函数增加了按键扫描通过按键控制SG90正反转180°。
1 `/ D! `5 b+ d u: U% L# \另外还增加了串口printf函数,打印SG90旋转时的角度变化。
" ]; h, {5 O, A$ H7 Z9 y, ?& O4 I0 R! J8 x" Z/ b3 W
代码如下(示例):
% m2 V# D+ b7 ?
, {' L; H+ y& b1 k" `- key=KEYPRESS(); //按键' J. S% C6 S2 O9 c) M
- if(key==1)//按键1按下SG90从0°旋转到180°
, `1 e# t$ I- Z! o2 m" A+ g& [, p - {
5 x9 h8 h5 C) j2 ] - for(u8 i=0;i<180;i++)//从0到180°递增( A& w9 k- Q& D* H
- {
5 X. T2 R9 E3 I% j9 X- K" m* X7 _ - Set_SG90_angle(&htim5,TIM_CHANNEL_1,i,20000,20);
; t: L- b9 x( g5 p" ~. i; K - printf("SG90角度:%d°",i);( O% W6 ] p( X
- HAL_Delay(5);
% C0 V* D& t" a8 u& ]( v( v - }
' Q# l; d9 D: l5 J- ^5 d2 f% T7 c - }
+ U, K9 {3 g% ]/ X. D' x" V - if(key==2)//按键2按下SG90从180°旋转到0°* v9 l* F0 U: D
- {) B* w5 r. n# K& c
- for(u8 j=180;j>0;j--)//从180°到0°递减, R/ A1 d- q1 h f5 k. }, C
- { w3 n# y6 N6 P& _+ q7 }8 r
- Set_SG90_angle(&htim5,TIM_CHANNEL_1,j,20000,20);
! b/ P% p+ ]5 { - printf("SG90角度:%d°",j);; H5 ?0 X4 m: |: Z5 i4 w
- HAL_Delay(5);
: ]' Y2 q1 Y: ` - }& }; [, [, W$ i
- }
复制代码
; P+ B% X/ g& k% J6 o2 X8 E+ I0 _+ T3 v$ | ~. U0 ]
可以看到按键按下SG90按照我们预期的动作变化。实验成功。* B f% f; o/ k' W" L
+ I& L& ?( D4 D% [% R; U# w
- j2 P* y# i* y( r
( c6 ]0 g8 H/ o |