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

用STM32CubeMX配置PWM捕获:从定时器选型到串口输出全流程

STM32CubeMX实战PWM捕获全流程解析与调试技巧在嵌入式开发中精确测量PWM信号的周期和占空比是常见需求。本文将带你从零开始使用STM32CubeMX和HAL库完成PWM捕获功能的完整实现。不同于简单的教程复制我们会深入探讨两种捕获模式的本质区别并分享实际调试中遇到的坑与解决方案。1. 环境准备与基础概念1.1 硬件选型与连接我们以STM32F103VET6开发板为例需要准备以下硬件ST-Link调试器USB转串口模块示波器可选用于信号观测杜邦线若干关键引脚连接PB1TIM3_CH4作为PWM输出引脚PA0TIM8_CH1作为PWM输入捕获引脚提示如果使用其他型号开发板请根据芯片手册确认定时器通道对应的引脚1.2 PWM捕获原理精要PWM捕获本质上是通过测量两个边沿之间的时间差来计算周期和占空比。STM32提供了两种实现方式捕获模式所需资源最低频率限制实现复杂度PWM输入模式定时器的两个通道有较低普通输入捕获模式定时器单通道中断处理无较高PWM输入模式利用了定时器的从模式特性硬件自动完成边沿检测和计数器复位适合对实时性要求不高的场景。普通输入捕获模式通过软件处理溢出中断可以测量任意频率的PWM信号但需要更精细的中断管理。2. CubeMX工程配置详解2.1 时钟树配置时钟配置是定时器精度的基础按照以下步骤操作在RCC配置中选择HSE为Crystal/Ceramic Resonator进入Clock Configuration界面设置HCLK为72MHzSTM32F103的最大主频确保APB1 Timer Clocks为72MHzTIM8的时钟源// 验证时钟配置的代码片段 SystemCoreClockUpdate(); printf(System Clock: %lu Hz\n, SystemCoreClock);2.2 定时器参数设置PWM输出配置TIM3Prescaler: 71Counter Mode: UpPeriod: 999Pulse: 300初始占空比30%CH Polarity: HighPWM输入捕获配置TIM8Mode: PWM Input ModeIC1/IC2 Polarity: Rising/FallingPrescaler: 71Counter Period: 65535注意PWM输入模式必须使用通道1和通道2且通道2需要配置为间接模式2.3 串口重定向配置为了方便调试我们需要重定向printf到串口在SYS配置中选择Debug: Serial Wire配置USART1为Asynchronous模式在Project Manager中勾选Use MicroLIB// 重定向代码示例添加到usart.c #include stdio.h int __io_putchar(int ch) { HAL_UART_Transmit(huart1, (uint8_t *)ch, 1, HAL_MAX_DELAY); return ch; }3. 代码实现与优化3.1 PWM输入模式实现在PWM输入模式下硬件会自动处理边沿检测我们只需在中断中读取捕获值// 全局变量定义 uint32_t CCR1, CCR2; float duty_cycle, frequency; // 定时器启动代码 HAL_TIM_PWM_Start(htim3, TIM_CHANNEL_4); HAL_TIM_IC_Start_IT(htim8, TIM_CHANNEL_1); HAL_TIM_IC_Start_IT(htim8, TIM_CHANNEL_2); // 中断回调函数 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM8) { CCR1 HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); if(CCR1 ! 0) { CCR2 HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); frequency 72000000.0f / (71 1) / CCR1; duty_cycle CCR2 * 100.0f / CCR1; printf(Frequency: %.2f Hz, Duty: %.2f%%\r\n, frequency, duty_cycle); } } }3.2 普通输入捕获模式进阶实现普通模式需要手动处理溢出中断代码更复杂但灵活性更高// 状态机变量 typedef enum { CAPTURE_RISING_EDGE, CAPTURE_FALLING_EDGE, CAPTURE_COMPLETE } CaptureState; CaptureState captureState CAPTURE_RISING_EDGE; uint32_t overflowCount 0; uint32_t riseValue, fallValue; // 定时器中断处理 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM8) { overflowCount; } } // 捕获中断处理 void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { switch(captureState) { case CAPTURE_RISING_EDGE: __HAL_TIM_SET_COUNTER(htim, 0); overflowCount 0; __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING); captureState CAPTURE_FALLING_EDGE; break; case CAPTURE_FALLING_EDGE: fallValue __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1) overflowCount * __HAL_TIM_GET_AUTORELOAD(htim); __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); captureState CAPTURE_COMPLETE; break; case CAPTURE_COMPLETE: riseValue __HAL_TIM_GET_COMPARE(htim, TIM_CHANNEL_1) overflowCount * __HAL_TIM_GET_AUTORELOAD(htim); frequency 1000000.0f / (riseValue * (71 1) / 72.0f); duty_cycle (fallValue * 100.0f) / riseValue; printf(Freq: %.2f Hz, Duty: %.2f%%\r\n, frequency, duty_cycle); captureState CAPTURE_RISING_EDGE; break; } }4. 调试技巧与性能优化4.1 常见问题排查指南问题1捕获值始终为0检查定时器时钟是否使能确认GPIO模式是否正确设置为Alternate Function验证信号是否真正到达MCU引脚可用示波器检查问题2测量结果波动大确保PWM信号源稳定适当增加定时器预分频值提高测量精度检查中断优先级配置避免被其他高优先级中断打断问题3低频率测量不准确对于普通模式增大ARR值扩展测量范围对于PWM输入模式确认信号频率高于最低可测频率4.2 性能优化建议中断优化将定时器中断优先级设置为较高优先级在中断中只做必要操作避免复杂计算DMA应用 对于高频PWM信号可以考虑使用DMA将捕获值直接传输到内存// DMA配置示例 HAL_TIM_IC_Start_DMA(htim8, TIM_CHANNEL_1, buffer, BUFFER_SIZE);滤波处理 在软件层面添加移动平均滤波提高测量稳定性#define FILTER_SIZE 5 float freqBuffer[FILTER_SIZE]; float filteredFreq 0; void updateFilter(float newValue) { static uint8_t index 0; freqBuffer[index] newValue; index (index 1) % FILTER_SIZE; filteredFreq 0; for(uint8_t i 0; i FILTER_SIZE; i) { filteredFreq freqBuffer[i]; } filteredFreq / FILTER_SIZE; }在实际项目中我发现PWM输入模式虽然简单但在测量低频信号时会遇到限制。而普通输入捕获模式虽然实现复杂但通过合理设置ARR值和中断处理可以实现更宽范围的频率测量。特别是在电机控制等应用中普通模式的灵活性往往更能满足需求。

