你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32f1之L298N电机驱动+PWM调速

[复制链接]
STMCU小助手 发布时间:2022-5-14 20:41
一、L298N电机驱动主要介绍
6 e$ ^2 ?  B7 q; h  k( N主要I/O口! N$ Z2 |& Y. ?, m4 [# ^
( q' @& ^/ ~; u! P. g% j* \9 L
使能端ENA和ENB,控制输入端INA、INB、INC、IND,马达输出口OUT1、OUT2、OUT3、OUT4,5V输出(可以不接),还有一个板载5V电压,具体如下图所示:" @/ n  `! s& H2 V
0 \( @( N" C2 _2 M, |0 g
2L_$AX`QM3WZL$C~O@O3`KA.png / ?+ J$ G, ?. F7 I( @# l
1 j/ e; I! T1 q! e; l' b9 N
二、控制实现功能
( n: g6 r) |+ k7 i9 p. G对于L298N模块,直接给12V输入,接上地,就可以给整个模块供电了,之后就是通过控制单片机(这里用的是STM32f1)给4个输入端(INA、INB、INC、IND)控制输入高低电平了6 l( \; t; V& `' C2 k1 S2 j, }

7 d% O9 r; s# f2 T( n% U注意:ENA和ENB一般情况下会有两个跳线帽连着,这是直接连上高电平,只有给高电平,这才能让四个输入端(INA、INB、INC、IND)口去控制四个输出(OUT1、OUT2、OUT3、OUT4)进而直流电机状态。特别注意GND是电源和单片机一起共地!
3 X' a; G2 ?- Y( ~. Q% s+ z/ j0 K9 t5 x, u9 {0 ?  H' w0 ~7 T( g
下面为真值表:
* \2 X; L* T7 x' h' u
  d! B' m  p) Y& m2 e: h _IZRG{XIF1`$$NAXLN[8FUI.png
) d: o% s0 E7 @: ?0 Z9 c; x
, Q5 f1 u( m1 |( G. t* U% _& X) m( ?6 I& A6 k" s4 S* C
三、PWM调速实现  J6 _) j  \% A4 `
这里就不再是把ENA、ENB再接上高电平了,这个时候就要把跳线帽拔掉了,在通过定时器来控制实现PWM调速,具体先上代码:
4 k( p* s" g% S# ~0 F. O; V. G; @0 t) @0 w; {4 R
  1. #include "timer.h"% J5 z) a7 A- c

  2. 6 }0 ?: J- h" b9 F

  3. 9 \/ p7 d) s. @6 \% _1 l
  4. #define Ina PGout(2)
    4 U5 B1 v  O- Z) W' y
  5. #define Inb PGout(3)1 n/ `( J  f) G4 O" W5 }9 Q
  6. #define Inc PGout(4)8 O! e0 O8 ]  x8 ^# n% V
  7. #define Ind PGout(5)) `  y# Z. x3 h+ ?
  8. ; _' |' \. v8 l' K* q( B* ~
  9. void TIM3_PWM_Init(u16 arr,u16 psc)
    % e! _7 O6 ]3 J& L. t  w
  10. {  1 G+ i- M4 r5 k# h6 x/ H6 H4 H6 l% }4 h
  11.         GPIO_InitTypeDef GPIO_InitStructure;
    ) ?4 ?: S2 @( h# G* j: m' P# Z
  12.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;7 D. u; N4 M5 U0 K# l# N+ L2 L
  13.         TIM_OCInitTypeDef  TIM_OCInitStructure;# H4 M/ U* y4 [) ?6 s
  14. 4 t- {3 G) N( d6 w5 T7 F
  15.         
    - b; Z( ~3 r1 B# |

  16. 3 H4 }1 [6 k5 r1 \3 z
  17.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        
    1 K0 ?* ~, t9 v* g4 F( d2 j
  18.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
    1 r2 n" I% u+ A" M% a6 c
  19.         
    ( [6 I# c, z+ E

  20. : w. B/ s+ V. A3 g. e
  21. 6 s: v' c- P3 L: C8 L
  22.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //
    - r( p" l3 ^$ v$ y9 g/ C1 W1 C" A
  23.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出* e" B5 a" v/ |( y0 Q) j) f% E
  24.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& z# q8 b! [. q) d; O+ G0 @7 o
  25.         GPIO_Init(GPIOA, &GPIO_InitStructure);//TIM3通道2
    5 D; f- L4 S% `# c* L; E3 c9 ~
  26.         
    ! [0 n: p. a, Q. H/ R2 u
  27.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //. z2 F! ?6 G4 ]0 `& ?6 G; H
  28.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //
    5 B  G  k$ v; u7 d5 H# u3 U( E# Y: ]
  29.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    " J' E, P  d7 q+ O6 {! J
  30.         GPIO_Init(GPIOA, &GPIO_InitStructure);//TIM3通道1
    0 P2 w4 n: g# |7 Q5 b
  31.         0 o9 v2 W+ x) ^9 L' j( e
  32.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                        : r0 B8 N. j7 }) W4 R' I# B0 Q0 I1 T
  33.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 
    6 E0 Y1 H9 k: i$ R4 |& ^
  34.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                6 J4 `! K" G  D! X- O
  35.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         $ ?, e$ T) \' o: r% a9 ^% i' h
  36.         GPIO_ResetBits(GPIOG,GPIO_Pin_2);                                       
    0 j  u) U" U& q3 U
  37.         
    1 `1 k* {' \- s- e
  38.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    : `" J' ?3 b! R" \% X, U! W
  39.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                 $ z  I6 H$ y" ]; K7 m) P1 X* H9 D
  40.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 # d/ O0 ~$ F, o# j. D5 c
  41.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                0 @, n6 D" J% F; ?
  42.         GPIO_ResetBits(GPIOG,GPIO_Pin_3);                                                
    * G; k9 a# c0 n) J. K/ O
  43.         ) w) ]# ^4 V& }1 q+ H5 S
  44.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                                 
    + K! S% @. g( O# ?
  45.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 5 L) [  m9 h! v
  46.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 ' \; D! x: J$ e. I
  47.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         5 M, i. r- ^" |6 S" B; s
  48.         GPIO_ResetBits(GPIOG,GPIO_Pin_4);                                                
    9 E5 g4 q, i! i, n
  49.         . W& {; Z6 O; V- j9 @
  50.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                  t/ M# k6 s, s. u5 |, b
  51.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 
    , H: g3 H) f# r  ~" x& x+ T
  52.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 
    & O6 j) k: ?7 E+ l
  53.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         9 ~6 I. c8 E0 W! r9 Y) `" w
  54.         GPIO_ResetBits(GPIOG,GPIO_Pin_5);                                                0 G+ d3 Z# J. o0 n4 y

  55. 5 k! g! C& @+ u5 ?  H1 i
  56.         TIM_TimeBaseStructure.TIM_Period = arr;
    ' t* B! Y' F% Q4 J9 v2 @: V
  57.         TIM_TimeBaseStructure.TIM_Prescaler =psc;
      {3 N, z( O  ^1 K, N
  58.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; 5 W/ ~5 P7 J0 v) j1 U" H, w
  59.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  % P% T( A9 r9 F( \% A6 K6 A, y
  60.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    ! \% D8 D& U2 l, O9 |
  61.         
    , T1 ~) Q) h" X
  62.         
    / U4 a) Z; T; u4 d  h2 K
  63.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    ( h* y. s7 T+ j- [0 V; o' J1 a
  64.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; ! _6 Q6 x8 k/ {: l: Z, [. {
  65.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; 7 Q8 R1 y, Y' ~& j% G  H1 u3 d
  66.         TIM_OC2Init(TIM3, &TIM_OCInitStructure);  / k8 ?+ h. k0 k& U* b: ^5 Y
  67. 4 Z: i2 Z6 H- `) S3 G* ~! L
  68.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; * v& t1 E9 D( f. O3 G
  69.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    $ k4 F( p0 Q) |8 r* w
  70.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; ; \. z4 Y! c' [# |
  71.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);  , B% m$ D' {' |& S  P  d# }' J1 T
  72. 8 f  A% ~$ M# _, U: D6 a
  73. 1 P6 j$ |, X* A8 \7 e
  74.         TIM_Cmd(TIM3, ENABLE);  
    & W, e* A6 X$ X

  75. ( N5 r! ~0 t( _6 Q, k0 d
  76. }
复制代码
( v% [, E% S5 O8 m& h: V
上面这段代码主要是定时器TIM3的初始化以及四个输入端的初始化,至于那个预分配系数psc和自动重装值arr可以自己设定,这里我设定的是arr=450,psc=7199;大家可以自己调试,这里不细讲。
2 V( d4 Z8 h7 N5 y) c) ~. U1 \; X
然后把PA6,PA7分别连接到ENA和ENB上,设置好arr和psc,最后通过TIM_SetComparex函数设置占空比即可实现PWM调速功能8 s8 l; n+ ^& ~! S; C2 `
2 T$ Y; n" |' H; S$ i7 d& ^
四、整体关键代码和马达连接图
9 v0 j' S3 J) |' _
剩下一下重要代码如下:/ d4 T0 o0 K. }7 l+ \

% V- R, d( i) u) i) i1 N' A
  1. void qianjin(void)
    ) N& I9 ]) e" H% d' m+ v
  2. {
    ; [( t* t3 N; L# f$ n
  3.         TIM_SetCompare2(TIM3,100);//设置通道2的占空比实现PWM调速,这里是100,在0~450间,越小速度越快
    8 P% U* h0 U% ?
  4.         TIM_SetCompare1(TIM3,100);//设置通道1的占空比实现PWM调速$ i; ~' P! K7 ]' H) Y4 l' ~) J4 H8 b7 m
  5.         Ina=1;
    6 i9 W8 N# j9 Z0 N
  6.         Inb=0;7 h( S5 j. ?, [  M) Z6 X, ~
  7.         Inc=1;
    ( P6 b; k# Q0 D5 d9 c
  8.         Ind=0;$ t: ]( b; i# Y9 L6 i) u
  9. }5 E5 [: c4 s+ O( ?; A) `% {+ C
  10. void houtui(void)3 u! `4 K# D' b# X* I. w& l% C& X3 E
  11. {
    ' i1 x  q- a1 n/ V! M$ K
  12.         TIM_SetCompare2(TIM3,100);- `3 F$ `0 c3 \# {- q0 j1 d' [
  13.         TIM_SetCompare1(TIM3,100);
    & r% S2 f0 x+ L' s1 O
  14.         Ina=0;$ T; i  C0 _4 ~- R( N' D+ l
  15.         Inb=1;
    1 o" D5 H  u* F5 f3 G
  16.         Inc=0;
    4 Q% S4 a* x8 x
  17.         Ind=1;/ W- O/ X9 ?# C( z: k% d0 L
  18. }
    % i  ^& C: O& q5 R7 @3 C
  19. void zuozhuan(void)0 r( f) u" @# Q* F1 S' \% F5 x
  20. {
    6 k2 D& m' u/ h6 O
  21.         TIM_SetCompare2(TIM3,100);
    3 E# I# R( g( t) U5 I+ L  Q, Q7 H
  22.         TIM_SetCompare1(TIM3,100);
    & H8 F5 O% l5 x- ~
  23.         Ina=0;
      p% {' O5 i1 i. j- d/ @
  24.         Inb=0;. M. a4 P& v$ F
  25.         Inc=1;+ t- v- W, _* a+ ]+ r: M( K+ i
  26.         Ind=0;& E3 \2 B. ^9 s6 L1 a! z# Z
  27. }# H, R8 |# G7 E- h; Z! ^
  28. void youzhuan(void)3 K) u6 w  z1 W; }) V5 h
  29. {
    + U& P7 G. E% @
  30.         TIM_SetCompare2(TIM3,100);3 u+ O, S) ^; p; e: f3 z- }. I. W8 Q
  31.         TIM_SetCompare1(TIM3,100);
    " m# L4 _& H2 J6 U+ ^" e
  32.         Ina=1;! a4 j; I6 \( w
  33.         Inb=0;' ~9 o4 ^9 D6 c6 ~1 h! J
  34.         Inc=0;; i  l( f9 X; K
  35.         Ind=0;
    * c. D2 v+ E' ^! \# ?
  36. }/ ~  a* W" K0 b  F
  37. void stop(void)
    , d5 E6 T2 x( X, U: y8 o7 ]/ S
  38. {) h2 s5 I7 h2 w2 d. U5 u( ?
  39.         TIM_SetCompare2(TIM3,100);
    . @$ g0 F' A0 h6 q& H
  40.         TIM_SetCompare1(TIM3,100);& R4 W" s- ]. p' N
  41.         Ina=0;
    3 E$ A0 R; k7 o: @
  42.         Inb=0;
    " H4 G9 r5 |! L' f  A* N3 M
  43.         Inc=0;/ E5 I# v- Z0 W: G
  44.         Ind=0;& x3 |" x2 ?9 n) G1 V
  45. }
复制代码
( [1 P3 n  h0 A- n1 o5 S& K$ ~
主函数:. p6 k7 w4 j' f
3 z2 a5 v' q6 p/ t4 c+ i; C
  1. int main(void); l# x& k$ \: o% N0 c! g
  2. {        , O& k' K8 ~6 ]
  3.         vu8 key=0;9 s/ t+ c: Y3 H) q7 w
  4.          % f, W5 c# s) Q) j
  5.         delay_init();            //          + n7 K) K5 `3 F% K) t
  6.         LED_Init();                          //
    3 {5 W9 D4 d! U# Q4 R
  7.         KEY_Init(); //. i' U5 m1 ^1 Z* |6 E, w5 s0 c& F
  8.     TIM3_PWM_Init(450,7199);
    ! C! n9 k9 [4 Z
  9.         while(1)
    / B7 ^  Z' ?4 i$ r8 ]
  10.         {* P, G& P2 F: `/ {! T5 n+ W7 E
  11.            key=KEY_Scan(0);        //通过按键简单实现
    ! U' k8 u& r( A+ O
  12.                    if(key)# i0 o3 `" k% b" {& J' T; D
  13.                 {                                                   
    % A$ U  h2 m& G7 C: A
  14.                         switch(key)
    + x8 @( ^5 A4 p# C& T5 k
  15.                         {                                 , P/ n: m" j# D9 H$ I
  16.                                 case WKUP_PRES:        
    4 |6 K7 }: m3 {" O* C$ t
  17.                                      LED0=0;
    0 L8 Y) ?( M8 O0 s9 z! O6 B
  18.                                      qianjin();
    ) a1 @, ^5 V4 c8 i/ r2 L7 q* x! ^
  19.                                          break; 8 G+ U# C+ }3 ~3 `5 ]0 S$ j" v6 m' j
  20.                                 case KEY1_PRES:        // + K- f# [1 {  \4 p& d
  21.                                      qianjin();
    ) \+ q1 R/ `; R1 D( t
  22.                                          delay_ms(5000);6 s  ~) G) A! K2 l8 w5 x, m2 q$ W
  23.                                          delay_ms(5000);
    5 h/ i" D0 l) B5 Q
  24.                                          delay_ms(5000);
    & \2 b' K  G1 O& H* t" i7 o) X
  25.                                      houtui();
    % _2 M! u, e8 ]0 x5 E( ^
  26.                                          delay_ms(5000);, i5 I3 g3 w: o% Q( \
  27.                                          delay_ms(5000);0 S+ `% s; ^; ^+ n) f
  28.                                          delay_ms(5000);
    4 O" g5 z3 i$ Y; m) m( r0 ]& v
  29.                                          break;
    ) }( k8 ?; M& `  A. t) v
  30.                                 case KEY0_PRES:        
    ( k* A! Q3 b5 y# K
  31.                                          LED0=1;
    % a. N& n, v- X, t  I4 x
  32.                                  stop();
    & W% U+ U8 [* W- S1 V
  33.                                          break;
    & M( s% ~6 y$ F- [  t8 h# ]: x/ u( i
  34.                         }, d( v  P1 P" E4 ~# h$ q
  35.                 }
      g- V% r% I  u7 f6 w. [$ ~0 g: J
  36.                 else delay_ms(10); . F6 q1 P$ _' {& h
  37.             0 \. l- K9 g9 b; S' Y! j' `# O4 m6 G
  38.                 5 J! h6 o- S4 p; w* Z
  39.         }
    8 H1 ^8 r2 y) U5 r$ h1 W9 f) h. ^
  40. }
复制代码
; J0 j' H2 ~$ J$ R# f  |/ _; p
以上是简单的代码实现,大家可以根据自己实际情况调整修改3 B$ h+ `3 H* g! U+ c& L4 E6 A  M& u

2 f3 o  h5 u5 y4 \. l% ]下面是实物连接图:
4 Z1 ?8 c% |* e! k0 Y  m4 S
  b, b4 i+ O) W. f! J; Z ~3O~2TCPP3P48296G556`(2.png
8 |: }5 p; R/ }+ w! `8 L7 E( o5 s, d6 X" G/ L6 h3 X
这里用另一个L298N来连接,原理一样的,我另外那个红色版的螺丝不好拧,就暂且用这个,这里我用这个电机驱动4个马达,特别注意单片机和电机上的GND是连在一起的!- k4 \+ w0 v2 E* s1 H

1 \; u! r" |8 j( F& H: t那个连接单片机的图片就不发了,具体按上述代码操作,不明白的地方可以留言或者哪里写的不对欢迎指正,谢谢!
# B, Q; D( c2 U5 c/ R
9 r& R# B/ r: X) u$ \. m" w
1 x9 k, K% e) s2 j9 A( T7 p2 N' _
赞 收藏 评论0 发布时间:2022-5-14 20:41

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版