当前位置: 首页 > news >正文

STM32F103_LL库+寄存器学习笔记23 - PWM波形输出及软件方式调整周期与占空比

导言


脉宽调制(PWM)是 STM32 定时器最常用的输出模式之一,广泛应用于电机驱动、LED 调光、伺服控制和功率管理等场景。本篇文章将以 TIM5 为例,从寄存器层面深入剖析 PWM 输出的原理与实现步骤。通过本篇博客,你不仅能掌握 CubeMX 及 LL 库的调用,更能从底层寄存器视角构建完整的 PWM 输出思维,为后续复杂控制奠定坚实基础。
本章节使用TIM5生成周期为1ms的PWM波形,占空比50%。并介绍如何通过软件方式改变PWM波形的周期与占空比。

如图所示,PWM的频率是1kHz(周期1ms),占空比500us(50%)。
在这里插入图片描述
项目地址:
github:

  • LL库: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library23_TIM_Generate_PWM
  • 寄存器方式: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_reg_library23_TIM_Generate_PWM

gitee(国内):

  • LL库: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_ll_library23_TIM_Generate_PWM
  • 寄存器方式: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_reg_library23_TIM_Generate_PWM

一、LL库


1.1、CubeMX

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

1.2、tim.c

在这里插入图片描述
CubeMX 根据上述配置,自动生成了相应初始化代码。

1.3、main.c

在这里插入图片描述

1.4、编译、调试

在这里插入图片描述
编译通过。

1.5、修改PWM波形的周期与占空比

在这里插入图片描述
如上所示:

  1. 函数LL_TIM_OC_SetCompareCH1()修改CH1的占空比,即TIM5_CCR1的值。
  2. 函数LL_TIM_SetAutoReload()修改TIM5_ARR的值,改变TIM5的PWM周期。
    在这里插入图片描述
    如上所示,PWM的周期从原来的1ms变成2ms,占空比500us变成100us。所以,占空比 = 100us / 2000us = 5%。

二、寄存器方式


2.1、TIM5PWMOutput_reg.c

#include "TIM5PWMOutput/TIM5PWMOutput_reg.h"/*** @brief  启动 TIM5 通道1 的 PWM 输出* @retval 无*/
void TIM5_PWM_Start(void)
{/* 使能 CC1 输出 */TIM5->CCER |= TIM_CCER_CC1E;/* 使能定时器计数 */TIM5->CR1 |= TIM_CR1_CEN;/* 立即生效:触发更新事件,加载预装载寄存器 */TIM5->EGR |= TIM_EGR_UG;
}/*** @brief  停止 TIM5 通道1 的 PWM 输出* @retval 无*/
void TIM5_PWM_Stop(void)
{/* 禁用定时器计数 */TIM5->CR1 &= ~TIM_CR1_CEN;/* 禁用 CC1 输出 */TIM5->CCER &= ~TIM_CCER_CC1E;
}/*** @brief  设置 PWM 占空比(通道1)* @param  ccr: 比较寄存器值,范围 0 ~ (ARR+1)* @retval 无*/
void TIM5_PWM_SetDuty(uint16_t ccr)
{TIM5->CCR1 = ccr;/* 若需立即生效,可取消注释触发更新事件 */// TIM5->EGR |= TIM_EGR_UG;
}/*** @brief  设置 PWM 周期(自动重装载寄存器)* @param  arr: 自动重装载寄存器值(周期 - 1)* @retval 无*/
void TIM5_PWM_SetPeriod(uint16_t arr)
{TIM5->ARR = arr;/* 若已使能 ARR 预装载,则需要触发更新事件 */TIM5->EGR |= TIM_EGR_UG;
}/*** @brief  配置并初始化 TIM5 通道1 PWM 输出(PA0 = TIM5_CH1)* @param  arr: 自动重装载寄存器值(周期 - 1)* @param  psc: 预分频器值* @retval 无*/
void TIM5_PWM_Init(uint16_t psc, uint16_t arr, uint16_t ccr)
{/* 1. 使能时钟:TIM5(APB1), GPIOA(APB2) */RCC->APB1ENR |= RCC_APB1ENR_TIM5EN;RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;/* 2. 配置 PA0 为复用推挽输出 */GPIOA->CRL &= ~(GPIO_CRL_MODE0 | GPIO_CRL_CNF0);GPIOA->CRL |=  (GPIO_CRL_MODE0_0   /* 输出模式,10 MHz */| GPIO_CRL_CNF0_1);  /* 复用推挽 *//* 3. 配置 TIM5 基础计数 */TIM5->PSC  = psc;    /* 预分频 */TIM5->ARR  = arr;    /* 自动重装载 *//* 使能 ARR 预装载 */TIM5->CR1 |= TIM_CR1_ARPE;/* 4. 配置通道1 为 PWM1 模式 */TIM5->CCMR1 &= ~TIM_CCMR1_OC1M;TIM5->CCMR1 |=  (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1); /* PWM 模式1 *//* 使能 CCR1 预装载 */TIM5->CCMR1 |= TIM_CCMR1_OC1PE;/* 默认占空比 0 */TIM5->CCR1 = ccr;/* 5. 设置极性(高电平有效)并暂时禁用输出 */TIM5->CCER &= ~TIM_CCER_CC1P;TIM5->CCER &= ~TIM_CCER_CC1E;
}

