STM32F103 TIM1四通道单脉冲输出:ETR触发配置与避坑指南

发布时间:2026/10/15 17:33:41

STM32F103 TIM1四通道单脉冲输出:ETR触发配置与避坑指南 简介这份资源面向STM32F103嵌入式开发者与定时器学习者聚焦高级定时器TIM1的ETR外部触发输入与四通道单脉冲输出One Pulse Mode实现解决外部事件触发下多路精确时序脉冲生成的问题适合具备一定寄存器与固件库基础的中级开发者参考。压缩包内仅1个C源文件体积约868B代码围绕TIM1时钟使能、ETR引脚输入配置、单脉冲模式初始化及各通道比较值设定展开可直接嵌入工程验证。目前已有4740人学习下载热度较高。读者可从中获取ETR驱动四通道独立脉冲输出的完整配置思路理解各通道比较寄存器如何决定脉冲宽度与输出时序并借鉴外部触发启动、计数到达后自动停止的机制为电机控制、信号发生与同步信号生成等场景提供可复用的代码骨架与排错参考。1. 单脉冲输出踩坑记为什么四路通道偏偏卡在 ETR 上去年帮一个做步进电机驱动的朋友调板子STM32F103 的 TIM1 要输出四路单脉冲每路脉冲宽度和延时都不同用来分别驱动四个轴的细分控制器。前两路用 TIM1_CH1、CH2 很顺第三路想用 ETR 引脚做外部触发源时示波器上死活出不来波形。翻了两天参考手册才发现TIM1 的 ETR 在单脉冲模式下有个隐藏前提——它默认是外部时钟输入通道不是普通 PWM 输出通道想让它参与单脉冲输出必须先把从模式控制器配成触发启动再让 ETR 走触发路径而不是时钟路径。这个坑在中文资料里几乎没人讲透。TIM1 作为 STM32F103 的高级定时器单脉冲输出模式One Pulse Mode本身是标准功能但四通道同时用、且其中一路涉及 ETR 引脚时寄存器配置的耦合关系会变得很绕。这篇笔记把 TIM1 四通道单脉冲输出的完整配置链路拆开重点讲 ETR 通道为什么特殊、怎么配、参数怎么算、哪里容易翻车。适合已经会用 TIM 输出 PWM、但被单脉冲模式和 ETR 复用卡住的嵌入式从业者新手跟着步骤也能跑通熟手可以直接看第 4 章的边界条件。2. TIM1 单脉冲模式与 ETR 通道寄存器层面的真实关系2.1 单脉冲模式的本质一次触发只出一个脉冲STM32F103 的 TIM1 单脉冲模式核心逻辑是定时器收到一个触发信号后计数器启动输出一个指定宽度的脉冲然后自动停止等待下一次触发。它和普通 PWM 的区别在于“只出一次”不是连续输出。实现上依赖三个寄存器协同TIM1_CR1的 OPM 位One Pulse Mode置 1开启单脉冲模式。TIM1_CCMRx配置通道为 PWM 模式 2 或输出比较模式决定脉冲极性。TIM1_ARR和TIM1_CCRx决定脉冲周期和占空比也就是脉冲宽度。触发源可以来自软件UG 位、内部时钟、或者外部触发输入。ETR 引脚在这里的角色就是外部触发输入的一个可选路径。2.2 ETR 引脚的双重身份外部时钟还是触发输入ETRExternal Trigger在 TIM1 里默认走的是外部时钟输入路径也就是 TIM1_SMCR 寄存器里 ECE1、SMS111 的配置。但单脉冲模式需要的是“触发启动”对应 SMS110触发模式。这两条路径在寄存器层面是互斥的配错了 ETR 就不会触发单脉冲而是变成外部时钟计数。关键寄存器位寄存器位域单脉冲触发所需值说明TIM1_SMCRSMS[2:0]110触发模式ETR 作为触发源TIM1_SMCRTS[2:0]111触发源选 ETRTIM1_SMCRECE0关闭外部时钟模式TIM1_CR1OPM1单脉冲模式使能TIM1_CCERCCxE1对应通道输出使能这张表是整篇文章最核心的配置依据。很多人卡住就是因为 SMS 和 ECE 同时置了 1结果 ETR 既想当时钟又想当触发硬件行为不可预测。2.3 四通道同时输出的资源冲突点TIM1 有四个独立通道 CH1~CH4但 ETR 是独立引脚不占通道。四通道单脉冲输出时每个通道的 CCRx 可以独立设脉冲宽度但 ARR 是共享的。这意味着四路脉冲的周期必须一致只有宽度可以不同。如果四路需要不同周期单靠 TIM1 做不到得用多个定时器或者软件重载 ARR。另一个冲突点是触发源。四通道如果都要外部触发TIM1 只有一个 ETR 引脚只能接一路外部信号。如果四路需要独立触发ETR 方案就不成立得改用软件触发或者外部中断分别启动。这一点在选型阶段就要想清楚不然后面改板子更麻烦。3. 从零配置四通道单脉冲寄存器操作与 HAL 库两条路3.1 时钟与 GPIO 初始化先把引脚复用配对TIM1 是高级定时器挂在 APB2 总线上时钟使能要开 RCC_APB2ENR 的 TIM1EN 位。GPIO 方面CH1~CH4 对应 PA8、PA9、PA10、PA11ETR 对应 PA12。这四个引脚都要配成复用推挽输出但 ETR 作为触发输入时实际是输入方向GPIO 模式要配成浮空输入或上拉输入。// 使能 TIM1 和 GPIOA 时钟 RCC-APB2ENR | RCC_APB2ENR_TIM1EN | RCC_APB2ENR_IOPAEN; // PA8~PA11 复用推挽输出50MHz GPIOA-CRH ~(0xFF 0); // 清 PA8~PA11 GPIOA-CRH | (0xBB 0); // 1011: 复用推挽, 50MHz // PA12 浮空输入作为 ETR 触发输入 GPIOA-CRH ~(0xF 16); GPIOA-CRH | (0x4 16); // 0100: 浮空输入这里有个容易翻车的点PA12 如果配成复用推挽输出ETR 就变成输出方向触发信号进不来。必须配成输入模式。很多人照着 PWM 例程改忘了改 PA12 的方向结果 ETR 完全没反应。3.2 时基与单脉冲参数计算ARR 和 CCR 怎么定假设系统时钟 72MHzTIM1 预分频器 PSC71则计数频率 1MHz每个计数 1us。要输出脉冲宽度 100us、周期 500us 的单脉冲ARR 500 - 1 499周期 500usCCR1 100脉冲宽度 100usCCR2 150第二路 150usCCR3 200第三路 200usCCR4 250第四路 250usTIM1-PSC 71; // 72MHz / (711) 1MHz TIM1-ARR 499; // 周期 500us TIM1-CCR1 100; // CH1 脉冲 100us TIM1-CCR2 150; // CH2 脉冲 150us TIM1-CCR3 200; // CH3 脉冲 200us TIM1-CCR4 250; // CH4 脉冲 250us参数说明PSC 和 ARR 都是 16 位寄存器最大值 65535。如果需要的周期超过 65.535ms1MHz 计数下就得加大 PSC 或者用 32 位定时器。TIM1 是 16 位的这是硬边界。3.3 通道模式与输出使能CCMR 和 CCER 的配法每个通道要配成 PWM 模式 2这样计数器小于 CCRx 时输出有效电平到 CCRx 时翻转配合单脉冲模式就能出一个脉冲。// CH1~CH4 都配 PWM 模式 2 TIM1-CCMR1 (0x70 4) | (0x70 12); // CH1, CH2 TIM1-CCMR2 (0x70 4) | (0x70 12); // CH3, CH4 // 使能所有通道输出高电平有效 TIM1-CCER TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC3E | TIM_CCER_CC4E;CCMR 的 OCxM 位设成 111 就是 PWM 模式 2。注意 CCMR1 控制 CH1 和 CH2CCMR2 控制 CH3 和 CH4别写错寄存器。3.4 ETR 触发路径配置SMCR 寄存器的精确写法这是整篇文章最关键的一步。ETR 要作为触发源SMCR 必须这样配// ETR 作为触发源触发模式关闭外部时钟 TIM1-SMCR TIM_SMCR_TS_2 | TIM_SMCR_TS_1 | TIM_SMCR_TS_0 | // TS111, 选 ETR TIM_SMCR_SMS_2 | TIM_SMCR_SMS_1; // SMS110, 触发模式 // ECE 位保持 0不使能外部时钟TS111 选 ETR 作为触发输入SMS110 进入触发模式。ECE 必须为 0否则 ETR 会走外部时钟路径单脉冲模式失效。这个配置顺序也有讲究先配 SMCR再使能 OPM最后开定时器。3.5 启动与验证OPM 位和 UG 位的时序TIM1-CR1 | TIM_CR1_OPM; // 单脉冲模式 TIM1-CR1 | TIM_CR1_CEN; // 启动定时器 TIM1-EGR | TIM_EGR_UG; // 软件产生一次更新加载寄存器UG 位的作用是手动产生一次更新事件把 PSC、ARR、CCRx 的值加载到影子寄存器。如果不加这一步第一次触发时寄存器值可能还没生效脉冲宽度会不对。这是血泪经验调试时示波器上第一个脉冲总是怪怪的加了 UG 就正常了。验证方法用信号发生器给 PA12 一个上升沿示波器接 PA8~PA11应该看到四路不同宽度的脉冲各出一个然后停止等下一个上升沿再出。如果某一路不出先查对应 CCER 位和 GPIO 配置。4. 避坑与排查ETR 单脉冲最常见的五个翻车点4.1 现象ETR 引脚有触发信号但四路都没输出原因SMCR 的 SMS 位配成了 000内部时钟模式或者 ECE 位误置 1 导致 ETR 走了外部时钟路径单脉冲模式根本没启动。解决读 TIM1-SMCR 的值确认 SMS110、TS111、ECE0。如果用的是 HAL 库检查 HAL_TIM_OnePulse_Start 之前有没有调 HAL_TIM_SlaveConfigSynchro 配触发源。4.2 现象只有 CH1 出脉冲CH2~CH4 没反应原因CCER 寄存器只使能了 CC1E其他通道的使能位没置 1。或者 CCMR2 写错CH3、CH4 的模式位没配对。解决直接读 TIM1-CCER确认低 8 位是 0x11CC1E~CC4E 都置 1。CCMR2 的 OC3M 和 OC4M 都要设成 111。4.3 现象脉冲宽度和 CCR 值对不上偏差很大原因UG 位没置影子寄存器没加载第一次触发用的是复位值。或者 PSC 配错实际计数频率和预期不符。解决在 CEN 置 1 之后、触发之前手动置一次 UG。用示波器测实际脉冲宽度反推计数频率验证 PSC 和 ARR 的计算。4.4 现象第二个触发来了没反应只出一次脉冲原因单脉冲模式触发后TIM1_CR1 的 CEN 位被硬件自动清零定时器停了。下一次触发需要重新置 CEN。解决在触发中断或者外部中断里重新置 CEN 和 UG。如果用的是 ETR 触发硬件不会自动重新使能必须在软件里处理。4.5 现象四路脉冲同时出但相位完全一样没有先后原因四通道共享同一个计数器和 ARRCCRx 只决定脉冲宽度不决定起始时刻。如果四路需要错开起始时间单靠 TIM1 的 CCRx 做不到。解决需要错相的话用四个独立定时器或者用 DMA 动态改 CCRx 的值。TIM1 的四通道单脉冲只适合“同时启动、宽度不同”的场景。5. 进阶技巧用 DMA 动态改 CCR 实现变宽度脉冲序列四通道单脉冲输出固定宽度只能应付简单场景。实际项目里经常需要一串宽度递增或递减的脉冲比如驱动步进电机做加减速。这时候可以用 DMA 在每次触发后自动更新 CCRx 的值实现脉冲宽度序列。思路是把一组 CCR 值放在数组里DMA 通道配成内存到外设模式外设地址指向 TIM1-CCR1每次更新事件触发一次 DMA 传输。这样每来一个触发CCR1 就换成下一个值输出宽度就变了。uint16_t ccr_seq[] {100, 150, 200, 250, 300, 350, 400}; // DMA1 通道 2 配到 TIM1_CH1 DMA1_Channel2-CPAR (uint32_t)TIM1-CCR1; DMA1_Channel2-CMAR (uint32_t)ccr_seq; DMA1_Channel2-CNDTR 7; DMA1_Channel2-CCR DMA_CCR_MINC | DMA_CCR_DIR | DMA_CCR_CIRC; DMA1_Channel2-CCR | DMA_CCR_EN; // TIM1 使能 DMA 更新请求 TIM1-DIER | TIM_DIER_UDE;参数说明CIRC 位让 DMA 循环传输数组用完自动回到开头。CNDTR 是传输次数对应数组长度。DIER 的 UDE 位让每次更新事件都发 DMA 请求。这样每触发一次CCR1 就换一个值脉冲宽度按数组顺序变化。验证方法示波器接 PA8给 PA12 一串触发信号应该看到脉冲宽度按 100、150、200 的顺序变化。如果宽度不变查 DMA 的 CPAR 地址对不对DIER 的 UDE 位有没有置。这个技巧的边界是DMA 传输有延迟触发频率太高时 CCR 更新可能跟不上脉冲宽度会乱。实测触发间隔低于 10us 时就不太稳了需要降频或者改用更高主频的型号。从那以后我每次配 TIM1 单脉冲都先把 SMCR 的 SMS 和 ECE 两位单独读出来确认一遍再往下走。这个习惯帮我省了至少三次重新翻手册的时间。希望帮到你。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/15 17:28:39

