STM32 单片机开发 - TIM 定时器(PWM)

一、硬件定时器

  • 高级控制定时器 Advanced Control Timers (TIM1/TIM8)
  • 通用定时器 General Purpose Timers (TIM2/TIM3/TIM4/TIM5)
  • 通用定时器 General Purpose Timers (TIM15/TIM16/TIM17)
  • 基本定时器 Basic Timers (TIM6/TIM7)
表 1 定时器种类

二、TIM 中 PWM 概念

PWM 的基本原理就是通过 ++ / -- 计数

2.1 PWM 概念

PWM:Pulse width modulation - 脉冲宽度调制 (定时器)

脉冲:方波信号

方波信号:一个高电平和一个低电平组成的波形

脉冲宽度调制:调制一个方波信号中高电平或者低电平的占比


方波周期:一个方波信号持续的时间

方波频率:单位时间可以生成的方波个数                周期和频率成反比


周期的单位:s        ms        μs        ns频率的单位:Hz(bps)  KHz(Kbps) MHz(Mbps) GHz(Gbps)

占空比:高电平信号在一个方波周期内的占比

图 1 不同占空比

        图1(1)占空比为 50%,(2)占空比为 70%.


1)PWM 的作用

        通过 PWM 调节周期内高低电平的占比,对基于频率参数控制的外设(蜂鸣器、马达、直流电机等)可以进行更加有效的控制。

图 2 PWM 信号

三、分析电路图

底板上的蜂鸣器引脚:PA15 - TIM2_CH1风扇引脚:PC6 - TIM3_CH1震动马达引脚:PC7 - TIM3_CH2
图 3  查找蜂鸣器引脚
图 4 查找风扇引脚
图 5 查找震动马达引脚
按图 3 - 图 5 所示查找到三个外设的引脚。

四、分析芯片手册

4.1 定时器介绍

1)介绍

图 6 通用定时器 TIM2 - TIM5 介绍

        TIM2/TIM3/TIM4/TIM5 都是通用可编程的定时器

        通用定时器由一个可编程预分频器驱动的 16 位 32位自动重载计数器组成。

        它们可用于多种用途:测量输入信号的脉冲长度(输入捕获)或生成输出波形(输出比较脉冲宽度调制PWM))。

        利用定时器预分频器和 RCC(复位和时钟控制)时钟控制器预分频器,脉冲长度和波形周期可在几微秒到几毫秒的范围内进行调制。

        这些定时器之间完全相互独立不共享任何资源


2)主要特性

图 7 通用定时器 TIM2 - TIM5 主要特性
  • 16 位或 32 位向上、向下、向上/向下自动重载计数器
  • 16 位可编程预分频器,可将计数器时钟频率从 1 到 65535 之间的任意系数分频(也可动态分频)。
  • 最多 4 个独立通道,用于
    • 输入捕获
    • 输出比较
    • 脉冲宽度调制(PWM)生成(边沿对齐和中心对齐模式)
    • 单脉冲模式输出

3)功能描述

图 8 通用定时器 TIM2 - TIM5 功能描述

        定时器基本单元。

        可编程定时器的主要模块是一个带有相关自动重载寄存器的 16 位 / 32 位计数器。计数器可以向上计数、向下计数,或者既向上又向下计数。计数器时钟可由预分频器分频。

        定时器基本单元包括:

  • 计数寄存器 - TIMx_CNT
  • 分频寄存器 - TIMx_PSC
  • 自动重载寄存器 - TIMx_ARR

4)预分频系数发生变化波形图

图 9 预分频系数发生变化波形图

4.2

图 10 TIMx 定时器内部框图

        分频器的分频范围: 16 位(分频系数的使用范围: 1 - 65535);
计数器的计数范围: 16 位(计数数值范围: 0 - 65535)32 位的(计数范围: 0 - (2^32) - 1);
计数器 / 定时器的计数方式边沿对齐方式递增计数方式递减计数方式 / 向下计数方式)、中心对齐计数方式先递增再递减计数方式)。