2.2、TIM5PWMOutput_reg.h

/*** @file    TIM5PWMOutput_reg.h* @brief   基于寄存器的 TIM5 驱动接口与寄存器定义** 本文件提供 STM32F1 系列 MCU 的 TIM5 基础定时器底层寄存器访问定义、* 配置参数以及初始化和控制函数原型。通过直接操作寄存器,实现对 TIM5* 外设的高效、精细化控制。** @note* - 该驱动不依赖 HAL/LL 库,完全通过寄存器位操作完成时钟使能、*   预分频、计数器模式等配置。** @version 1.0.0* @date    2025-05-13* @author  Wallace.zhang** @copyright* (C) 2025 Wallace.zhang。保留所有权利。** @license SPDX-License-Identifier: MIT*/
#ifndef __TIM5PWMOUTPUT_REG_H
#define __TIM5PWMOUTPUT_REG_H#ifdef __cplusplus
extern "C" {
#endif#include "main.h"void TIM5_PWM_Start(void);
void TIM5_PWM_Stop(void);
void TIM5_PWM_SetDuty(uint16_t ccr);
void TIM5_PWM_SetPeriod(uint16_t arr);
void TIM5_PWM_Init(uint16_t psc, uint16_t arr, uint16_t ccr);#ifdef __cplusplus
}
#endif#endif /* __TIM5PWMOUTPUT_REG_H */

2.2、main.c

在这里插入图片描述
如上所示,在main()函数里依次调用两个函数即可。

2.4、编译、调试

在这里插入图片描述
将代码烧录进去,效果跟LL库一样。

三、梳理寄存器


3.1、TIMx_CCMR1捕获/比较模式寄存器1

在这里插入图片描述
在这里插入图片描述
如上所示,设置PWM模式1将OC1M设置110。

/* 4. 配置通道1 为 PWM1 模式 */
TIM5->CCMR1 &= ~TIM_CCMR1_OC1M; // 清0
TIM5->CCMR1 |=  (TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1M_1); /* PWM 模式1 */

另外,将OC1PE设置1,使能CCR1的预装载。

/* 使能 CCR1 预装载 */
TIM5->CCMR1 |= TIM_CCMR1_OC1PE;

3.2、TIMx_CCER捕获/比较使能寄存器

在这里插入图片描述

/* 5. 设置极性(高电平有效)并暂时禁用输出 */
TIM5->CCER &= ~TIM_CCER_CC1P; // 高电平有效
TIM5->CCER &= ~TIM_CCER_CC1E; // 禁用输出

3.3、TIMx_EGR事件产生寄存器

在这里插入图片描述

/* 6. 触发更新事件,立即加载预装载寄存器 */
TIM5->EGR |= TIM_EGR_UG;

四、细节补充


4.1、PWM波形的启动与关闭

在这里插入图片描述
如上所示,从寄存器代码看来,启动与关闭PWM输出有两个开关。分别是CHx的开关(CC1E)与定时器的开关(CEN)。

相关文章:

  • 【行为型之访问者模式】游戏开发实战——Unity灵活数据操作与跨系统交互的架构秘诀
  • ConfigMap 和 Secret 是否支持热更新
  • Screen Mirroring App:轻松实现手机与电视的无缝投屏
  • 【C/C++】深度探索c++对象模型_笔记
  • elasticsearch硬件与资源配置优化
  • Docker 疑难杂症解决指南:从入门到进阶的全面剖析
  • 【leetcode】349. 两个数组的交集
  • 银行卡真伪验证助力金融合规-银行卡实名认证接口
  • 联排半孔PCB如何进行SMT贴片?
  • MySQL增删查改进阶
  • Python机器学习笔记(二十二、模型评估-交叉验证)
  • 【消息队列】RabbitMQ基本认识
  • Qml自定义组件之车辆风扇展示
  • TypeScript装饰器:从入门到精通
  • PyTorch中mean(dim=1)的深度解析
  • k8s 中使用 Service 访问时NetworkPolicy不生效问题排查
  • ubuntu24.04上安装NVIDIA driver+CUDA+cuDNN+Anaconda+Pytorch
  • 计算机视觉最不卷的方向:三维重建学习路线梳理
  • 分布式2(Zookeeper )
  • ubuntu 22.04 wifi网卡配置地址上网
  • 金正恩观摩朝鲜人民军各兵种战术综合训练
  • 融创中国:境外债务重组计划聆讯定于9月15日召开
  • 外交部亚洲司司长刘劲松会见印度驻华大使罗国栋
  • 多家中小银行存款利率迈入“1时代”
  • 中美经贸高层会谈将在午餐后继续
  • 第三届“老山国际春茶节”活动在云南麻栗坡举办