恶意软件分类数据集实战:从特征工程到模型训练避坑指南

简介:面向恶意软件检测与机器学习研究的数据集资源,适合安全分析人员、算法工程师及高校学生用于恶意软件分类模型训练与特征工程实践。压缩包共25个文件,约19.12MB,涵盖9个CSV特征表与标签文件、6个Python脚本、2个ASM汇编与2个B…

2026/10/15 18:24:16

Windows全版本.NET部署指南:兼容矩阵、安装实操与排错

“又要给人装.NET环境了。”这是我在机房说得最多的一句话。上个月帮同事去客户现场部署一套自研的业务客户端,三台机器三种年代:一台Windows 7 SP1老工控机,一台Windows 10 LTSC,一台刚买的Windows 11笔记本。同一个安装包&#…

2026/10/15 18:24:16

C#控制佳能相机拍照实时传输:EOS SDK调用与避坑指南

简介:这套源码包面向C#开发工程师,解决在Windows平台上通过佳能官方EDSDK控制相机拍照、实时取景与图像传输等需求。程序基于WinForms编写,集成最新版EOS SDK(EDSDK.Dll),兼容EOS 5D Mark II、7D、60D、550…

2026/10/15 18:24:16

armel平台openocd-esp32安装与ESP32调试避坑指南