递增计数方式:

        CNT 计数器由分频后的时钟 CK_CNT 驱动工作,每来一个分频后的时钟,CNT 计数器中的值从 0 开始 + 1;
首先,需要设置自动重载寄存器中的值(ARR = 1000)和计数器的计数方式(递增计数方式);
当计数器开关开始工作时,自动重载寄存器中的值会被加载到计数器,每来 1 个时钟信号,计数器会从 0 开始 + 1;

        直到计数器中的值加到和自动重载寄存器中的值相等时,此时就代表一个 PWM 方波产生了
当产生一个 PWM 方波后,会产生一个溢出事件(标志位),CNT 计数器又会回到 0,重新开始 + 1,循环操作。

递减计数方式:
首先,需要设置自动重载寄存器中的值(ARR = 1000)和计数器的计数方式(递减计数方式);
当计数器开关工作时,自动重载寄存器中的值(ARR = 1000)会被加载到计数器中,每来 1 个时钟信号,计数器中的值会从 1000 开始 - 1;
直到计数器中的值递减到 0 时,此时就代表一个 PWM 方波产生了;
当产生一个 PWM 方波后,会产生一个溢出事件(标志位),CNT 计数器中的值又会回到 1000,重新开始 - 1,循环操作。

先递增再递减计数方式:
首先,需要设置自动重载寄存器中的值(ARR = 1000)和计数器的计数方式(先递增再递减计数方式);
当计数器开关开始工作时,自动重载寄存器中的值会被加载到计数器,每来 1 个时钟信号,计数器会从 0 开始 + 1;
当计数器中的值加到和自动重载寄存器中的值相等时,开始递减,也就是每来 1 个时钟信号,计数器会从 1000 开始 - 1;

        直到计数器中的值递减到 0 时,此时就代表一个 PWM 方波产生了;
当产生一个 PWM 方波后,会产生一个溢出事件(标志位),循环上述操作。

目的:为了生成一个自定义脉宽的 PWM 波信号(可以人为改变高低电平占比的方波信号,也就是可以人为改变占空比的方波信号)
生成一个
自定义脉宽的方波信号的流程:

  1. 准备工作:(默认以初始给出的频率值为频率甲)
    1.1 由 RCC 产生并分配给 TIM 一个分频前的时钟频率 CK_PSC = 160MHz
    1.2 设置分频寄存器中的分频系数 PSC = 160,分频后的时钟频率 CK_CNT = 100MHz,分频后的时钟可以驱动计数工作(递增 / 递减计数)
    1.3 设置自动重载寄存器的值(ARR = 1000),设置计数器的计数方式为递增计数方式,设置捕获比较存储的值 CCR1 = 700
  2. 自动重载寄存器中的值(ARR)会被加载到计数器(CNT)中
  3. 每来 1 个时钟信号,计数器中的值从 0 开始 + 1
  4. 当计数器中的值(CNT)加到和比较 / 捕获寄存器中的值(CCR1)相等时,此时输出的电平发生翻转
  5. 接着,计数器中的值继续 + 1,直到加到和自动重载寄存器中的值(ARR)相等时,此时就代表一个自定义脉宽的 PWM 方波产生了
图 11 默认初始输出电平不同时的占空比

        分频前时钟 CK_PSC = 160 MHz,分频系数 PSC = 160,自动重载寄存器 ARR = 1000,计数器计数方式为递增计数,捕获/比较寄存器 CCR1 = 700;

        默认输出初始电平为高电平。

则:

