STM32实现PWM输出与PWM输入捕获(HAL库)

2023-05-16

文章目录

  • 一. 前言
  • 二. STM32 定时器
    • 2.1 基本定时器
      • 2.1.1 功能与框图
      • 2.1.2 CubeMX配置
    • 2.2 通用定时器
      • 2.2.1 功能与框图
      • 2.2.2 CubeMX配置
    • 2.3 高级定时器
      • 2.3.1 功能与框图
      • 2.3.2 CubeMX配置
  • 三. 开发环境
  • 四. STM32 PWM输出
  • 五. STM32 PWM输入捕获
  • 五. 实战项目

一. 前言

前段时间,由于项目原因需要驱动四线风扇(电脑CPU用的散热风扇大多就是四线风扇),打算做一块风扇的驱动板。风扇通过输入PWM波来控制电机输出,而风扇内置了霍尔传感器,可以输出PWM信号,通过捕获波形信号可以得到信号的占空比、周期、频率等信息,换算后可以得到风扇的转速,实现对风扇的闭环控制。

过程主要使用STM32的定时器实现PWM输出与PWM捕获,项目完成后就把这两个知识整理后写成这篇博客。

二. STM32 定时器

STM32定时器可以分为:基本定时器通用定时器高级定时器,以STM32F1为例:

定时器类型定时器型号定时器总线定时器功能
基本定时器TIM6
TIM7
APB11. 拥有定时中断。
2. 主模式触发DAC的功能。
通用定时器TIM2
TIM3
TIM4
TIM5
APB11. 拥有基本定时器全部功能。
2. 具有内外时钟源选择。
3. 输入捕获。
3. 输出比较。
4. 编码器接口。
5. 主从触发模式等功能。
高级定时器TIM1
TIM8
APB21. 拥有通用定时器全部功能。
2. 具有重复计数器。
3. 死区生成。
4. 互补输出。
5. 刹车输入等功能。

它们之间的关系是:通用定时器具备基本定时器的所有功能并额外增加功能,高级定时器具备通用定时器所有功能并额外增加功能。

2.1 基本定时器

2.1.1 功能与框图

基本定时器TIM6和TIM7各包含一个16位自动装载计数器,由各自的可编程预分频器驱动。其主要功能包括:
  ● 16位自动重装载累加计数器 。
  ● 16位可编程(可实时修改)预分频器,用于对输入的时钟按系数为1~65536之间的任意数值分频 。
  ● 触发DAC的同步电路 。
  ● 在更新事件(计数器溢出)时产生中断/DMA请求 。

2.1.2 CubeMX配置

以TIM6为例,在STM32CubeMX中通过以下参数设置基本定时器:

2.2 通用定时器

2.2.1 功能与框图

通用定时器主要功能包括:
  ● 16位向上、向下、向上/向下自动装载计数器。
  ● 16位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为1~65536之间的任意数值。
  ● 4个独立通道:
  - 输入捕获
  - 输出比较
  - PWM生成(边缘或中间对齐模式)
  - 单脉冲模式输出
  ● 使用外部信号控制定时器和定时器互连的同步电路。
  ● 如下事件发生时产生中断/DMA:
  - 更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)
  - 触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)
  - 输入捕获
  - 输出比较
  ● 支持针对定位的增量(正交)编码器和霍尔传感器电路。
  ● 触发输入作为外部时钟或者按周期的电流管理。

2.2.2 CubeMX配置

2.3 高级定时器

2.3.1 功能与框图

高级定时器在涵盖通用定时器所有功能的同时,多出如下特性:

  ● 死区时间可编程的互补输出。
  ● 允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器。
  ● 刹车输入信号可以将定时器输出信号置于复位状态或者一个已知状态。
  ● 刹车信号输入事件发生时产生中断/DMA。

2.3.2 CubeMX配置

笔者用得不多,在此不作介绍。

三. 开发环境

开发环境: Keil 、CubeMX
软件版本: 5.31 、6.2.1
使用芯片: STM32F103C8T6
开发语言: C

四. STM32 PWM输出

PWM的输入输出需要使用通用定时器或者高级定时器。STM32F103C8T6有4个定时器,其中TIM1为高级定时器,TIM2、TIM3、TIM4为通用定时器,没有基本定时器,因此随便选择即可。