简介:这是一款面向嵌入式开发者的芯片级调试工具包,专为ESP32无线SoC在Linux ARM架构下的调试、固件烧录与批量生产场景打造。该版本基于OpenOCD 0.11.0,支持JTAG/SWD接口、GDB远程调试服务器、芯片初始化与复位、内存与寄存器读写等核心功能…

2026/10/15 18:19:15

Qt+CMake三大配置范式:从Demo到企业级项目的演进路径

1. 为什么Qt项目里CMakeLists.txt总让人“改得心虚”?你有没有过这种经历:刚用Qt Creator新建一个Qt Widgets Application,点开CMakeLists.txt一看,满屏的find_package(Qt6 REQUIRED COMPONENTS Widgets)、target_link_libraries(…

2026/10/14 11:31:03

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/14 17:41:07

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/15 13:42:16

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/15 0:02:22

防关联浏览器哪个好?三款产品实测差异解析

新手做多店铺,最纠结的就是防关联浏览器选哪个。飞跨、网易、站斧这三款被问得最多,先给结论:要一体化省心、长期便宜,选站斧;要网易招牌和稳,选网易;预算紧做东南亚 Lazada,选飞跨。…

2026/10/15 0:02:22

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成

影刀RPA深度实战:大模型Fine-tuning定制RPA专用Prompt与指令生成 一、技术背景 大模型(LLM)在通用场景下表现强大,但当我们将 GPT-4 或 Qwen 直接用于生成影刀RPA操作指令和 XPath 定位时,准确率通常只有 40%-60%。原因…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