STM32学习笔记(6):PWM控制

PWM控制

PWM方波

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

PWM它是一系列脉冲,这些脉冲将以方波的形式出现。在任何给定的时间点,波型要么是高电平或者是低电平。

信号保持在高电平的持续时间称为“接通时间”,信号保持在低电平的持续时间称为“断开时间”。对于PWM信号我们需要关注两个与之相关的重要参数,一个是PWM占空比,另一个是PWM信号的频率。

1.PWM占空比

PWM信号在特定的时间内保持接通状态,然后在剩余的时间内保持断开状态。占空比是指在一个脉冲循环内,接通时间相对于总时间所占的比例。在一段连续工作时间内脉冲高电平时间与总时间的比值。如果信号总是处于高电平,它的占空比是百分之百;如果信号总是处于低电平,那么它的占空比是0%。计算占空比的公式如下所示:

占空比 = 接通时间 / 总持续时间 = 接通时间 / (接通时间 + 断开时间)

STM32学习笔记(6):PWM控制_第1张图片

通过控制从0%到100%的占空比,我们可以控制PWM信号的“接通时间”,从而控制信号的宽度。由于我们可以通过调节脉冲信号的宽度控制接通时间,所以将这种控制方式称为“脉冲宽度调制”。

2.PWM的频率

PWM信号的频率决定了PWM完成一个信号周期的速度。周期是指PWM信号完成一个接通和关闭的时间。计算频率的公式如下所示

频率 = 1 / 总持续时间

3.PWM的产生

单片机产生PWM,有以下几种方法:

  • 指令生成PWM,可产生分辨率很高的PWM,但会影响其他任务运行,一般用在较简单的控制中
  • 定时器产生PWM
  • 部分单片机本身具有PWM模块功能

定时器

1.定时器功能

定时、输出比较(PWM)、输入捕获(测量脉冲宽度)、互补输出

2.定时器分类

基本定时器、通用定时器、高级定时器

3.定时器资源

F103系列有两个高级定时器TIM1和TIM8、4个通用定时器TIM2~5、2个基本定时器

基本定时器(TIM6,TIM7)的主要功能

  • 基本的定时功能

  • 包含一个16位自动装载计数器,由各自的可编程预分频器驱动

通用定时器(TIM2~TIM5)的主要功能

  • 基本的定时器的功能
  • 测量输入信号的脉冲长度( 输入捕获)
  • 产生输出波形( 输出比较和PWM)

高级定时器(TIM1,TIM8)的主要功能

  • 具有基本,通用定时器的所有功能
  • 具有控制交直流电动机所有的功能,如输出6路互补带死区的信号、刹车功能等等

PWM控制电机

引脚查询

博主采用如下开发板进行学习STM32的编程,其中封装了两块TB6612电机驱动和四个预留的编码器电机接口。

STM32学习笔记(6):PWM控制_第2张图片
STM32学习笔记(6):PWM控制_第3张图片

对原理图做如下分析:

  • 六线电机接口:
    • 1线和6线为电机控制线,控制电机方向
    • 2线至5线为编码器线
  • 驱动芯片U8
    • 连接控制电机接口MOTORA和MOTORB
    • PA2、PA3控制电机接口MOTORA上方向
    • PA4、PA5控制电机接口MOTORB上方向
    • PC6和PC7控制电机A和B的PWM方波输出
  • 驱动芯片U9
    • 连接控制电机接口MOTORC和MOTORD
    • PC5、PE12控制电机接口MOTORC上方向
    • PB11、PB15控制电机接口MOTORD上方向
    • PC8和PC9控制电机C和D的PWM方波输出

博主主要采用MOTORA和MOTORB进行控制两个12V直流有刷电机。

设置引脚

打开CubuMX配置控制电机方向的四个引脚(PA2、PA3、PA4、PA5)为输出模式。

随后,采用定时器控制输出PWM方波。对于电机A的PWM方波输出引脚PC6设置为TIM8_CH1;对于电机B的PWM方波输出引脚PC7设置为TIM8_CH2。

STM32学习笔记(6):PWM控制_第4张图片

如上图所示,处于定时器控制的引脚颜色为黄色说明相关配置尚未完成,存在错误。此时需要进一步配置8号定时器的通道1和通道2。点击上方Pinout&Configuration子页面并点击左侧Timers选项卡,选择TIM8

在中间弹出菜单中将Channel1Channel2分别设置为PWM Generation CH1PWM Generation CH2,此时右侧Pinout View中引脚PC6和PC7将变回绿色。

最后,需要修改定时器的计数周期。在页面下方选择Parameter Settings并修改其下参数Counter Period为7200-1。

此处需要说明,由于博主设置单片机频率为72MHz,对应表明单片机1s中执行了72 000 000次。故而计数周期7200的含义为每7200次(0.1ms),进行一次定时器任务。由于计数从0开始,故而需要减一。

STM32学习笔记(6):PWM控制_第5张图片

配置完成后,需要点击右上角GENERATE CODE重新生成程序。

电机PWM控制

1.开启定时器

首先需要在主程序中开启定时器,采用函数HAL_TIM_PWM_Start()进行。