这里选择定时器TIM2,打开Channel1 选择功能PWM Generation CH1


配置参数如下:

注意:

PWM频率计算公式:

F = T i m e r C l o c k ( P r e s c a l e r + 1 ) ∗ ( C o u n t e r P e r i o d + 1 ) F=\frac{TimerClock}{(Prescaler+1)*(CounterPeriod+1)} F=(Prescaler+1)(CounterPeriod+1)TimerClock           (1)

PWM周期计算公式:

T = 1 F = ( P r e s c a l e r + 1 ) ∗ ( C o u n t e r P e r i o d + 1 ) T i m e r C l o c k T=\frac{1}{F}=\frac{(Prescaler+1)*(CounterPeriod+1)}{TimerClock} T=F1=TimerClock(Prescaler+1)(CounterPeriod+1)    (2)

若有效电平为High,采用PWM模式一时,PWM占空比计算公式:

D u t y = C C R x C o u n t e r P e r i o d + 1 Duty=\frac{CCRx}{{CounterPeriod}+1} Duty=CounterPeriod+1CCRx                               (3)

若有效电平为High,采用PWM模式二时,PWM占空比计算公式:

D u t y = C o u n t e r P e r i o d + 1 − C C R x C o u n t e r P e r i o d + 1 Duty=\frac{CounterPeriod+1-CCRx}{{CounterPeriod}+1} Duty=CounterPeriod+1CounterPeriod+1CCRx                     (4)

若有效电平为Low,则上述(3)、(4)公式变为1-Duty,计数方式(向上向下计数)并不影响占空比的计算公式 。

其中TimerClock为对应定时器的时钟频率;Prescaler为预分频系数;CounterPeriod为重装载值;CCRx为比较寄存器的值,在代码工程中可以使用函数__HAL_TIM_SetCompare()修改CCRx的值从而修改PWM的占空比。

PWM模式一: 在PWM1模式下,无论是向上计数还是向下计数,TIMx_CNT<TIMx_CCR1时通道1为有效电平,有效电平可以在 CH Polarity 参数中设置。

PWM模式二: 在PWM2模式下,无论是向上计数还是向下计数,TIMx_CNT>TIMx_CCR1时通道1为有效电平。

初始脉冲宽度(Pulse): 脉冲宽度即高电平持续的时间,Pluse与CounterPeriod+1的比值即为PWM的初始占空比。

自动预重装载(auto-reload preload): 当使能自动预重装载时,自动重装载寄存器写入新值后,计数器立即产生计数溢出,然后开始新的计数周期;当不使能自动预重装载时,自动重装载寄存器写入新值后,计数器完成当前旧的计数后,再开始新的计数周期。

假设采用如上配置,配置TIM2通道一作为PWM输出,只需在代码工程中调用如下两条函数便可以实现PWM的控制。

HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_1);//初始化,开启PWM

__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1,1000);//设置比较寄存器CCRx的值,占空比=CCRx/ARRx 此处 CCRx=1000,ARRx=65536

五. STM32 PWM输入捕获

定时器的PWM输入捕获的框图如下,由通用定时器的框图剪裁得到(去掉了一些与输入捕获无关的功能):


PWM输入捕获流程如下:
1. PWM信号由TIMx_CH1进入,依据是上升沿还是是下降沿从而触发TI1FP1或TI1FP2。
2. 当捕捉到第一次上升沿时,触发TI1FP1,计数器复位,计数值CNT清零。
3. 当捕捉到下降沿时,触发TI1FP2,CNT计数值在TIMx_CH2中被记录到TIMx_CCR2寄存器中。
4. 当再次捕捉到上升沿时,触发TI1FP1,CNT计数值在TIMx_CH1中被记录到TIMx_CCR1寄存器中,同时计数器复位,计数值清零。
5. 依据TIMx_CCR1、TIMx_CCR2的值便可以计算PWM的周期、频率、占空比。TIMx_CCR1的值就是周期, T I M x C C R 2 T I M x C C R 1 \frac{TIMxCCR2}{TIMxCCR1} TIMxCCR1TIMxCCR2的值就是占空比。

