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

PWM控制

PWM方波

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

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

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

1.PWM占空比

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

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

在这里插入图片描述

通过控制从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电机驱动和四个预留的编码器电机接口。

在这里插入图片描述
在这里插入图片描述

对原理图做如下分析:

  • 六线电机接口:
    • 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。

在这里插入图片描述

如上图所示,处于定时器控制的引脚颜色为黄色说明相关配置尚未完成,存在错误。此时需要进一步配置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开始,故而需要减一。

在这里插入图片描述

配置完成后,需要点击右上角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之间时舵机就可以对应旋转到不同的角度。

img

由于单片机设置的频率为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路舵机控制如图所示。

img

舵机一般包含三根线:

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

在这里插入图片描述

取PE9引脚用于信号控制

设置引脚

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

在这里插入图片描述

随后,在下方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 */
  • 9
    点赞
  • 117
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嗨!对于学习STM32笔记,我可以给你一些基本的指导。首先,你需要了解STM32是一系列由STMicroelectronics公司开发的32位微控制器。它们具有广泛的应用领域,包括嵌入式系统、物联网和工业自动化等。 在学习STM32时,你可以按照以下步骤进行: 1. 硬件准备:获取一块STM32开发板,例如STM32F4 Discovery或NUCLEO系列。这些开发板通常带有一些外设和接口,便于学习和实验。 2. 开发环境搭建:下载并安装Keil MDK或者IAR Embedded Workbench等集成开发环境(IDE)。这些IDE提供了编译器、调试器和其他工具,方便你编写和调试STM32的代码。 3. 学习基本知识:了解STM32的体系结构、寄存器和外设等基本知识。可以通过阅读相关的参考手册、数据手册和应用笔记来深入了解。 4. 编写代码:使用C/C++语言编写STM32的应用程序。你可以使用相关的库函数来简化开发过程,如标准外设库(StdPeriph Library)或者新的STM32Cube库。 5. 调试和测试:使用调试器和仿真器来调试和测试你的代码。这些工具能够帮助你单步执行代码、观察寄存器和内存的状态,以及检查外设的操作。 6. 实践项目:尝试一些小型的项目,如LED闪烁、按键输入和PWM输出等,以巩固你的学习成果。随着经验的积累,你可以尝试更复杂的项目,如通信接口、传感器应用和无线通信等。 记得在学习过程中多查阅官方文档、参考资料和在线论坛,以便解决遇到的问题。祝你学习STM32的旅程愉快!如果你有具体的问题,欢迎随时向我提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值