STM32F103VET6 ADC架构解析:从ADC1/2/3硬件到ADC12/123协同模式 1. 项目概述从ADC1到ADC123一次搞懂STM32F103VET6的模数转换器如果你正在用STM32F103VET6这颗经典的“国民MCU”做项目无论是采集传感器数据、监测电池电压还是做简单的信号分析ADC模数转换器功能几乎是你绕不开的一环。但当你打开数据手册和CubeMX配置工具看到ADC1、ADC2、ADC3以及ADC12、ADC123这些术语时是不是感觉有点懵它们到底指的是同一个东西的不同叫法还是完全不同的功能实体我刚开始接触STM32时也在这个问题上卡了很久。简单来说在STM32F103VET6上ADC1、ADC2、ADC3是三个独立的ADC外设硬件模块而ADC12、ADC123则描述了这些硬件模块之间可以协同工作的模式特别是“双ADC模式”和“三ADC模式”。理解这背后的硬件架构和软件配置逻辑是高效、稳定使用ADC的关键。否则你可能会遇到采样数据错乱、DMA传输异常或者资源浪费、性能无法发挥的问题。这篇文章我就结合自己踩过的坑和项目经验帮你彻底理清STM32F103VET6上ADC1、ADC2、ADC3以及ADC12、ADC123的概念、联系、配置方法和典型应用场景。目标是让你看完后不仅能正确配置更能理解为什么这么配从而在设计系统时做出最优选择。2. 核心概念解析硬件实体与工作模式要理解ADC1/2/3和ADC12/123我们必须先深入到STM32F103VET6的芯片内部去看它的ADC子系统架构。这不仅仅是命名差异而是硬件资源和软件调度逻辑的体现。2.1 ADC1, ADC2, ADC3三个独立的硬件转换器STM32F103VET6内部集成了最多3个12位精度的逐次逼近型模数转换器。你可以把它们想象成三个独立的“测量员”。ADC1这是功能最全的“主力测量员”。它通常拥有最多的外部通道具体数量取决于封装和引脚复用并且是唯一一个支持DMA传输的ADC。这意味着ADC1可以连续采样并通过DMA自动把数据搬运到内存完全不需要CPU干预效率极高。在单ADC工作模式下我们最常使用的就是ADC1。ADC2可以看作是ADC1的“搭档”。它的通道通常与ADC1的部分通道共享外部引脚即同一个引脚既可以给ADC1用也可以给ADC2用。但ADC2不支持独立的DMA。在双ADC模式下它需要和ADC1配合由ADC1来触发DMA。ADC3在一些型号如VET6中提供是第三个“测量员”。它的通道可能独立也可能与前面两个共享。和ADC2一样ADC3通常也不支持独立的DMA需要在多ADC模式下协同工作。注意具体每个ADC有多少个外部通道哪些通道是共享的一定要查阅你所使用的具体型号STM32F103VET6的**数据手册Datasheet中的“Pinouts and pin description”章节和参考手册Reference Manual**中的ADC章节。例如VET6的ADC1可能有16个外部通道而ADC2和ADC3可能少一些。2.2 ADC12与ADC123协同工作的“团队模式”当单个“测量员”速度不够或者你需要同步采集多个相关信号时就需要团队协作。这就是ADC12和ADC123模式的意义。ADC12模式指ADC1和ADC2组成一个团队在特定的同步模式下工作。它不是指一个叫“ADC12”的新硬件而是ADC1和ADC2这两种硬件资源的一种协同工作状态。在CubeMX中当你启用ADC2时软件层面通常就会涉及ADC12模式的配置。ADC123模式同理指ADC1、ADC2和ADC3三个硬件模块组成团队协同工作。为什么需要团队工作主要是为了实现更高级的采样功能交替采样ADC1和ADC2轮流对同一个通道进行采样。比如ADC1采一次紧接着ADC2采一次然后再ADC1...这样可以在不提高单个ADC转换速度的情况下有效提升对同一信号的采样率。同步采样ADC1和ADC2在同一个时刻对不同的通道进行采样。这对于需要保持相位关系的信号至关重要比如电机控制中同时采集三相电流。注入通道这是一种可以打断常规序列采样的“插队”机制。在多ADC模式下注入通道的管理会更复杂功能也更强大。2.3 关键区别与联系总结为了更直观我们可以用一个表格来对比特性ADC1 (独立硬件)ADC2/ADC3 (独立硬件)ADC12/123 (工作模式)本质独立的ADC外设单元独立的ADC外设单元ADC1与ADC2/ADC3的协同工作状态DMA支持支持可独立使用DMA通常不支持独立DMA需依赖ADC1的DMA在同步模式下通常由ADC1的DMA统一搬运数据触发源丰富TIM、EXTI等丰富但常与ADC1同步触发触发主ADC通常是ADC1从ADC跟随动作典型用途单通道高速采样、多通道扫描独立使用必须与ADC1配合用于双/三ADC模式提高采样率交替、同步采样多路信号、复杂序列采样配置体现在CubeMX中作为一个外设单独配置在CubeMX中作为独立外设配置但模式依赖ADC1在ADC1的“Parameter Settings”中“Multimode Mode”选项下选择如“Dual Regular simultaneous mode”核心联系你必须先有ADC1、ADC2这些硬件才能让它们以ADC12的模式去工作。ADC12是功能ADC1和ADC2是实现这个功能的资源。在代码中你操作的对象始终是hadc1,hadc2这些实体句柄但通过配置它们的同步关系来实现ADC12模式的功能。3. 实战配置详解从CubeMX到代码理论清楚了我们动手配置。这里以最常用的ADC1独立模式和ADC1与ADC2同步模式为例讲解如何在STM32CubeMX和HAL库中实现。3.1 场景一独立使用ADC1进行多通道扫描这是最基础、最常用的场景。假设我们需要循环采集3个传感器的电压通道1, 2, 3。CubeMX配置步骤引脚分配在Pinout Configuration视图找到你需要使用的模拟输入引脚例如PA1, PA2, PA3将其功能设置为ADC1_IN1,ADC1_IN2,ADC1_IN3。ADC1参数设置在左侧导航栏找到Analog-ADC1。Resolution: 选择12 Bits。分辨率越高转换时间越长。Scan Conversion Mode:启用Enabled。这是多通道扫描的关键。Continuous Conversion Mode: 根据需求选择。启用则自动连续转换禁用则需要手动或定时器触发。Discontinuous Conversion Mode: 通常禁用。DMA Continuous Requests: 如果启用了连续转换并打算用DMA必须启用此项否则DMA只传输一次。End Of Conversion Selection: 选择EOC flag after each conversion每个通道转换后产生EOC或EOC flag after sequence整个序列转换后产生一个EOC。对于DMA多通道传输通常选后者。规则通道配置切换到Regular Channels标签。在Rank中依次添加你的通道。Rank 1选择Channel 1Sampling Time选择一个时间如Cycles 239.5时间越长抗噪性越好但速度越慢。然后添加Rank 2Channel 2Rank 3Channel 3。这个顺序就是ADC扫描采样的顺序。DMA配置强烈推荐在DMA Settings标签点击Add。DMA Request选择ADC1。Mode选择Circular循环模式这样DMA会不间断地自动搬运数据。Data Width选择Word32位因为HAL库的ADC值存放在uint32_t类型的变量中。代码要点与解析// 1. 定义缓冲区 uint32_t adc_buf[3]; // 存放3个通道的数据 // 2. 启动ADC的DMA转换 HAL_ADC_Start_DMA(hadc1, (uint32_t*)adc_buf, 3); // 参数解释hadc1 - ADC1句柄 // adc_buf - 目标内存地址 // 3 - 需要转换的数据长度等于通道数 // 此后adc_buf数组就会被DMA自动更新内容为[通道1值, 通道2值, 通道3值] // 无需在main循环中调用HAL_ADC_GetValue // 3. 将原始值转换为电压假设Vref 3.3V float voltage_ch1 (float)adc_buf[0] / 4095.0f * 3.3f; // 12位精度满量程4095实操心得Sampling Time采样时间的配置至关重要。对于高输出阻抗的传感器如果采样时间太短ADC内部的采样电容来不及充到稳定电压会导致读数不准。一个简单的原则信号源阻抗越高需要的采样时间越长。如果不确定可以先设一个较长的值如239.5 Cycles确保读数稳定再尝试缩短以提升速度。3.2 场景二配置ADC1与ADC2同步采样不同通道现在我们需要同时采集两个信号比如电机的电流和电压要求采样时刻严格对齐。这就需要使用ADC12的同步模式。CubeMX配置步骤配置ADC1主ADC基本设置同上分辨率、扫描模式等。关键步骤在Multimode Mode下拉框中选择一种同步模式。例如Dual Regular simultaneous mode only仅规则通道同步模式。ADC1的DMA必须启用。配置ADC1的规则通道例如Channel 1。配置ADC2从ADC启用ADC2。其Multimode Mode会自动关联无需额外设置。注意ADC2的Scan Conversion Mode和Continuous Conversion Mode应与ADC1保持一致。配置ADC2的规则通道例如Channel 2。它的转换将由ADC1的触发事件来同步启动。DMA配置只在ADC1下配置DMA。因为在这种模式下ADC1和ADC2转换完成的数据会通过一个特定的数据寄存器ADC_CDR被ADC1的DMA统一读取。代码要点与解析// 1. 定义缓冲区。在同步模式下ADC1和ADC2的数据会交错存储。 uint32_t adc_sync_buf[2]; // 索引0放ADC1数据索引1放ADC2数据 // 2. 启动同步转换。只需要启动主ADC1的DMA。 HAL_ADCEx_MultiModeStart_DMA(hadc1, (uint32_t*)adc_sync_buf, 2); // 注意这里使用的是 HAL_ADCEx_MultiModeStart_DMA 而不是普通的 HAL_ADC_Start_DMA // 3. 数据处理 uint16_t adc1_value adc_sync_buf[0] 0xFFFF; // 低16位是ADC1数据 uint16_t adc2_value adc_sync_buf[1] 0xFFFF; // 高16位是ADC2数据取决于模式需查手册 // 更准确的获取方式应参考参考手册中关于双ADC模式数据寄存器的描述 // 对于F1系列通常使用 HAL_ADCEx_MultiModeGetValue 函数来获取组合后的值并解析踩坑记录双ADC模式下的数据排列格式是最大的坑点之一。不同的同步模式如Simultaneous、Interleaved、Alternate triggerADC1和ADC2的数据在ADC_CDR寄存器或DMA缓冲区中的排列顺序可能不同。务必查阅《参考手册》的“双ADC模式”章节找到对应的数据格式图否则解析出的数据全是错的。我建议在初始化后用已知电压测试每个通道打印出原始数据确认排列顺序。4. 时钟与采样率计算让你的ADC跑在最佳状态ADC的性能和采样率直接受到时钟频率的影响。STM32F103的ADC时钟ADCCLK由PCLK2APB2时钟分频而来。配置不当会导致采样率达不到要求或者转换精度下降。4.1 时钟树配置分析在CubeMX的Clock Configuration标签页系统时钟SYSCLK通常设为72MHzF103的最高频率。APB2总线时钟PCLK2默认与SYSCLK同频即72MHz。ADC时钟ADCCLK必须由PCLK2经过分频得到且最大不能超过14MHz这是STM32F103 ADC模块的极限。因此最常用的配置是将PCLK2的72MHz进行6分频得到12MHz的ADCCLK。这个频率既安全又能提供不错的转换速度。4.2 单次转换时间与最大采样率计算一次ADC转换所需的总时间Tconv由两部分组成Tconv 采样时间 转换时间采样时间Tsampling在CubeMX的Sampling Time中选择例如239.5 Cycles。这个周期数是ADCCLK的周期数。Tsampling 采样周期数 / ADCCLK。转换时间Tconversion对于12位分辨率固定为12.5个ADCCLK周期。举例计算ADCCLK 12 MHz采样时间选择 239.5 Cycles总周期数 239.5 12.5 252 CyclesTconv 252 / 12 MHz ≈21 us对应的最大采样率≈ 1 / 21 us ≈47.6 kSPS(每秒千次采样)注意事项这是单个通道单次转换的理论极限。如果使用多通道扫描总转换时间需要乘以通道数。如果使用DMA连续传输实际可持续的采样率就是1 / Tconv。另外12.5这个固定转换周期数很重要很多人在计算时漏掉它导致预期的采样率远高于实际值。4.3 双ADC模式下的采样率提升在交替采样模式Interleaved下ADC1和ADC2轮流对同一通道采样。假设每个ADC的单次转换时间仍是21us但由于它们交替工作从系统角度来看采样间隔就缩短到了约10.5us等效采样率提升至约95.2 kSPS。这是利用ADC12模式提升单通道采样率的典型方法。5. 常见问题排查与调试技巧即使配置正确ADC采样也常常会遇到各种“玄学”问题。下面是我总结的几个高频问题点和排查思路。5.1 问题一采样值不稳定跳动大可能原因1电源和参考电压噪声。排查确保模拟部分电源VDDA干净稳定并与数字电源VDD通过磁珠或0Ω电阻隔离在靠近芯片引脚处并联10uF和0.1uF的退耦电容。如果使用内部参考电压需注意其精度和温漂。解决为VDDA使用独立的LDO供电并增加LC滤波。对于高精度应用考虑使用外部基准电压源芯片。可能原因2采样时间不足。排查信号源有较高的输出阻抗如分压电阻、某些传感器ADC的采样开关阻抗与之形成RC电路充电需要时间。解决在CubeMX中大幅增加Sampling Time如设置为最大239.5 Cycles观察跳动是否减小。如果是则说明需要更长的采样时间或者需要在信号源和ADC输入之间增加一个电压跟随器运放来降低输出阻抗。可能原因3数字信号干扰。排查ADC输入引脚附近有高速数字信号如PWM、SPI时钟频繁翻转。解决布线时让模拟走线远离数字走线。在软件上可以在ADC采样期间短暂关闭附近不必要的高速外设。5.2 问题二DMA传输不工作或数据错位可能原因1DMA缓冲区溢出或配置错误。排查检查DMA是否配置为Circular模式。检查缓冲区大小是否足够Size参数应等于需要转换的总通道数。在双ADC模式下缓冲区大小和数据结构要匹配复杂的多ADC数据格式。解决使用调试器查看DMA相关寄存器如CNDTR是否在递减。在DMA传输完成中断HAL_ADC_ConvCpltCallback中设置断点看是否能进入。可能原因2多ADC模式数据解析错误。现象双ADC模式能进DMA中断但读出的数据明显不对比如两个通道值相同或为0。解决这是最经典的问题。回头仔细看《参考手册》找到你所用同步模式如“Dual Simultaneous Mode”对应的数据寄存器ADC_CDR结构图。写一个简单的测试代码让ADC1和ADC2采集两个已知的不同电压如3.3V和GND然后打印出DMA缓冲区里的原始32位数据对照手册逐位分析确认ADC1和ADC2的数据分别在哪几个比特位。5.3 问题三注入通道与规则通道冲突现象规则通道在循环采样但偶尔需要紧急采样一个关键信号如过流保护使用了注入通道。发现注入通道采样后规则通道的序列被打乱或DMA错乱。原因注入通道拥有更高优先级会中断规则通道的转换。转换完成后规则通道的序列是从中断点继续还是重新开始取决于JAUTO位和DISCEN位的配置。解决如果希望注入转换后规则序列继续需禁用自动注入JAUTO0并合理配置不连续模式。更稳妥的做法是在注入通道转换完成后手动重启规则通道的DMA转换先Stop再Start。5.4 调试利器ADC的看门狗与中断除了DMA善用ADC的内部看门狗Analog Watchdog和中断能极大提升系统可靠性。模拟看门狗可以为一个或一组通道设置电压阈值高阈值和低阈值。当采样值超出这个窗口范围时会触发中断。非常适合用于电池电压监控、故障检测等场景无需CPU不断轮询ADC值。转换完成中断EOC即使不用DMA在单通道单次转换模式下使能EOC中断在中断服务程序里读取数据也是一种简单可靠的异步采样方式尤其适合低速、非连续的采样需求。我个人在复杂项目中通常会采用“DMA连续传输规则通道 看门狗监控关键注入通道”的组合方案。DMA负责高效搬运大量的常规采样数据而看门狗则像一名忠诚的哨兵只在异常发生时才打断CPU实现了效率与安全性的平衡。