细说STM32单片机使用通用定时器生成固定占空比和可变占空比PWM波的方法

news2024/11/22 10:26:49

目录

一、本实例测试的目的

二、硬件和CubeMX项目配置

1、硬件开发板 

2、项目配置

(1)定时器TIM2_CH1

(2)时钟和Debug

(3) NVIC

(4)GPIO

3、输出固定占空比的PWM波源码

(1)启动定时器

(2)控制LED

(3)下载与测试

4、输出可变占空比的PWM波

(1)改变占空比的方法

5、输出可变占空比的PWM波源码

(1)新增变量

(2)启动定时器

(3)控制LED

(4)下载与测试


一、本实例测试的目的

        使用TIM2的CH1输出生成PWM波, 首先输出固定占空比的PWM波,然后再改动程序后输出可变占空比的PWM波。

二、硬件和CubeMX项目配置

1、硬件开发板 

        开发板型号NUCLEO-G474RE,MCU型号STM32G474RET6,该MCU有1个高精度定时器、3个高级控制定时器、7个通用定时器(TIM2~TIM5、TIM15~TIM17)和2个基础定时器。此外还有2个看门狗定时器和1个SysTick定时器。

        开发板上TIM2的CH1连接的引脚PA5。PA5引脚不能设置为GPIO_Output,而要设置为TIM2_CH1。

        开发板上PB11设置为LED1,PB11输出高电平时LED1亮,否则,LED1灭。可以用TIM2的CH1输出PWM波控制LED1的亮灭。PB11引脚设置为GPIO_Output。

2、项目配置

(1)定时器TIM2_CH1

        Channel1选择PWM Generation CH1;Clock Source选择Internal Clock;

  • Prescaler,预分频寄存器值,设置为16999,所以预分频系数为17000。定时器使用内部时钟信号频率为170MHz,经过预分频后进入计数器的时钟频率就10kHz,即

  • Counter Period,计数周期(ARR的值),设置为199,所以一个计数周期是

        

  • Internal Clock Division,内部时钟分频,是在定时器控制器部分对内部时钟进行分频,可以设置为1、2或4分频,选项No Division就是无分频,使得CK_PSC等于CK INT。
  • auto-reload preload,自动重载预装载,即设置TIM2_CR1寄存器中的ARPE位。如果设置为Disable,就是不使用预装载,设置的新ARR的值立即生效;如果设置为Enabled, 设置的新ARR的值在下一个UEV事件时才生效。
  • Mode,PWM模式,选项有PWM Mode 1(PWM模式1)和PWM Mode 2(PWM模式2)。这两种模式的定义如下:

        PWM模式1:在递增计数模式下,只要CNT<CCR,通道就是有效状态,否则为无效状态。在递减计数模式下,只要CNT<CCR,通道就变为无效状态,否则为有效状态。

        PWM模式2:其输出与PWM模式1正好相反,例如,在递增计数模式下,只要CNT<CCR,通道就是无效状态,否则为有效状态。

  • Pulse,PWM脉冲宽度,就是设置32位的捕获/比较寄存器CCR的值。脉冲宽度的值应该小于计数周期的值,这里设置为50,因为计数器的时钟频率是10kHz,所以脉冲宽度为5ms。
  • Output compare preload,输出比较预装载。CCR有预装载功能,寄存器TIMx_CCMRy中的OCyPE(Output Capture y Preload Enable)位可以使能或禁用其预装载功能。这个参数就是设置这个位的值,设置为Enable时,修改CCR的值需要到下一个UEV事件时才生效,否则立刻生效。
  • Fast Mode,是否使用输出比较快速模式,就是设置寄存器TIMx_CCMR1中的OC1FE位,用于加快触发输入事件对CC输出的影响,一般设置为Disable即可。
  • CH Polarity,通道极性,就是CCR与CNT比较输出的有效状态,可以设置为高电平 (High)或低电平(Low)。通道极性和PWM模式的组合可以生成不同的PWM波形。 

(2)时钟和Debug

        HSE选择外部晶振,24MHZ,APB1 = APB2 = 170MHz;

        Debug选择Serial Wire;

(3) NVIC

        Time Base修改为0;

        TIM2 global interrupt设置为1;

