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

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

[复制链接]
STMCU小助手 发布时间:2022-5-14 20:41
一、L298N电机驱动主要介绍
  Z% L3 x2 U9 j* [主要I/O口
: ?+ f2 p! S- i, @  C
& Y4 a( T4 |( U: K" o/ U使能端ENA和ENB,控制输入端INA、INB、INC、IND,马达输出口OUT1、OUT2、OUT3、OUT4,5V输出(可以不接),还有一个板载5V电压,具体如下图所示:* B, f. g2 L8 b1 x+ ]3 t. o+ W& b
$ A0 O4 J- }* Y
2L_$AX`QM3WZL$C~O@O3`KA.png * a- b/ _3 z1 ]* F
1 d# {+ J2 {0 W/ @' ]( i
二、控制实现功能9 U8 }/ M. ^$ z3 f6 ]* r: X
对于L298N模块,直接给12V输入,接上地,就可以给整个模块供电了,之后就是通过控制单片机(这里用的是STM32f1)给4个输入端(INA、INB、INC、IND)控制输入高低电平了
  y6 G* i1 n: a! R7 w
( ?. O- e" {6 v: b8 Y& n) w1 Y注意:ENA和ENB一般情况下会有两个跳线帽连着,这是直接连上高电平,只有给高电平,这才能让四个输入端(INA、INB、INC、IND)口去控制四个输出(OUT1、OUT2、OUT3、OUT4)进而直流电机状态。特别注意GND是电源和单片机一起共地!
7 m: p6 J/ e5 q/ Y" [
5 p. E. Y+ J6 c8 s% V  C+ }# u5 \$ u下面为真值表:
" R  w: Q7 R8 Z# d# X
" u. l' J' Q# m; Y# x2 L& z) V _IZRG{XIF1`$$NAXLN[8FUI.png ) x$ ~! T& x6 Q0 `# ^: l* v, _# m: `

