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

STM32F103C8T6+L298N通过PWM控制直流电机转速

[复制链接]
STMCU小助手 发布时间:2022-11-1 15:57
前言1 v7 z1 n. [9 q' C( m* K
原来做的差速小车是基于Arduino控制的,感觉有些简单,也有些基础,Arduino方便简单的同时,可操作性感觉也少了很多,所以想将控制器换成STM32,然后将树莓派作为上位机,STM32作为下位机,通过树莓派和STM32进行通讯,实现对差速移动小车的控制,本人也是寒假期间初学STM32,也是奔着应用去的,所以对于STM32编程原理方面可能不太精通,这里偏重于记录应用层面的知识。; ^6 S: t$ p: v: j0 X. o# A9 i
1 c; F9 w/ T( n( h' x# E1 @
一、PWM调速原理
& v8 s& k$ o: a7 J( W' J; J直流电机驱动是最简单的,给电机通上电就能转,根据电机的公式:
! Z$ {* v' O2 U2 |9 q
1 ?9 z- M. |: G2 m0 Q K([]3$@[2CC}E]5`K2VUCXQ.png 0 x* |& W7 b7 r0 P+ k% N9 E

8 }+ Y: L# T0 d5 D  q9 A( U3 |可知:当提高电压时,反电势升高,进而转速升高,电压与转速大致有如图所示的关系* v1 U- v3 `4 Y5 F$ Z

& K( `5 S  G7 ?) \; Y abb0e5e55fbd41d3bf80a0c3b786c636.png . X- p( g& R, Z2 ]! g

! I, y7 H. u2 K  h6 D# Q* x0 U$ E所以我们只要控制给电机通电的电压即可控制电机的转速,但是在实际的控制中,控制直流电机需要通过H桥控制电机的正反转,如图,当T1和T4二极管导通时,有粉色通路;当T2和T3二极管导通时,有蓝色通路,这样我们就可以实现弱电控制强电,通过二极管的通断来控制电机的转向。
% l( T8 ?/ C7 M3 d4 s2 i% _
- [4 q$ a7 v5 G5 n. b但是这样电机通电时电压就是Us,我们如果想自由的控制Us的电压值基本是不能实现的,因为电机是接到单片机的引脚上的,引脚的供电电压值是确定的,我们就要使用控制二极管的通断时间对电机的转速进行控制,即PWM控制。
  E$ O" {" a. I- b$ f; s1 V
& p- H' F% r5 g图中的D1~D4二极管为续流的作用,因为电机中有绕组,在断电后,电感的电流不能瞬时变为0,所以在断电后电流沿棕色和绿色的通路放点。
( d- x+ g* x9 }5 z9 ?! _3 K7 x- G3 c7 T
fdfb9e01ebf44892b29da3b6b44fcb75.png 4 {. \# R: X& N. m; w

% j8 I$ T" J- C) ]* |% m d82be034a45043beb011032eebbf1569.png
4 G, W$ Q  x# k6 y' [7 U0 P6 U/ x* p, D2 c/ o8 F
在一个周期内,我们通过控制通电的时间就可以调控平均电压,而平均电压的高低直接控制电机的转速,通电时间/周期,就可以得到占空比,我们也就是通过控制电机的占空比来控制电机的转速的。
4 o5 D. e4 X' h; ^4 D8 W
/ i! U0 e; _$ ]7 c1 g; @' f9 i4 |. G 8d1111caaea041fca59258e9c11af1f4.png 1 J! l$ C. v$ m0 v  F: j$ D& q
* w& }% }  F9 e! A6 I' B
在实际应用过程中,我们不用自己搭建H桥,而是使用电机驱动板(如:L298N)对直流电机进行驱动,L298N内搭载两个H桥电路,可以实现对两个电机的转向和转速进行控制。* L9 r( V# p" |3 q9 R1 y. }

/ B3 F% u9 }9 T$ e& a f9dbeeb361534857a4944e3f8bb5acdc.png 4 u2 n6 ?; @! r5 d: @
) s9 v% Z) K: _2 F/ e( v4 B
这是淘宝商家提供的电机驱动板控制表,将IN1~4接到单片机的引脚,我们就可以通过引脚输出PWM控制信号,对直流电机进行控制。; Y- `6 P$ O0 `2 f, k* _
( o- E4 K( E8 Y8 J/ N" ?, n
二、STM32编程实现& _- X( t5 }& q% X/ a3 p$ y
在STM32中如果想输出PWM信号,需要借助定时器,通过定时器的捕获/比较通道的PWM输出2 x$ m( Q/ w$ P4 ?5 X

, ^" W: H# ]+ d+ z& v, g fe3401a0430c448a93df615bb13ce127.png
1 k+ {0 J1 k0 z* o- C
+ F2 O$ G8 G# G$ S5 z" c 当我们对定时器设置了预装载值arr和比较值ccr后,可以通过配置PWM模式,使定时器CNT计数值超过ccr后产生有效信号,并通过配置相应寄存器设置有效信号是1还是0,而配置PWM的输出方式,具体原理信息可以参考原子哥的视频,也可以参考中文参考手册的14.4.7内容。
8 l( O# S4 y8 {/ B0 ~0 B; U) P, R! h! K1 R+ z# x# `0 B
78a1f1c52ee2438996f36a9ab63b49a6.png 5 B8 {0 M7 j; m( a$ n5 `4 _' q
1 Y; s% i3 r' a
在程序中,我们使用库函数进行配置,配置步骤如下:1 Q8 F8 @8 ]0 L: e2 @5 }- n
1.使能定时器和相关外设引脚时钟 :RCC_APBxPeriphClockCmd(): H. t$ n  d' x  n0 s! s: ^* `
2.配置IO口为复用输出模式(查手册8.1.11)配置成相应的模式(复用推挽输出)4 D# \- T: a% `5 u/ b6 z% _, L
3.初始化定时器:TIM_TimeBaseInit()9 S' ?( |  z8 @! R  c2 L9 x4 T
4.初始化TIM2 Channe1234 PWM模式:TIM_OCxInit()
; M: \9 o( d* w5 b5.使能OCx通道的预装载寄存器:TIM_OC1PreloadConfig()0 P) D) }2 u# Y+ u( S) s
6.使能时钟:TIM_Cmd()
9 G7 \9 B0 A7 V* s/ N. s7.在主函数中配置占空比进行调速:TIM_SetCompare1()
! _& z3 m' t3 J6 A$ B+ X" C3 D
  1. #include "sys.h"
    ( n! h$ s: ^2 e2 i3 Z) M

  2. ) t& ?- e% b" |4 e  \. T
  3. /********************, A4 g8 [5 [* G8 a1 G7 W. D+ r; ]1 A
  4. 功能:通用时钟2用来产生通道1234四路PWM信号
    8 O1 q$ C0 B" ?0 v8 P; f4 `$ U/ Q( W0 t
  5. 函数:TIM2_PWM_Init(u16 arr,u16 psc)
    , H: K4 H' S- W0 w/ }' w
  6. 作者:K.Fire
    7 J  x: J* @: F7 E& N
  7. 日期:2022.01.30' b$ F9 A, Z7 r9 `
  8. 引脚:PA0 PA1 PA2 PA3
    % }6 O3 e, X, u
  9. 参数:arr:自动重装值 psc:时钟预分频数
    + g/ T: l3 X4 J* s% G6 L- ~6 e9 w  G
  10. *****************/
    3 A2 y" D, e* t( Z# @8 r0 I$ J" A
  11. 2 @* S& _0 H: M5 H' R- D
  12. void TIM2_PWM_Init(u16 arr,u16 psc)9 v9 @# J9 M4 |9 H
  13. {  6 e/ G( G: _, U% V  ~2 q
  14.         GPIO_InitTypeDef GPIO_InitStructure;5 t3 D5 }( Y2 k  C  _" }# Z1 |
  15.         TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    * M& G* K( L3 E. R" t+ \
  16.         TIM_OCInitTypeDef  TIM_OCInitStructure;
    : U! ?+ `5 C/ E! Z. b. A" Y
  17.         . E1 P$ B- X  `- l" Q+ t- |
  18.         //使能GPIOA外设模块时钟  
    8 h$ {/ k; r: a; |& W4 \- h- F
  19.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   
    7 Q+ G3 C$ z" P
  20. , x# Q/ M6 C7 f" _4 i9 O
  21.         //设置引脚为复用输出功能,输出TIM2 CH1的PWM脉冲波形        GPIOA.0
    8 T. i4 u& z$ A! Z7 n
  22.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //TIM2_CH1% w1 ~* j: ?" z
  23.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出' {7 @5 _3 [/ Y  E+ z* D# `
  24.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    - i5 d7 m/ ]& K% h+ i  j
  25.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
    8 \2 n, `  v8 z
  26.         / {1 \: A0 p) h
  27.         //设置引脚为复用输出功能,输出TIM2 CH2的PWM脉冲波形        GPIOA.1; }' M  s/ V: v, g& K1 U" K  `. C
  28.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //TIM2_CH2: O; i( @! y/ e
  29.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO, \+ x7 k! X' [) h/ p( p$ M
  30.         
    2 z2 W2 `% S% ~; z# M) ^& y
  31.     //设置引脚为复用输出功能,输出TIM2 CH3的PWM脉冲波形        GPIOA.2, N. F3 j) A  [: |6 |& }6 W9 b. e
  32.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM2_CH3) ?( |4 e0 o; V6 l5 i7 {/ D
  33.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO% `( [( j& h8 M7 C* b  m
  34.         
    : C3 s' F$ ?$ K7 s
  35.         //设置引脚为复用输出功能,输出TIM2 CH4的PWM脉冲波形        GPIOA.3; @4 x6 o4 k) ]/ B1 Y/ N2 U9 u8 U5 x5 e
  36.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //TIM2_CH4
    & F3 M3 ]+ B8 `+ k
  37.         GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
    2 O+ \0 G7 p  U: d, X4 E3 \
  38. / M5 ?0 J1 C  N
  39.         //使能定时器2时钟
    8 w; Z8 x' U, }& h- u9 r
  40.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);        4 l! l( Q8 y( x
  41.     //初始化TIM24 B* R/ |# W" g: e) A* R6 ^
  42.         TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
    $ C" ]' ^9 t! S! z
  43.         TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 1 \8 ]" y6 W4 f* v& F
  44.         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim9 [% D: m+ r  @; j7 K; l5 a+ l
  45.         TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式( G; o7 H8 d/ d' X! A0 n4 a
  46.         TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
    9 Z+ |! N& ~0 V
  47.         
    + j3 [6 D+ ~% t, Z( i0 r5 h( P+ s) e
  48.         //初始化TIM2 Channe1234 PWM模式         ! `" {; p0 t. B8 q1 i
  49.         TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式21 I2 }1 m! G* x4 S; ]* P# a! u7 j. {
  50.          TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    & _) k/ ?  F# S
  51.         TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高/ d0 B4 H4 p" ?7 ~8 B
  52.         
    * N. a- a4 M# Z# G
  53.         TIM_OC1Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC1
    & y; A/ c, Z2 B5 Z% p
  54.         TIM_OC2Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC2
    1 H* h! D: m6 p% }
  55.         TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC3/ K) x( _$ I! z8 [
  56.         TIM_OC4Init(TIM2, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM2 OC4
    # W3 m0 }" L4 c9 N0 e

  57. 5 z0 I. Z% h" u5 a, u$ C0 V
  58.         TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR1上的预装载寄存器
    , V* ^6 r6 m% N' D$ E5 A
  59.         TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR2上的预装载寄存器: r% z9 K; x& p1 C
  60.         TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR3上的预装载寄存器& j0 x- ]0 a5 E4 j
  61.         TIM_OC4PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM2在CCR4上的预装载寄存器
    8 s( [( R/ a/ Z8 S

  62. 7 z' l' s3 a4 H" t
  63.         TIM_Cmd(TIM2, ENABLE);  //使能TIM2
    * i+ M8 I- Q* V' Y
  64.         ; Z) R! I$ n0 a1 J
  65. }
复制代码

& s* a8 p, ?2 S/ A4 X- |总结
' x. n8 A0 ]( Y8 ~( q9 [$ `) C原理部分我讲的不清晰,我也是看原子哥的视频学的,大家可以通过传送门去B站看原子哥的视频,先更新PWM调速,因为这一部分我测试成功了,等我编码器来了在对编码器和蓝牙进行测试。) {( r4 v0 E  S
————————————————# U7 x- Q3 P! O# k+ [+ w
版权声明:K.Fire浑身是肝
# F  j: m% O. L; P6 o. `
; |6 _5 n5 L' @  o- I+ L6 Y: u0 V7 N$ @% a9 j+ z
赞 收藏 评论0 发布时间:2022-11-1 15:57

举报

0个回答

所属标签

相似技术帖

官网相关资源

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