(4)GPIO

        设置PB11为GPIO OUTPUT,默认高电平,PP,高速,别名LED1。

        经过这样的设置,在启动定时器TIM2后,在引脚PA5(TIM2_CH1通道)上输出的PWM 波形:通道极性为高,PWM模式为1。PWM波的周期为20ms,由ARR的值决定;高电平脉冲宽度为5ms,由CCR的值决定。

        同时扩展板上的PB11的LED1闪烁。

3、输出固定占空比的PWM波源码

(1)启动定时器

/* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);				//以中断方式启动TIM2
  HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_1);	//TIM2通道1,启动生成PWM
/* USER CODE END 2 */

        MX_TIM2_Init()是定时器TIM2的初始化函数。要启动TIM2的PWM波输出,需要先执行函数HAL_TIM_Base_Start_IT()启动定时器,再执行函数HAL_TIM_PWM_Start IT()启动CH1的PWM波输出。 

(2)控制LED

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM2)
		HAL_GPIO_TogglePin (LED1_GPIO_Port,LED1_Pin);
}
/* USER CODE END 4 */

(3)下载与测试

        下载到开发板连续运行,用示波器可以观察PA5引脚上输出的固定占空比的PWM波形。用眼睛可以看到闪烁的LED1(PB11)。改变PWM高电平脉冲宽度可以改变LED的亮度,因为PB11引脚为高电平时LED亮,所以PWM脉冲宽度越大,LED越亮。在函数MX_TIM2_Init()的代码里,直接修改PWM参数结构体变量sConfigOC的成员变量的赋值,可以观察不同参数取值的影响,例如,修改PWM模式参数OCMode、有效极性参数OCPolarity、脉冲宽度参数Pulse等。

//sConfigOC成员
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 50;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;

4、输出可变占空比的PWM波

(1)改变占空比的方法

        LED的亮度是由PWM波的占空比控制的,例1的程序输出PWM波是固定占空比,所以 LED的亮度是固定的。如果在程序运行过程中动态修改PWM的占空比,就可以使LED从暗到明、从明到暗地变化,形成一种呼吸的效果。

        在程序中动态改变PWM波的占空比,就是要修改寄存器TIMx_CCR1的值。下图是动态修改PWM波的占空比的示意图。在本示例中,PWM波的周期是200个时钟周期,在发生比较匹配事件时,会产生TIM_IT_CC1中断事件(置位CCyF中断标志位),可以在此中断里修改CCR的值。

 

        CCR是有预装载功能的。如果禁止CCR预装载功能,对CCR的修改立即生效;如果启用了CCR预装载功能,设置新的CCR值需要在下一个UEV事件时才生效。参数Output compare preload控制是否启用CCR的预装载功能,本例里需要设置为 Enable。

        如果CCR的值等于定时器计数器的值,就会置位中断事件标志位CCyIF,即产生TIM_IT_CCy中断事件。生成PWM波是输出比较,HAL_TIM_PWM_PulseFinishedCallback() 是对应的回调函数,可以在这个回调函数里修改CCR的值。当CCR预装载功能使能时,在下次UEV事件时对CCR的修改就会生效,从而可以动态地改变PWM波的占空比。

        使用宏函数__HAL_TIM_SET_COMPARE()可以设置CCR的值,其原型定义为:        

__HAL_TIM_SET_COMPARE(__HANDLE__, __CHANNEL__, __COMPARE__)

        其中,__HANDLE__是定时器对象指针,__CHANNEL__是定时器通道,__COMPARE__是需要为CCR设置的值。例如,将TIM2的CH1通道的CCR设置为0x0037的语句为:

__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,0x0037);

        另外,宏函数__HAL_TIM_GET_COMPARE()可以获取CCR当前的值,其函数原型定义如下,这个函数返回结果是16位或32位整数,与具体定时器的CCR的长度有关。

__HAL_TIM_GET_COMPARE(__HANDLE__ ,__CHANNEL__)

5、输出可变占空比的PWM波源码

(1)新增变量

/* USER CODE BEGIN PV */
uint16_t pulseWidth = 50; //脉宽
uint8_t dirInc = 1;       //脉宽变化方向,1=递增,0=递减
/* USER CODE END PV */

(2)启动定时器

  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);				//以中断方式启动TIM2
  HAL_TIM_PWM_Start_IT(&htim2,TIM_CHANNEL_1);	//TIM2通道1,启动生成PWM
  /* USER CODE END 2 */