分频后的时钟频率 CK_CNT = CK_PSC / PSC = 160MHz / 160 = 1MHz(1s内产生1M个时钟信号)
分频后的时钟周期 = 1 / 分频后的时钟频率 = 1 / 1MHz = 1us(产生一个时钟信号需要1us)
生成的PWM方波的频率 = 分频后的时钟频率CK_PSC / 自动重载寄存器的值ARR = 1MHz / 1000 = 1000Hz = 1KHz
生成的PWM方波的周期 = 1 / 生成的PWM方波的频率 = 1 / 1000Hz = 0.001s = 1ms
生成的PWM方波的周期 = 分频后的时钟周期 * +1次数 = 分频后的时钟周期 * ARR = 1us * 1000 = 1ms
生成的PWM方波的频率 = 1 / 生成的PWM方波的周期 = 1 / 1ms = 1KHz
生成的PWM方波的占空比 = 700 / 1000 * 100% = 捕获/比较寄存器的值CCR1 / 自动重载寄存器的值ARR * 100% = 70%
  1. PWM方波的频率周期分频寄存器的分频系数 PSC自动重载寄存器的值 ARR 有关;
  2. PWM方波的占空比自动重载寄存器的值 ARR捕获/比较寄存器的值 CCR1输出的初始电平(有效电平)PWM 的工作模式 有关。

4.3 边沿对齐方式 - 递增计数

图 12 递增计数时序图

4.4 边沿对齐方式 - 递减计数

图 13 递减计数时序图

4.5 中心对齐计数

图 14 中心对齐计数时序图

4.6 TIMx_CR1 寄存器

图 15 TIMx_CR1

1)Bit 6:5

位 6:5 CMS[1:0]:中心对齐模式选择
00:边沿对齐模式。计数器根据方向位(DIR)进行递增或递减计数。
01:中心对齐模式 1。计数器交替进行递增和递减计数。配置为输出的通道(TIMx_CCMRx 寄存器中 CCxS=00)的输出比较中断标志仅在计数器递减计数时置位
10:中心对齐模式 2。计数器交替进行递增和递减计数。配置为输出的通道(TIMx_CCMRx 寄存器中 CCxS=00)的输出比较中断标志仅在计数器递增计数时置位
11:中心对齐模式 3。计数器交替进行递增和递减计数。配置为输出的通道(TIMx_CCMRx 寄存器中 CCxS=00)的输出比较中断标志在计数器递增或递减计数时都会置位
注意:只要计数器使能(CEN=1),就不允许从边沿对齐模式切换到中心对齐模式。

2)Bit 4

位 4 DIR:计数方向位
0:计数器用作向上计数器,递增计数
1:计数器用作向下计数器,递减计数

3)Bit 0

位 0 CEN:计数器使能
0:计数器不使能
1:计数器使能

4.7 TIM_CCMR1 寄存器

图 16 TIM_CCMR1

1)Bit 7

位 7 OC1CE:输出比较 1 清除使能(通道 1 的输出比较寄存器清除使能位)
0:OC1Ref 不受 ETRF 输入的影响
1:一旦在 ETRF 输入上检测到高电平,OC1Ref 就会被清除

2)Bits 16, 6:4

图 17 TIM_CCMR1 的 Bits 16, 6:4
图 18 TIM_CCMR1 的 Bits 16, 6:4 设置为 0110(PWM 模式 1)
图 19 TIM_CCMR1 的 Bits 16, 6:4 设置为 0111(PWM 模式 2)

4.8 TIM_CCER 寄存器

图 20 TIM_CCER

位 3 CC1NP:捕获 / 比较 1 输出极性。
CC1 通道配置为输出:在这种情况下,CC1NP 必须保持清零。

位 1 CC1P:捕获 / 比较 1 输出极性。
CC1 通道配置为输出:
0:OC1 高电平有效 - 通道1的活跃电平(有效电平)为高电平信号,不活跃电平(无效电平)为低电平信号
1:OC1 低电平有效 - 通道1的活跃电平(有效电平)为低电平信号,不活跃电平(无效电平)为高电平信号

位 0 CC1E:捕获 / 比较 1 输出使能 - 通道 1 的捕获 / 比较功能使能
CC1 通道配置为输出:
 0:关闭 - OC1 未激活
 1:开启 - OC1 信号在相应的输出引脚上输出 - 使能比较输出的功能