相关文章:

用STM32CubeMX配置PWM捕获:从定时器选型到串口输出全流程

STM32CubeMX实战:PWM捕获全流程解析与调试技巧 在嵌入式开发中,精确测量PWM信号的周期和占空比是常见需求。本文将带你从零开始,使用STM32CubeMX和HAL库完成PWM捕获功能的完整实现。不同于简单的教程复制,我们会深入探讨两种捕获…...

Jimeng AI Studio应用场景:独立艺术家数字创作工作流整合方案

Jimeng AI Studio应用场景:独立艺术家数字创作工作流整合方案 1. 引言:当艺术家遇见AI 想象一下,你是一位独立艺术家或设计师。灵感来了,你想立刻把它变成一幅画、一张海报,或者一个全新的视觉概念。但传统的数字创作…...

Go语言中的正则表达式

Go语言中的正则表达式 1. 正则表达式的基本概念 正则表达式是一种用于匹配字符串中字符组合的模式。在Go语言中,正则表达式通过regexp包来实现。 2. 基本用法 2.1 编译正则表达式 package mainimport ("fmt""regexp" )func main() {// 编译正则…...

Go语言中的字符串处理

Go语言中的字符串处理 1. 字符串的基本概念 在Go语言中,字符串是一种不可变的字节序列,使用UTF-8编码。字符串的类型为string,是Go语言的基本类型之一。 package mainimport "fmt"func main() {// 字符串字面量s1 : "Hello, W…...

Go语言中的包管理

Go语言中的包管理 1. 包管理的基本概念 包管理是Go语言开发中的重要部分,它负责管理项目的依赖关系。Go语言的包管理经历了几个阶段: GOPATH模式vendor模式Go Modules模式(当前推荐) 2. Go Modules简介 Go Modules是Go 1.11引入的…...

Minecraft启动器与游戏配置工具全攻略:从新手到大师的进阶指南

Minecraft启动器与游戏配置工具全攻略:从新手到大师的进阶指南 Minecraft启动器是每一位玩家进入方块世界的第一道门,而一款优秀的游戏配置工具则能让你的冒险之旅更加顺畅。本文将以玩家视角,带你深入了解如何利用PCL2-CE这款强大的开源工具…...

终极EdgeRemover指南:专业卸载Windows Edge浏览器的完整解决方案

终极EdgeRemover指南:专业卸载Windows Edge浏览器的完整解决方案 【免费下载链接】EdgeRemover PowerShell script to remove Microsoft Edge in a non-forceful manner. 项目地址: https://gitcode.com/gh_mirrors/ed/EdgeRemover EdgeRemover是一款专业的P…...

《Linux网络编程》2.Socket编程(UDP/TCP)

💡Yupureki:个人主页 ✨个人专栏:《C》 《算法》《Linux系统编程》《高并发内存池》《MySQL数据库》 《个人在线OJ平台》《Linux网络编程》 🌸Yupureki🌸的简介: 目录 1. UDP编程 1.1 常用接口 1.1.1 socket() – 创建套接字 1.1.2 bin…...

网安实验干货每日分享(Weevely配置使用)

网安实验干货每日分享(Weevely配置使用)-1031 渗透测试环境搭建与工具使用-Weevely配置使用 实验目的 熟悉Webshell管理工具Weevely的配置使用。 实验环境 操作机:Kali2018-TS (1)操作系统:Kali Linu…...

革新游戏配置体验:PCL2-CE社区版,Minecraft玩家的效率神器

革新游戏配置体验:PCL2-CE社区版,Minecraft玩家的效率神器 PCL2-CE社区版是一款开源游戏配置工具,它不仅能让玩家轻松管理Minecraft游戏环境,更能通过智能时间管理、跨平台同步等功能,为玩家节省宝贵的游戏时间&#…...

新手必看,用快马生成的示例代码轻松学懂stm32f103c8t6引脚配置

作为一个刚接触STM32的开发者,我完全理解新手面对芯片引脚配置时的困惑。最近在InsCode(快马)平台尝试生成STM32F103C8T6的示例代码时,发现它特别适合用来建立引脚功能与代码的映射关系。下面分享我的学习过程: 理解芯片引脚特性 STM32F103C…...

终极AI图像分层指南:3分钟将复杂插画变成可编辑PSD图层

终极AI图像分层指南:3分钟将复杂插画变成可编辑PSD图层 【免费下载链接】layerdivider A tool to divide a single illustration into a layered structure. 项目地址: https://gitcode.com/gh_mirrors/la/layerdivider 你是否曾面对一幅精美的数字插画&…...

智能音乐情绪生成器:当AI遇见音乐,用代码谱写情感旋律

引言:音乐与情感的数字化探索音乐是人类情感最直接的表达方式之一,欢快的旋律让人振奋,悲伤的曲调令人沉思。在人工智能时代,我们能否让机器理解情感,并创作出符合特定情绪的音乐?本文将带你走进一个融合了…...

攻克模电难点(一):多级放大电路与差动放大电路实战解析

1. 多级放大电路的设计基础 第一次接触多级放大电路时,我被各种耦合方式绕得头晕。直到在实验室烧坏几个三极管后,才真正理解其中的门道。多级放大电路的核心思想很简单:把多个单级放大电路像搭积木一样连接起来,但实际设计时却要…...

ai辅助开发:向快马描述你的微服务项目,智能生成全套java环境配置与编排文件

最近在搭建一个分布式微服务项目时,遇到了环境配置这个老大难问题。不同模块需要不同中间件,团队成员电脑环境各异,每次新人加入都要折腾半天环境。好在发现了InsCode(快马)平台的AI辅助开发功能,用自然语言描述需求就能自动生成全…...

Apache Paimon面试通关秘籍-快照机制深度解析

1. 快照机制:Paimon的时光机原理 第一次接触Paimon的快照功能时,我脑海中浮现的是《哆啦A梦》里的时光机——它能带你回到任意时间点查看数据的历史状态。这个看似简单的功能背后,其实藏着Paimon最核心的设计哲学。 快照本质上就是数据表在某…...

JavaScript基础课程二、学习JavaScript路线图

JavaScript 全栈学习路线 JavaScript 基础→进阶→高级→跨平台实战 这是一套零基础可入门、循序渐进、覆盖全场景的 JavaScript 学习路线,包含学习重点、实战项目、工具资源和避坑指南,学完可独立开发网页、小程序、APP、桌面软件、后端服务。 一、先搞懂:JavaScript 到…...

VisualCppRedist AIO:Windows系统运行库的一站式解决方案

VisualCppRedist AIO:Windows系统运行库的一站式解决方案 【免费下载链接】vcredist AIO Repack for latest Microsoft Visual C Redistributable Runtimes 项目地址: https://gitcode.com/gh_mirrors/vc/vcredist VisualCppRedist AIO是一个开源项目&#x…...

从滤波到故障诊断:手把手教你用MATLAB实现信号互相关分析的实际项目

从振动信号到故障定位:MATLAB互相关分析的工业实战指南 车间里那台大型离心泵的异常振动已经持续两周了。王工程师带着加速度传感器采集了三组不同位置的振动信号,屏幕上跳动的波形看起来杂乱无章。"到底是轴承磨损还是叶轮不平衡?"…...

Calico-Node Pod 启动时 READY 状态卡在 0/1 排查流程

Calico Node 启动失败 故障表现 发现请求集群 demo 入口时卡住,并且对应 Pod 没有新的日志输出 rootce-demo-1:~# kubectl get pods -n deepflow-otel-spring-demo -o wide NAME READY STATUS RESTARTS AGE IP …...

Linux日志高效搜索:从基础grep到journalctl实战技巧

1. Linux日志搜索:运维工程师的必备技能 每次服务器出现异常,第一反应是什么?没错,就是查日志。作为在Linux系统摸爬滚打多年的老运维,我见过太多新手面对海量日志时的手足无措。其实日志排查就像破案,关键…...

关于爬虫源影视资源设置

1.首先目前的omnibox的版本已更新到2.0.3版本,之前的配置会丢失,原本的资源都会无法使用,这里以新版本增加数据源,看完以下教程再下载脚本。 2.添加爬虫源,这里以猫眼资源为主测试: 增加脚本之后,点击保存即可! 复制以下脚本,修复改site_api即可,一般公用的资源都是正…...

【无标题】修改+删除顶层class

# 最顶层的class信息如何删除-- 步骤1:删除该班级学生关联的成绩(先删最底层score表) DELETE FROM score WHERE studentNo IN (SELECT studentNo FROM student0 WHERE classNo210601);-- 步骤2:删除该班级的所有学生(再…...

Java Web 入门学习笔记:Servlet 请求响应与登录功能实战

一、开篇:今日学习核心与目标学习背景:Java Web 入门阶段核心 ——Servlet 与 HTTP 请求响应交互学习目标:掌握 HttpServletRequest/HttpServletResponse 核心用法实现「登录表单提交→Servlet 验证→页面重定向」完整流程解决实操中 404、中…...

AI编程革命:重塑程序员未来(一)

AI编程时代到来AI不会让程序员消失,但会深刻重塑这个职业。当代码生成变得轻而易举,程序员 的角色将从“代码编写者”升级为“问题解决者”与“架构设计师”。未来的核心竞争力,在于 理解复杂业务、设计系统逻辑,并用人类独有的创…...

K均值算法(C++版)

选用K均值算法对一串整形数据(100行,100列)进行聚类。输出两个结果文件:1)第一个输出结果文件为cluster_centers.txt,其中输出聚类得到的各区域(聚类)的中心,以及每个聚类…...

Nginx 高可用、负载均衡与 HTTPS 配置实战(一)

Nginx作为当下最主流的开源反向代理与Web服务器,凭借轻量、高性能、高并发的特性,成为企业级服务入口的首选方案。在生产环境中,单节点Nginx存在单点故障风险,并发请求过高会导致服务卡顿,同时HTTP明文传输存在数据泄露…...

bilibili-api技术解析:如何解决视频标识符转换核心问题

bilibili-api技术解析:如何解决视频标识符转换核心问题 【免费下载链接】bilibili-api 哔哩哔哩常用API调用。支持视频、番剧、用户、频道、音频等功能。原仓库地址:https://github.com/MoyuScript/bilibili-api 项目地址: https://gitcode.com/gh_mir…...

11. v4 版本升级指南

11. v4 版本升级指南 1. 概述 Tailwind CSS v4 是一个重大版本更新,从 JavaScript 配置转向 CSS 优先的配置方式。 1.1 主要变化 变化v3v4配置方式tailwind.config.jsCSS 文件 (theme)安装方式postcss tailwindcsstailwindcss/vite 等暗色模式dark: 前缀相同&a…...

告别硬编码!用Rule-Engine 1.0.0重构你的Java业务逻辑(附订单折扣实战)

告别硬编码!用Rule-Engine 1.0.0重构你的Java业务逻辑(附订单折扣实战) 每次电商大促前夜,技术团队最怕听到的一句话是什么?"折扣规则又改了!"——这往往意味着通宵修改代码、紧急测试和冒着风险…...