/**
  * @brief  Starts the PWM signal generation.
  * @param  htim TIM handle
  * @param  Channel TIM Channels to be enabled
  *          This parameter can be one of the following values:
  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)
  • 参数一 *htim:定时器标号,指针
  • 参数二Channel:通道数

2.设置电机方向

随后,需要设置控制占空比

//控制电机A方向(正转)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_RESET);
//控制电机A方向(反转)
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_2,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_3,GPIO_PIN_SET);

3.速度PWM设置

开启定时器后,需要设置对应定时器通道的占空比,用于设置PWM。采用函数__HAL_TIM_SET_COMPARE()进行

/**
  * @brief  Set the TIM Capture Compare Register value on runtime without calling another time ConfigChannel function.
  * @param  __HANDLE__ TIM handle.
  * @param  __CHANNEL__ TIM Channels to be configured.
  *          This parameter can be one of the following values:
  *            @arg TIM_CHANNEL_1: TIM Channel 1 selected
  *            @arg TIM_CHANNEL_2: TIM Channel 2 selected
  *            @arg TIM_CHANNEL_3: TIM Channel 3 selected
  *            @arg TIM_CHANNEL_4: TIM Channel 4 selected
  * @param  __COMPARE__ specifies the Capture Compare register new value.
  * @retval None
  */
#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)
  • 参数一 _HANDLE_:定时器标号,指针
  • 参数二 _CHANNEL_:通道数
  • 参数三 _COMPARE_:发送次数

其中发送次数是指在计算周期内,一共发送多少次。如在7200次计数中发送5000,其占空比=5000/7200:

//控制占空比 在配置的7200次计数中 5000次发送
__HAL_TIM_SET_COMPARE(&htim8,TIM_CHANNEL_1,5000);

4.控制电机正转

对上述代码进行整合,控制电机A和电机B正转代码如下:

  /* USER CODE BEGIN 2 */
  //  开启电机A的PWM输出定时器
  HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_1);
  //  电机A设置正转
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
  //  设置占空比 计数周期(7200)内,一共发送3000次
  __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_1, 3000);
  
  //  开启电机B的PWM输出定时器
  HAL_TIM_PWM_Start(&htim8, TIM_CHANNEL_2);
  //  设置电机B正转
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
  //  设置占空比 计数周期(7200)内,一共发送3000次
  __HAL_TIM_SET_COMPARE(&htim8, TIM_CHANNEL_2, 3000);
  
  /* USER CODE END 2 */

修改占空比可以控制电机旋转速度,而修改引脚上高低电平则可以控制电机正反转。

PWM控制舵机

对于舵机,一般其接收的PWM信号频率为50Hz,即20ms。当高电平的脉宽在0.5ms-2.5ms之间时舵机就可以对应旋转到不同的角度。

STM32学习笔记(6):PWM控制_第6张图片

由于单片机设置的频率为72MHz,即1s运行72 000 000次程序

则计数周期20ms应表示被每秒执行72000 * 20

采用这种方式过于繁琐,为进一步简化计算引入分辨系数的概念。

分频系数

为较为简便的得到50Hz的频率,引入分配系数的概念。根据单片机运行频率72MHz,设置分频系数为72,计数周期如下表示:

1 s 72 MHz 每1 s执行72 000 000次
0.1 ms 7 200 Hz 每0.1 ms执行7 200次
1 ms 72 000 Hz 每1 ms执行72 000次
20 ms 72 000 * 20 Hz 每20 ms执行 72 000 * 20次

72 000 * 20 = 72 * 20 000 Hz
即设分频频率为72时,计数周期为20 000

按照前面的规定,我们如果想要在20ms周期中得到0.5ms的高电平,那么PWM的占空比的计算方式应该如下:

# 舵机0°

0.5 ms / 20 ms = PWM / 20 000
PWM = 0.5 ms / 20 ms * 20 000 = 500

# 舵机45°

1 ms / 20 ms = PWM / 20 000
PWM = 1 ms / 20 ms * 20 000 = 1 000

# 舵机90°

1.5 ms / 20 ms = PWM / 20 000
PWM = 1.5 ms / 20 ms * 20 000 = 1 500

# 舵机135°

2 ms / 20 ms = PWM / 20 000
PWM = 2 ms / 20 ms * 20 000 = 2 000

# 舵机180°

2.5 ms / 20 ms = PWM / 20 000
PWM = 0.5 ms / 20 ms * 20 000 = 2 500

引脚查询

博主所用开发板上预留4路舵机控制如图所示。

STM32学习笔记(6):PWM控制_第7张图片

舵机一般包含三根线:

  • 棕色线(或黑色):负极线接GND
  • 红色线(或白色):正极线接VCC
  • 橙色线(或灰色):信号线

STM32学习笔记(6):PWM控制_第8张图片

取PE9引脚用于信号控制

设置引脚

打开CubeMX配置PE9引脚为定时器模式,选取TIM1_CH1。随后,Pinout&Configuration页面左侧Timers选项卡下的TIM1选项,配置其下通道1为PWM Generation CH1

STM32学习笔记(6):PWM控制_第9张图片

随后,在下方Parameter Settings中设置**Prescaler(分频系数)**为72-1;**Counter Period(计数周期)**为20000-1。

配置完成后,需要点击右上角GENERATE CODE重新生成程序。

舵机PWM控制

  /* USER CODE BEGIN 2 */
  //  开启舵机定时器
  HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_3);
  //  驱动舵机
  //  0°
  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 500);
  //  等待2s
  HAL_Delay(2000);
  //  45°
  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 1000);
  //  等待2s
  HAL_Delay(2000);
  //  90°
  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 1500);
  //  等待2s
  HAL_Delay(2000);
  //  135°
  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 2000);
  //  等待2s
  HAL_Delay(2000);
  //  180°
  __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, 2500);
  //  等待2s
  HAL_Delay(2000);
  /* USER CODE END 2 */

你可能感兴趣的:(STM32,stm32,单片机,arm)