4.9 TIM_CNT 寄存器

图 21 TIM_CNT

计数器中的值可以人为手动写入;
一般需要手动写入时,应用在对计数器清0 / 设置阀值;
一般计数器中的值从自动重载寄存器(ARR)中来。

==========================================================

位 31 CNT [31]:计数器值的最高有效位(在 TIM2 和 TIM5 上)
在其他定时器上为保留位。

位 30:16 CNT [30:16]:计数器值的最高有效部分(在 TIM2 和 TIM5 上)

位 15:0 CNT [15:0]:计数器值的最低有效部分

4.10 TIM_PSC 寄存器

图 22 TIM_PSC
分频后的时钟频率 = 分频前的时钟频率 / (PSC寄存器中的值 + 1)

4.11 TIM_ARR 寄存器

图 23 TIM_ARR

4.12 TIM_CCR1 寄存器

图 24 TIM_CCR1

五、CubeMX 配置

以震动马达为例:

图 25 配置 PC7 引脚
将 PC7 引脚配置为 TIM3_CH2 模式,设置 TIM3 的 时钟源和通道 2 的模式
图 26 TIM3 参数含义
图 27 TIM3 参数设置

        按照如图所示设定 TIM3 的参数。

        之后和之前一样设置 Debug、时钟频率 160Mhz、工程设置。直接生成代码。


六、API 接口

6.1 HAL_TIM_PWM_Start 函数

HAL_StatusTypeDef HAL_TIM_PWM_Start(TIM_HandleTypeDef *htim, uint32_t Channel)

1)功能

        HAL库提供的用于开启某个定时器下某个通道的PWM功能的函数

2)参数

        htim:可以代表TIM3外设控制器的句柄

        Channel:需要开启PWM功能的通道

3)返回值

        成功,返回 HAL_OK(0)

        失败,返回错误码

6.2 __HAL_TIM_SET_COMPARE 宏函数

#define __HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__) \(((__CHANNEL__) == TIM_CHANNEL_1) ? ((__HANDLE__)->Instance->CCR1 = (__COMPARE__)) :\((__CHANNEL__) == TIM_CHANNEL_2) ? ((__HANDLE__)->Instance->CCR2 = (__COMPARE__)) :\((__CHANNEL__) == TIM_CHANNEL_3) ? ((__HANDLE__)->Instance->CCR3 = (__COMPARE__)) :\((__CHANNEL__) == TIM_CHANNEL_4) ? ((__HANDLE__)->Instance->CCR4 = (__COMPARE__)))

1)功能

        HAL库提供的用于设置捕获/比较寄存器中数值的函数(向捕获/比较寄存器中写入值)

2)参数

        __HANDLE__:TIM3外设控制器的句柄对象

        __CHANNEL__:需要写入数值的通道(1/2/3/4)

        __COMPARE__:需要写入到捕获/比较寄存器中的值


七、代码