(3)控制LED

/* USER CODE BEGIN 4 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if (htim->Instance == TIM2)
	HAL_GPIO_TogglePin (LED1_GPIO_Port,LED1_Pin);
}

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
 {
	if (htim->Instance != TIM2)
		return;
	if(dirInc == 1) //脉宽递增
	{
		pulseWidth++;
		if (pulseWidth >= 195)
		{
			pulseWidth = 195;
			dirInc=0; //脉宽递减
		}
	}
	else
	{
		pulseWidth--;
		if (pulseWidth <= 5)
		{
			pulseWidth = 5;
			dirInc=1;//脉宽递增
		}
	}
	__HAL_TIM_SET_COMPARE(&htim2,TIM_CHANNEL_1,pulseWidth);//设置CCR的值
}
/* USER CODE END 4 */

(4)下载与测试

        该方法实现了按脉宽递增或递减方向修改CCR的值,因为开启了CCR预装载功能,所以新设置的CCR的值在下一个UEV事件时才生效。下载并运行此程序,我们就可以观察到LED1 由明到暗,再由暗到明的循环往复变化效果。

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

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

相关文章

a√斗地主之顺子

题目描述 在斗地主扑克牌游戏中&#xff0c;扑克牌由小到大的顺序为:3,4,5.6,7.8,9,10,J,Q,K,A,2&#xff0c;玩家可以出的扑克牌阵型有:单张、对子、顺子、飞机、炸弹等。 其中顺子的出牌规则为:由至少5张由小到大连续递增的扑克牌组成&#xff0c;且不能包含2。 例如:(3.4.…

三、Kubernetes中的控制器的使用

一 什么是控制器 官方文档&#xff1a; 工作负载管理 | Kubernetes 控制器也是管理pod的一种手段 自主式pod&#xff1a;pod退出或意外关闭后不会被重新创建 控制器管理的 Pod&#xff1a;在控制器的生命周期里&#xff0c;始终要维持 Pod 的副本数目 Pod控制器是管理pod…

Vue3+CesiumJS相机定位camera

new Cesium.Camera (scene) 摄像机由位置&#xff0c;方向和视锥台定义。 方向与视图形成正交基准&#xff0c;上和右视图x上单位矢量。 视锥由6个平面定义。每个平面都由 Cartesian4 对象表示&#xff0c;其中x&#xff0c;y和z分量定义垂直于平面的单位矢量&#xff0c;w分量…

springboot 整合 nacos 配置实现多个环境不同配置

目录 1、描述 2、Nacos服务端安装 3、创建dataId 配置中心 4、创建一个springboot 项目 5、重点&#xff1a;不同的springboot 读取不同application 6、总结 1、描述 一个项目一般会有中心配置文件&#xff0c;现在简单上手主流有Apollo&#xff0c;nacos config &#…

python的流程控制语句之制作空气质量评估系统

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

VideoSRT 注册邀请码,填写邀请码免费获得3天专业版授权

邀请码&#xff1a;aN2M40 填写邀请码免费获得3天专业版授权

【Python刷题】Atcoder Beginner Contest 371

目录 A - Jiro题目描述算法思路代码实现 B - Taro题目描述算法思路代码实现 D - 1D Country题目描述算法思路代码实现 E - I Hate Sigma Problem题目描述算法思路代码实现 A - Jiro 题目描述 有三个人&#xff0c;知道他们之中每两个人的年龄关系&#xff0c;输出年龄第二大的…

rust GUI框架Tauri入门——基于vanilla.js

文章目录 Tauri介绍Vite开始创建 Rust 项目 调用指令window.__TAURI_INVOKE__.invoke is undefined 问题参考资料JavaScript 模块VueVue RouteviteNuxt Tauri介绍 Tauri是一款用Rust构建的开源框架&#xff0c;用于创建轻量级、安全且高效的桌面应用程序。它将Rust的强大功能与…

Qt-QProgressBar显示类控件(27)

目录 描述 相关属性 使用 引入头文件机制 作用 描述 就是一个进度条&#xff0c;如下这个样子 相关属性 这里是一些属性 minimum进度条最⼩值maximum进度条最⼤值value进度条当前值 alignment ⽂本在进度条中的对⻬⽅式&#xff1a; • Qt::AlignLeft :左对⻬ • Qt::…