关于PWM的输入捕获,有两种CubeMX的配置方式,虽然配置方式不一样但是效果和原理都是完全一致的

方法一:

这是网上大多数帖子的推荐配置,非常麻烦,这里不推荐使用。


方法二(推荐使用):

方法二与方法一原理与效果是一样的,只不过ST官方考虑到PWM输入捕获较为常用,可以一键配置。只需在Combined Channels中选择PWM Input on CH1同时打开定时器中断即可。


配置完成后在代码中完成定时器的中断回调函数,便可计算PWM的占空比、频率、周期。


/**
*  @brief 定时器中断回调函数
*  @note  htim 定时器句柄
*/

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
	if(htim == &htim2)
	{
		if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_1)    
		{
			/* 记录TIM2_CCR1的值 */
			PWM_RisingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);
			
			if(PWM_RisingCount != 0 && PWM_FallingCount!= 0)
			{
				PWM_Duty        = (float)(PWM_FallingCount / PWM_RisingCount);//占空比
				PWM_Period      = PWM_RisingCount*0.000001f;                  //周期
				PWM_Frequency   = 1/PWM_Period;                               //频率
			}
		}
		else if(htim2.Channel == HAL_TIM_ACTIVE_CHANNEL_2)
		{	
			/* 记录TIM2_CCR2的值 */
			PWM_FallingCount = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_2);
		}
	}
}

五. 实战项目

前言所说的风速控制板最终效果如下,非常简单,使用TIM1四路PWM输出用于控制四个LED灯,通过呼吸灯的方式指示风扇转速;使用TIM3一路PWM用于控制风扇输出(PWM频率为25KHz)。使用TIM4用于PWM捕获,测出PWM频率后转化风扇转速。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32实现PWM输出与PWM输入捕获(HAL库) 的相关文章