int main(void)
{/* Initialize all configured peripherals */MX_GPIO_Init();MX_TIM1_Init();MX_TIM3_Init();/* USER CODE BEGIN 2 */HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){for(int i=100;i<=900;i+=100){__HAL_TIM_SET_COMPARE(&htim3,TIM_CHANNEL_2,700);HAL_Delay(2000);}/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/98070.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/98070.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenCV内置分类器实现简单的人脸识别

引言 人脸检测是计算机视觉领域的基础任务之一&#xff0c;广泛应用于安防监控、人机交互、图像美化等场景。今天我们将通过一段简洁的Python代码&#xff0c;使用OpenCV库实现实时摄像头人脸检测功能。无论你是计算机视觉新手还是有经验的开发者&#xff0c;这篇文章都能帮你理…

Tomcat 性能优化与高并发调优

Tomcat 性能优化与高并发调优1. 引言 经过前几篇文章的学习&#xff0c;我们已经掌握了 Tomcat 的核心原理&#xff1a; Connector 连接器容器体系&#xff08;Engine → Host → Context → Wrapper&#xff09;Servlet 执行链路线程模型&#xff08;Executor Worker&#xf…

MacOS M1安装face_recognition

MacOS M1安装face_recognition一致失败&#xff0c;尝试网上各种方法还是失败&#xff0c;遂分享自己安装成功的经历。 conda虚拟环境python版本&#xff1a;3.9.23准备工作确保 Homebrew 已安装 Homebrew 是 macOS 的包管理器&#xff0c;用于安装依赖项。如果尚未安装&#x…

动态库和静态库的链接加载

静态库的链接与加载静态库&#xff08;如.a或.lib文件&#xff09;在编译时直接链接到可执行文件中。编译器会将静态库中实际用到的代码复制到最终的可执行文件&#xff0c;生成独立的二进制文件。优点是不依赖外部库文件&#xff0c;但会导致可执行文件体积较大。生成静态库的…

如何处理在pytorch环境中已经安装的matplotlib无法使用的问题

1 问题已经安装好的matplotlib包无法在pytorch环境中使用。2 方法方法一&#xff1a;用命令安装matplotlib &#xff1a;方法二&#xff1a;打开cmd&#xff0c;使用conda install matplotlib命令安装matplotlib库#输入以下代码段&#xff0c;查询当前执行路径import osos.sys.…

Linux基础命令汇总

系统基础指令 ls:列出目录内容 ls -a:显示所有文件(包括隐藏文件) ls -l:显示详细文件信息 ls /etc:列出 /etc 目录内容 示例: cat:查看文件内容 cat /etc/os-release:查看系统版本信息 cat file1:显示文件内容 cat file1 file2 > merged.txt:合并文件并输出到新…

一场史诗级的冒险——Docker命令大航海!

各位亲爱的开发者、运维勇士、以及所有对现代化软件部署充满好奇的小伙伴们&#xff01;今天&#xff0c;我们将开启一场史诗级的冒险——Docker命令大航海&#xff01;我们将乘坐“Docker号”巨轮&#xff0c;驶向容器化技术的星辰大海。 这不是一篇枯燥的说明书&#xff0c;而…

告别依赖混乱:Spring IoC 容器与 DI 依赖注入入门精讲

目录 什么是 IoC IoC 介绍 传统开发思路 解决方法 IoC 优势 DI IoC & DI 使用 IoC 详解 Bean 的存储 Controller&#xff08;控制器存储&#xff09; 获取 bean 对象的其他方法 bean 命名 面试题之 ApplicationContext pk BeanFactory Service&#xff08;服…

视频理解学习笔记

目录 VideoRefer VideoPrism 核心解密&#xff1a;通用视频编码器的力量 VideoRefer VideoRefer 是由浙江大学和阿里达摩院联合推出的视频对象感知与推理技术&#xff0c;增强视频大型语言模型&#xff08;Video LLMs&#xff09;的空间-时间理解能力。简单一点来说就是可以…

P1198题解

题目链接 开题第一件事看数据范围.这里的范围是二十万,支持O(nlogn). 这是一个RMQ问题,同时要加点,我们因此考虑ST表或者线段树.这里用线段树是核弹打蚊子,没有意义,我们因此考虑ST表.我们注意到如果加点操作需要改动ST表原来的东西ST表就会炸掉,我们就要考虑更高级的数据结构…

使用yolov8对视频进行目标检测

使用 Ultralytics 的 YOLO 模型对视频进行逐帧目标检测非常简单&#xff0c;以下是完整的实现方法&#xff1a; 我们的输入视频是这样的 视频目标检测输入视频这里是天津市和平区天津大学附近&#xff0c;感兴趣的小伙伴来天津玩哈&#xff01;&#xff01; 1. 安装依赖 确保已…

Edge浏览器的自动化点击系统

Tag_click_openclose_V6 开发与使用注意事项 网页自动化点击系统 一个基于Python和CustomTkinter开发的桌面应用程序&#xff0c;通过Selenium实现对Edge浏览器的自动化控制。点击Tag_click_openclose_V6进入Github自取&#xff0c;记得点赞收藏嗷。 功能介绍 连接到已打开…

Python股票数据分析与预测系统 LSTM神经网络算法 股票价格预测 Tensorflow深度学习 机器学习 Flask框架 东方财富(建议收藏)✅

博主介绍&#xff1a;✌全网粉丝50W&#xff0c;前互联网大厂软件研发、集结硕博英豪成立软件开发工作室&#xff0c;专注于计算机相关专业项目实战6年之久&#xff0c;累计开发项目作品上万套。凭借丰富的经验与专业实力&#xff0c;已帮助成千上万的学生顺利毕业&#xff0c;…

英莱科技焊缝跟踪系统亮相德国埃森焊接展,激光视觉点亮世界舞台

9月15-19日&#xff0c;每4年一届的德国埃森焊接与切割展览会&#xff08;SCHWEISSEN & SCHNEIDEN&#xff09;即将盛大开幕。作为焊接行业最具规模及权威性的盛会之一&#xff0c;英莱科技将携全新PF系列激光视觉焊缝跟踪系统惊艳亮相&#xff0c;为全球智能化焊接贡献中国…

嵌入式基本概念:什么是指令集,微架构,IDE,DFP等等是什么意思,有什么关系???

注&#xff1a;下面是指令集和微框架的分类图&#xff0c;后面我会以ARM的M4举例子。 一.什么是指令集 大概的可以看这个视频 https://www.bilibili.com/video/BV1uXzbYBEy2/?spm_id_from333.1007.top_right_bar_window_custom_collection.content.click&vd_source406ed…

Spring Cloud之服务入口Gateway之自定义过滤器

目录 过滤器执行顺序 自定义过滤器 自定义GatewayFilter 定义GatewayFilter 配置过滤器 启动服务并访问 自定义GlobalFilter 定义GlobalFilter 启动服务并访问 服务部署 过滤器执行顺序 如果⼀个项⽬中, 既有GatewayFilter, ⼜有 GlobalFilter时, 执⾏的先后顺序是什…

MySQL——视图、储储过程、触发器

目录 一、视图 二、存储过程 三、触发器 一、视图 视图是一种虚拟存在的表。视图中的数据并不在数据库中真实存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。通俗的讲&#xff0c;视图只保存了查询的SQL逻辑&#xff0c…

iOS App 卡顿与性能瓶颈排查实战 如何定位CPU内存GPU帧率问题、优化耗电与网络延迟(uni-app开发性能优化全流程指南)

在 iOS 应用开发中&#xff0c;卡顿 是用户最直观的负面体验。 一个 App 如果在页面切换、滚动、后台运行时频繁掉帧或发热&#xff0c;用户很快就会放弃使用。 对于 uni-app 跨平台开发者 来说&#xff0c;卡顿问题更为复杂&#xff1a; JS 与原生层桥接增加了 CPU 负载&#…

腾讯开源多模态 RAG:复杂文档秒变自建知识库,支持 API 调用

上篇&#xff0c;分享了 小智AI MCP系列的第一篇&#xff1a; 小智 AI 闹钟提醒 定时任务&#xff0c;设备端MCP实现 有朋友问&#xff0c;能否接入知识库 RAG&#xff1f; 让小智可以根据企业知识库&#xff0c;回答客户的疑问~ 当然可以&#xff0c;接入方式同样是 MC…

Node.js中的 http 模块详解

http 模块是 Node.js 中的核心模块之一&#xff0c;专门用于构建基于 HTTP 的网络应用程序。它允许创建 HTTP 服务器和客户端&#xff0c;处理网络请求和响应。1. 核心 API 详解1.1. http.createServer([options][, requestListener])用于创建 HTTP 服务器的核心方法&#xff0…