[Python学习日记-21] Python 中的字符编码(上)

[Python学习日记-21] Python 中的字符编码&#xff08;上&#xff09; 简介 ASCII 码 字符编码中的断句 GB2312 和 GBK 简介 在编程之路上&#xff0c;如果你不把编码问题搞清楚&#xff0c;那么它将像幽灵一般纠缠你整个职业生涯&#xff0c;各种灵异事件会接踵而来&#…

除了字符串前导的*号之外,将串中其它*号全部删除

要求 假定输入的字符串中只包含字母和*号。请编写函数fun&#xff0c;它的功能是:除了字符串前导的*号之外&#xff0c;将串中其它*号全部删除。在编写函数时&#xff0c;不得使用C语言提供的字符串函数。函数fun中给出的语句仅供参考。 例如&#xff0c;字符串中的内容为:-**…

文件格式转换:EXCEL和CSV文件格式互相转换

目录 1.EXCEl和CSV文件格式互相转换1.1首先安装所需的Python包1.2excel转换为csv代码如下:1.3csv转换为excel代码如下:由于excel文件在数学建模数据处理当中的局限性,我们通常把excel文件转换为csv文件来处理,下面是相关的代码,我直接封装成函数,你们直接调用即可,我会添…

Selenium基础入门:环境搭建、浏览器驱动配置及基本使用方法

目录 引言 一、Selenium环境搭建 1.1 Python环境准备 1.1.1 下载并安装Python 1.1.2 安装pip 1.2 Selenium库安装 1.3 浏览器驱动安装 1.3.1 ChromeDriver 1.3.2 GeckoDriver&#xff08;Firefox&#xff09; 1.3.3 其他浏览器驱动 1.4 IDE和插件&#xff08;可选&a…

免费AI播客生成:notebooklm可以生成播客的两个发言人谈论的内容,从各种来源如研究论文、文章

参考&#xff1a; https://notebooklm.google.com/ 可以上传文章链接&#xff0c;ai自动生成播客两人对话&#xff1a; 另外notebooklm他本身也是个rag知识库对话&#xff0c;可以直接聊天框对话

CorrMatch复现

复现结果–Full&#xff1a;81.78327847863439&#xff0c;成功 U2PL’s splits计算量太大&#xff0c;不建议复现

Ubuntu 20.04 解决 nvidia-smi 出错问题

目录 一、初始问题 二、解决方法 2.1 法一 2.2 法二 三、新的问题 3.1 解决方案 3.2 进一步解决 3.3 最后解决 一、初始问题 今天要在本机上装个环境时&#xff0c;运行了一下 nvidia-smi 突然遇到一个问题&#xff1a; Failed to initialize NVML: Driver/library ver…

Qt_按钮类控件

目录 1、QAbstractButton 2、设置带图标的按钮 3、设置带有快捷键的按钮 4、QRadioButtion&#xff08;单选按钮&#xff09; 4.1 QButtonGroup 5、QCheckBox 结语 前言&#xff1a; 按钮类控件是Qt中最重要的控件类型之一&#xff0c;该类型的控件可以通过鼠标的点击…

了解线程池

引出线程池&#xff1a; 假设小编是一个女生&#xff0c;小编处了一个对象&#xff0c;但是某一天小编不想和这个男生处对象了&#xff0c;但是小编还是想和别的男生处对象的&#xff0c;于是现在我就面临两个问题&#xff1a;一、怎么跟现任分手 二、开始物色新的对象&#…

软件安装攻略:Sublime Text 下载安装和使用教程

Sublime Text 下载安装和使用教程 Sublime Text是一个流行的跨平台文本编辑器&#xff0c;它具有以下一些主要功能和特点&#xff1a; &#xff08;1&#xff09;简洁的界面和快速的速度&#xff1a;Sublime Text拥有简约干净的界面&#xff0c;启动和响应速度很快。 &#…

Visual Studio打开项目的一些小技巧

Visual Studio(VS)是一款功能强大的集成开发环境&#xff0c;许多刚入门C/C的小白也会使用这款软件进行写代码&#xff0c;然而它的操作并不简单&#xff0c;下面将讲解一下VS打开项目文件的一些小技巧。 目录 &#x1f381;创建空项目 ❤️①点击“创建新项目” ❤️②点击“…