$ p, v0 I( ~2 U( T' t5 l0 ?8 e. l( U! n/ N
三、PWM调速实现
' w5 y: v# v' e! g+ F) i7 t这里就不再是把ENA、ENB再接上高电平了,这个时候就要把跳线帽拔掉了,在通过定时器来控制实现PWM调速,具体先上代码:
$ s/ @: j7 v! ?. M! z6 q0 S* |' ^& _
2 g: L/ B) l- H: g7 k4 [
  1. #include "timer.h"
    ) A" D8 @8 s0 U7 M

  2. ' ^( r0 f7 s/ x! _7 Z! I
  3. $ e4 E" c0 S4 S2 [1 F3 s% x) H
  4. #define Ina PGout(2)9 m) z4 s, ]" e6 |3 z
  5. #define Inb PGout(3)
    # V; ^; l( _# q7 F
  6. #define Inc PGout(4)
    ) W2 i4 j* C& o* y
  7. #define Ind PGout(5)& z+ W: Y, Q& F! m: v  o3 P( E

  8. ' ~! C4 L5 B& o4 p( m0 ]- f4 }& x
  9. void TIM3_PWM_Init(u16 arr,u16 psc)
    ; |/ o' X+ _+ D8 |
  10. {  
    ! x! ^% Q8 W% m
  11.         GPIO_InitTypeDef GPIO_InitStructure;
    & r6 n7 u3 O7 @& k
  12.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    8 v% B8 h& T# Z5 n) N* {0 o9 b) i- K
  13.         TIM_OCInitTypeDef  TIM_OCInitStructure;
    ; J  H1 t. s2 O9 i

  14. ' }" W6 K/ [0 q! `2 Z
  15.         6 t! Z9 d; A( Y. \; |

  16. ) t; z# h2 S0 C" q- ~3 L- A
  17.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        
    3 A1 Q: B% }* ^  a0 z) m6 A+ R
  18.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG,ENABLE);
    3 N$ k8 d2 F+ `6 ]+ a3 r, Z* a
  19.         
    4 H, i' J. d. W- A6 E. N

  20. 8 q4 a( \4 l" i1 b/ f& M5 U6 [
  21. 0 O) d" o0 ]# X- [% k
  22.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7; //
    & E* I3 w) \1 F+ B7 I1 ?1 V
  23.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出# A6 d" b& ]2 f: m
  24.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;0 y; Y5 ?( I& ^4 ?9 a: [8 |
  25.         GPIO_Init(GPIOA, &GPIO_InitStructure);//TIM3通道2
    3 }. d5 O+ Z& c0 \) W- ^" {- O  P+ i
  26.         
    2 `3 Z& M- E, k0 ?& A
  27.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; //
    ' s) H$ X' V/ c6 x
  28.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //
    - o+ v  ~( h8 Q8 [9 y+ }+ O: x
  29.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;1 \$ x& }5 \8 k( S7 s
  30.         GPIO_Init(GPIOA, &GPIO_InitStructure);//TIM3通道17 S& M1 l5 R9 E+ c! q
  31.         ! Z. b" U$ }/ {5 B
  32.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                        
    1 l6 n( m5 `; _- q, g  v
  33.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 # Z0 H6 J6 h1 M7 e3 j, w
  34.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;               
    4 g8 A" A' d/ r, w* ~; h/ M( f5 @, N
  35.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         3 p* k6 N+ }: h% |; V
  36.         GPIO_ResetBits(GPIOG,GPIO_Pin_2);                                       
    9 V8 V% o. {, _/ I6 u2 N. `
  37.         
    9 D) }9 `! Q7 i
  38.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;* T# h- A, l1 m% j
  39.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                 ( W$ X# Y# Y4 a3 I. X# n6 F
  40.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   N0 U+ C# X+ h
  41.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                9 K7 ]- r9 p0 _* @3 o! J
  42.         GPIO_ResetBits(GPIOG,GPIO_Pin_3);                                                : l  e0 o, v7 u, ?9 N8 T9 m9 G
  43.         " l3 l) ?( R% d2 [4 p0 m
  44.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;                                   f1 @' g, t' G$ F! E
  45.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 
    5 \/ Z/ ]: p/ c' G! L
  46.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                 : m  w2 ]+ x5 r8 h
  47.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         7 C1 `; }9 c5 H+ z8 Q! A
  48.         GPIO_ResetBits(GPIOG,GPIO_Pin_4);                                                4 M& W7 Y, J+ U; z  Q: P9 b
  49.         
    , L6 O2 U% u1 Y8 e% o( n) A
  50.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                                
    * R3 Q" e: c# e- w" s1 j
  51.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                 & O8 G5 _& ^/ G' ~
  52.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                   V0 f4 L, N% i/ R2 p7 s
  53.         GPIO_Init(GPIOG, &GPIO_InitStructure);                                         & H. ?& o+ g. P4 f; [
  54.         GPIO_ResetBits(GPIOG,GPIO_Pin_5);                                                
    3 x1 T. o* l' }$ Q( D* e/ _
  55. ) Y8 \/ H$ ~5 h) y, S9 h( j
  56.         TIM_TimeBaseStructure.TIM_Period = arr; " V8 b/ E. r( Z% _
  57.         TIM_TimeBaseStructure.TIM_Prescaler =psc;
    + V/ `# N0 }% I3 ]3 ~
  58.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; ' Y4 R4 ]( |( l0 w
  59.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  * ?) k& d( R: h# \- g; M5 I3 x
  60.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    2 H* T0 ~# e3 x; N9 d
  61.         
    # s: o6 V9 j9 r9 t/ W0 l1 ^
  62.         * G5 z; U& d3 _$ P8 ]( b
  63.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
    * R) F( @& C( M6 e3 O+ O, B+ p' T8 e
  64.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 2 g& D* P  R4 p; {" H  S4 `) J
  65.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; ! U! A' O  J3 |4 W
  66.         TIM_OC2Init(TIM3, &TIM_OCInitStructure);  
      \  d) _8 Y& a4 H! P- w
  67. # X) O8 P, F; E
  68.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 1 ~! E3 k  s( m8 h) n, t
  69.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 7 B5 M, a$ M. R% m
  70.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    $ t( K5 w8 C* `
  71.         TIM_OC1Init(TIM3, &TIM_OCInitStructure);  
    " c% w: |$ M6 e/ L! ~# I7 v( a( _0 g

  72. ( I2 |5 ^) ?* B/ D% z

  73. 2 M% u: y( ^- E$ Q. U; V
  74.         TIM_Cmd(TIM3, ENABLE);  8 X- g  f9 N0 ~8 t$ ~4 t7 @8 C

  75. / ?. R4 w$ m4 b  p: T0 W
  76. }
复制代码
" G( n. b1 r, i# V4 K: I
上面这段代码主要是定时器TIM3的初始化以及四个输入端的初始化,至于那个预分配系数psc和自动重装值arr可以自己设定,这里我设定的是arr=450,psc=7199;大家可以自己调试,这里不细讲。( o6 l% m) b4 F9 p9 \  T8 @" g! T

# F. @8 \1 r" t" N) t2 s* l然后把PA6,PA7分别连接到ENA和ENB上,设置好arr和psc,最后通过TIM_SetComparex函数设置占空比即可实现PWM调速功能
6 J; n+ J. _6 ?& X( `2 H  R* [. I# i* L# |. Y- E
四、整体关键代码和马达连接图
2 E9 }& W! J) }
剩下一下重要代码如下:. n1 I5 Q' C/ M6 @* R* y
* O" d* X/ O; J% w7 R% l
  1. void qianjin(void)
    - P0 Z. d$ Y+ |( P) ?. R; q
  2. {
    . h( l6 L& C+ ~! K9 t
  3.         TIM_SetCompare2(TIM3,100);//设置通道2的占空比实现PWM调速,这里是100,在0~450间,越小速度越快
    * M4 {4 K* v/ B8 |$ d
  4.         TIM_SetCompare1(TIM3,100);//设置通道1的占空比实现PWM调速* G. _* V$ ]5 s& U
  5.         Ina=1;
    * _; O6 r0 y1 P! `, I
  6.         Inb=0;, W) c" I; w2 I' m6 u8 u% E  E
  7.         Inc=1;( x5 u; g5 Y" J& c% }- G
  8.         Ind=0;1 S- A2 u2 V7 m7 J% [, V2 Z
  9. }
    % y* I! I3 Q& B% R0 [  R
  10. void houtui(void)5 Q% s9 _7 R' c8 q! h4 z
  11. {
    7 h; ^6 ^* U' E2 j7 ?  d
  12.         TIM_SetCompare2(TIM3,100);
    & q+ b, y, D) p# @- s+ k. I. J2 Z  ?
  13.         TIM_SetCompare1(TIM3,100);
    - S5 u/ k" `0 T5 n0 u
  14.         Ina=0;
    & l6 d% _, J3 d* ^7 a) c7 {
  15.         Inb=1;
    1 q+ ]2 L; v+ _
  16.         Inc=0;5 F6 Q/ r/ |, r
  17.         Ind=1;5 W' \8 Z8 c) X$ J
  18. }9 M3 U' L: n! F) e
  19. void zuozhuan(void). I$ E0 C' x+ r" ~- k1 `1 V
  20. {- f1 N. n. G# T' x
  21.         TIM_SetCompare2(TIM3,100);% `; C4 H# I) a! i
  22.         TIM_SetCompare1(TIM3,100);
    ' y* Z- Z" O' j# Z2 x, V. B
  23.         Ina=0;
    . F5 d0 y; M# m) ]
  24.         Inb=0;
    - d" s8 ?; j- }  d, J( W
  25.         Inc=1;- R1 ~' Q/ w" W5 ^
  26.         Ind=0;
    * C! M  k: J- k9 g+ Q6 i* ^: Z
  27. }
    ; z, G0 }: j+ z
  28. void youzhuan(void)
    / m& u6 \/ J! \! M) a
  29. {
    + P2 D: B! J: N- t7 h2 `, K. n" u
  30.         TIM_SetCompare2(TIM3,100);
    3 `! V, v  _; [; _3 \0 v* {3 h0 J
  31.         TIM_SetCompare1(TIM3,100);/ K0 ]6 N7 F7 U, W- z- O
  32.         Ina=1;
    5 q, ~* f5 u" z! ?* m
  33.         Inb=0;# T/ Z' G) s! Z1 `4 U6 G8 D( n" n
  34.         Inc=0;; @5 |2 t. |8 q2 T
  35.         Ind=0;3 O8 w( G) o$ t6 Z
  36. }7 p3 P% E& W' g9 I5 C
  37. void stop(void)' L, d9 u2 o% @1 w  U( M
  38. {3 q- T: r- p, {0 H+ y4 j# L8 r
  39.         TIM_SetCompare2(TIM3,100);
    $ }' B, N1 k" K3 G' A! z0 u# ]. C
  40.         TIM_SetCompare1(TIM3,100);
      N' ^/ ^0 z" C$ U
  41.         Ina=0;
    ( N2 Z% |2 \9 ?, u
  42.         Inb=0;
    5 {3 [6 C, d: }5 G: z( B9 D
  43.         Inc=0;
    + o6 u, B6 C( }, Y
  44.         Ind=0;
    2 M5 m" \* p+ F2 I
  45. }
复制代码

* X  e( H9 Q! i4 C8 b/ s$ X( }% q主函数:
( k3 x! x2 N* Z" x% ~7 b) l) Q6 P7 @! ]0 W
  1. int main(void), _- Z9 ?4 J! V' E( R2 d
  2. {        ) F  Y$ ^1 K1 K. v% @1 I
  3.         vu8 key=0;* C3 S9 G( g; a; ]7 @8 V3 O
  4.          $ s/ ~& e$ e6 f/ f" D
  5.         delay_init();            //          , R" m8 |; a, ]
  6.         LED_Init();                          //6 Y9 D2 p. ?* n
  7.         KEY_Init(); //
    9 N" `8 U) E% m+ u$ B3 \
  8.     TIM3_PWM_Init(450,7199);
    7 X8 k- N  c1 a9 E8 w  F( {6 t1 K. T
  9.         while(1)4 g5 A& e- |/ w, O$ f, P( h
  10.         {
    3 [* ]. G) B7 s8 d
  11.            key=KEY_Scan(0);        //通过按键简单实现
    + a3 S8 c* F7 u- z$ m9 ^
  12.                    if(key): S( B: T3 i& T, r
  13.                 {                                                   * D! O! l5 Q/ }* C9 B1 S8 s* m# C8 u
  14.                         switch(key)$ N# a. {. ]  Y) u
  15.                         {                                 
    2 A7 O9 p1 Y$ Q5 f" |2 J4 {
  16.                                 case WKUP_PRES:        
    ' |- U# u& D% n" D
  17.                                      LED0=0;% V& P8 {2 I& H$ T7 [/ `4 n
  18.                                      qianjin();& L1 U8 h# |. Q  {& {3 L7 I# a
  19.                                          break;
    , l, N7 e6 ?+ H0 `
  20.                                 case KEY1_PRES:        //   {' ]' P! u1 m- s! L$ Z
  21.                                      qianjin();
    + i( d7 P  V2 L3 m' H
  22.                                          delay_ms(5000);
      s5 F$ e+ ?9 S7 q
  23.                                          delay_ms(5000);+ ]1 q: Y7 ^( s9 g
  24.                                          delay_ms(5000);
    % i2 `& \' S; p) k, W
  25.                                      houtui();
    1 n* K* j7 f; ^( v% B3 p6 x9 z
  26.                                          delay_ms(5000);
    / }7 H3 d' B% z- {
  27.                                          delay_ms(5000);
    * b4 S9 g. t3 ?& u  w
  28.                                          delay_ms(5000);
    : j& X0 x- b. M+ l! l% I
  29.                                          break;4 s# _  p& A1 T) W, o
  30.                                 case KEY0_PRES:        4 y3 }, n0 ^  w. K" e
  31.                                          LED0=1;- Y* N& o( U! s/ k. }/ E
  32.                                  stop();
    : ?( `5 x+ q. M9 {7 W, K
  33.                                          break;6 R7 e7 A" T1 V0 i& P
  34.                         }
    0 \, ]) W" v% M8 ?8 u2 Y
  35.                 }! f# Z3 s$ f* v6 k' Y
  36.                 else delay_ms(10);
    3 H5 _& L5 E/ E  o6 o7 t9 `% k
  37.             
      v! E& h: N& j- w4 _
  38.                 6 O& l: [( K# x) I2 t
  39.         }  L: J; `* F/ k* a0 [' I
  40. }
复制代码

4 T9 m( @5 W# A+ t9 U8 ?9 u以上是简单的代码实现,大家可以根据自己实际情况调整修改' h0 e. Y0 u9 ^+ v5 k2 G, _

& ?/ a7 g2 e- I- Z+ L+ N1 U下面是实物连接图:
2 J3 B% b* h2 e  `; c+ i4 ~
, w0 i' _) S6 f2 D  M ~3O~2TCPP3P48296G556`(2.png
! z) n; e9 j5 r" [# p8 P' T$ A& B- P$ c5 `2 B
这里用另一个L298N来连接,原理一样的,我另外那个红色版的螺丝不好拧,就暂且用这个,这里我用这个电机驱动4个马达,特别注意单片机和电机上的GND是连在一起的!
. ~0 t% I+ g! }5 D/ T. y( f9 }
: \" ]6 j. _: I  r: c8 f- y那个连接单片机的图片就不发了,具体按上述代码操作,不明白的地方可以留言或者哪里写的不对欢迎指正,谢谢!4 s1 X% w! {: S4 U/ c* L

9 O8 x: m2 \( Y% o* W# y" |4 }' E8 u
* H" w( S6 O# i. K3 k
收藏 评论0 发布时间:2022-5-14 20:41

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版