C++如何通过单片机定时器级联同步触发ADC瞬时采样

小涛小哥_4300

小涛小哥_4300

2026-10-30

974人浏览

原创

硬件前提是单片机支持定时器TRGO事件输出及主从级联,如STM32F4/F7/H7、GD32F4系列;主定时器需配置MMS=0b100输出UEV,从定时器设为外部时钟或触发模式并选择对应TRGO源,ADC须关闭软件启动且EXTSEL指向从定时器TRGO,所有时钟与参数须预先配置完成。

c++如何通过单片机定时器级联同步触发adc瞬时采样

定时器级联触发ADC的硬件前提是什么

单片机必须支持定时器输出事件(如TRGO)作为ADC的外部触发源,且至少有两个定时器能配置为主从关系。常见满足条件的平台包括STM32F4/F7/H7系列(TIM2/TIM3可设为主,TIM8/TIM1可设为从)、GD32F4系列;而基础型如STM32F0或某些8位MCU通常不支持TRGO级联,强行配置会导致ADC_CR2_EXTEN无效或采样时序漂移。

  • 主定时器需启用更新事件输出(TIMx_CR2_MMS = 0b100),这是触发链起点
  • 从定时器必须配置为“外部时钟模式1”或“触发模式”,并选择主定时器的TRGO为输入源(TIMx_SMCR_TS = 0b101等,具体值查对应芯片参考手册)
  • ADC必须关闭软件启动(ADC_CR2_EXTEN != 0),且EXTSEL字段指向从定时器的触发信号(如EXTSEL = 0b1010对应TIM3_TRGO)
  • 所有模块时钟必须已使能,且ADC预分频、采样周期等参数在触发前完成配置,否则首次触发可能丢失

为什么用两个定时器而不是一个定时器+ADC直接触发

单个定时器的更新事件(UEV)虽然能直接触发ADC,但无法实现「多路同步瞬时采样」所需的精细相位控制。比如需要对三相电流(IA/IB/IC)在电角度0°、120°、240°三个严格等间隔点同时采样,此时:

  • 主定时器生成基准周期(如PWM载波周期),输出TRGO到从定时器
  • 从定时器配置为“复位模式”,其计数器由主TRGO清零,并通过TIMx_CCRx设置不同比较值,分别输出TRGO1/TRGO2/TRGO3到多个ADC(若芯片支持多ADC同步)或分时触发同一ADC的多个通道(需配合注入组)
  • 若只用一个定时器,所有ADC触发沿完全重合,无法错开采样时刻;而级联后,从定时器的比较事件可精确偏移主周期的任意整数倍TCLK,误差仅取决于定时器时钟抖动(通常

STM32中配置TIM2→TIM3→ADC1的典型寄存器顺序

顺序错误会导致触发静默或时序紊乱,尤其注意时钟使能与寄存器写入的依赖关系:

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 先开启所有相关时钟:RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN;,RCC->AHB1ENR |= RCC_AHB1ENR_ADC1EN;
  • 配置主定时器TIM2:自动重装载值TIM2->ARR = 999(1kHz基准),预分频TIM2->PSC = 83(假设84MHz APB1),然后设置TIM2->CR2 = TIM_CR2_MMS_2(MMS=100b → TRGO=UEV)
  • 配置从定时器TIM3:先清零TIM3->CR1 = 0,再设TIM3->SMCR = TIM_SMCR_TS_2 | TIM_SMCR_SMS_2(TS=101b选TIM2_TRGO,SMS=010b为触发模式),最后设TIM3->ARR = 333,TIM3->CCR1 = 111(用于ADC触发点)
  • ADC1配置:确保ADC1->CR2 |= ADC_CR2_EXTEN_1(上升沿触发),ADC1->CR2 &= ~ADC_CR2_EXTSEL,再置ADC1->CR2 |= (0b1010 (EXTSEL=1010 → TIM3_TRGO)
  • 最后统一使能:先启TIM2(TIM2->CR1 |= TIM_CR1_CEN),再启TIM3(TIM3->CR1 |= TIM_CR1_CEN),最后启ADC(ADC1->CR2 |= ADC_CR2_ADON)

实际运行中容易忽略的同步失效点
  • 主定时器未真正产生TRGO:检查TIMx_CR2_MMS是否写入成功(有些库函数会覆盖该位),以及TIMx_EGR是否手动触发过一次更新事件(TIMx_EGR = TIM_EGR_UG)来初始化TRGO电平
  • 从定时器未响应TRGO:确认TIMx_SMCR_TS选择的触发源编号与主定时器实际输出TRGO的编号一致(例如TIM2_TRGO是TS=101b,但误配成100b就会静默)
  • ADC触发延迟超预期:若使用高分辨率(如16位)或慢速时钟(如ADCCLK=14MHz),ADC_SMPR1中通道采样时间设置过短会导致转换未完成就被下一次触发打断,表现为ADC_DR读数恒为0或随机跳变
  • 多ADC同步时DMA地址未对齐:当TIM3_TRGO同时触发ADC1和ADC2,若两路DMA目标缓冲区起始地址非字对齐(如uint16_t buf[1024]定义在栈上导致地址奇数),可能引发总线错误而非单纯采样失败

级联触发本身不难,难的是每个环节的时序约束都得卡准——主从定时器的时钟域切换、ADC模拟前端建立时间、DMA搬运带宽,任何一环没压住,同步就变成“看起来同步,实则各采各的”。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2268

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1039

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

447

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

426

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

600

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1429

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1237

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习