随机推荐

  • 关于写代码的几个看法

    最近在新公司负责bug的修复 xff0c 发现很多的代码逻辑理解起来有些困难 现在将其中观察到的现象列出来 xff0c 谈谈自己的看法 1 类过大 对于代码来说 xff0c 我们在编写的时候最好做到SRP Single Responsibi
  • 树莓派VNC server设置开机自启动

    目前已测试OK的几个方法 xff1a 方法1 xff08 作为服务自启动 xff09 xff1a 在 etc init d 中创建一个文件 例如tightvncserver xff1a span class token function s
  • 一个结构体 = 另一个结构体(同类型结构体之间可直接赋值操作)

    两个同类型结构体变量可以直接赋值 xff0c 不同类型结构体不能直接赋值 span class token macro property span class token directive hash span span class tok
  • FreeRTOS任务切换过程深层解析

    FreeRTOS 系统的任务切换最终都是在 PendSV 中断服务函数中完成的 xff0c uCOS 也是在 PendSV 中断中完成任务切换的 为什么用PendSV异常来做任务切换 PendSV 可以像普通中断一样被 Pending xf
  • QT C++入门学习(1) QT Creator安装和使用

    Qt官方下载 Qt 官网有一个专门的资源下载网站 xff0c 所有的开发环境和相关工具都可以从这里下载 xff0c 具体地址是 xff1a http download qt io 进入链接后 xff0c 是一个文件目录 xff0c 依次进入
  • QT初体验:手把手带你写一个自己的串口助手

    前言 本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程 xff0c 整个工程只有几百行代码 xff0c 跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法 对新手学习QT能增强信心 xff0
  • QT如何打包生成独立可执行.exe文件

    一 将QT程序使用Release编译 二 新建一个文件夹 xff0c 将Release编译生成的exe文件复制到新建文件夹中 先找到Release编译生成的exe文件夹位置 xff0c 与项目创建的文件夹有关 xff1a 临时文件夹 rel
  • 利用OpenCV识别不规则图形轮廓并找其中心点和角度

    关于寻找图形的轮廓 xff0c 想来大家都不陌生 但平常寻找并进行识别的轮廓都是较为标准的图形 xff0c 如圆形 xff0c 矩形等 但在一些特殊情况下 xff0c 我们所检测的图形并不是理想的标准图形 比如说我们检测元件的引脚 xff0
  • 神经网络学习小记录21——InceptionV3模型的复现详解

    神经网络学习小记录21 InceptionV3模型的复现详解 学习前言什么是InceptionV3模型InceptionV3网络部分实现代码图片预测 学习前言 Inception系列的结构和其它的前向神经网络的结构不太一样 xff0c 每一
  • Ubuntu的快乐学习3——ros的launch用法

    Ubuntu的快乐学习3 ros的launch用法 学习前言launch是什么launch的使用方法一 简单使用二 常用标签1 launch标签2 node标签3 include标签4 remap标签5 param标签6 rosparam标
  • 三周年创作纪念日

    机缘 不知不觉已经开始分享三周年了 xff0c 最开始什么都不懂 xff0c 作为自动化的学生 xff0c 以为学点算法就可以变得厉害一些 xff0c 于是学了点C 43 43 相关就开始分享 后来立志于研究深度学习算法 xff0c 感觉强
  • win10+vs2017+opencv4.0.1+opencv_contrib-4.0.1详细教程

    最近想好好认真学习一下opencv4 0 xff0c 需要用到contrib扩展库 xff0c 配置完记录下 先写一下版本信息 xff1a opencv4 0 1 xff0c vs2017和 win10 其他opencv版本安装和配置原理一
  • OpenHD---低成本开源高清数字图传

    转载注明出处 文章目录 一 前言二 OpenHD简单介绍三 图传材料准备1 树莓派2 摄像头 排线 SD卡 读卡器4 网卡 四 硬件连接五 镜像刷写六 通电测试七 系统参数设置八 连接飞控九 关于二次开发十 最后 一 前言 这篇文章是对树莓
  • PS2手柄通讯协议解析---附资料和源码

    文章目录 一 PS2介绍二 PS2通讯协议介绍 xff08 1 xff09 PS2端口介绍 xff08 2 xff09 PS2通讯过程 三 基于STM32的PS2通信源码四 文档与源码下载链接 一 PS2介绍 今天就带大家来认识一下PS2的
  • Stm32延时与计时方法(HAL库)

    文章目录 一 延时的3种方法1 循环延时2 定时器中断延时与非中断延时 三 定时器中断式计时与延时二 定时器非中断式延时四 代码例程五 同系列博客 一 延时的3种方法 首先 xff0c 先了解一下什么延时 顾名思义 xff0c 延时即是延长
  • CAN通信知识梳理及在Stm32上的应用(HAL库)

    文章目录 一 CAN通信简介二 硬件连接三 CAN总线上的电平信号四 CAN帧的种类 xff08 1 xff09 遥控帧 xff08 2 xff09 数据帧 五 CAN的仲裁方法六 CAN在Stm32上的应用 xff08 1 xff09 C
  • C语言标准库函数大全(ctype、time 、stdio、stdlib、math、string)

    文章目录 C语言函数库 一 lt ctype h gt 二 lt math h gt 三 lt stdio h gt 四 lt stdlib h gt 五 lt time h gt 六 lt string h gt 文档资料 C语言函数库
  • 作品分享:基于STM32的温度报警器含源码、原理图、PCB文件、作品报告

    文章目录 一 前言二 材料准备三 硬件部分四 软件部分1 底层封装库2 中间层3 应用层 五 外壳设计六 资料链接 一 前言 该作品是我在华工电工开放实习的作品 xff0c 本作品由七部分组成 中央为Stm32F405RG芯片 xff0c
  • 基于时延法的麦克风阵列声源定位分析

    文章目录 一 关于麦克风阵列二 关于声源定位三 基于广义互相关 GCC 计算时延四 基于时延差的声源定位法1 近场模型2 远场模型 五 三维空间阵列的声源定位系统实现1 推导过程 六 六元圆形麦克风阵列声源定位七 相关链接 一 关于麦克风阵
  • STM32实现PWM输出与PWM输入捕获(HAL库)

    文章目录 一 前言二 STM32 定时器2 1 基本定时器2 1 1 功能与框图2 1 2 CubeMX配置 2 2 通用定时器2 2 1 功能与框图2 2 2 CubeMX配置 2 3 高级定时器2 3 1 功能与框图2 3 2 Cube