
1. 项目概述与核心价值在电机控制、并网逆变器或者多轴伺服驱动这类对实时性要求极高的嵌入式系统里我们常常需要同时采集多路模拟信号比如三相电流、母线电压、位置传感器反馈等。这时候ADC的同步操作就成了一个绕不开的核心话题。简单来说同步操作的目标就是让多个ADC模块在同一时刻“按下快门”确保采集到的多路数据在时间轴上是对齐的没有先后误差。这对于后续的算法处理比如克拉克变换、帕克变换或者复杂的观测器计算至关重要。时间上的微小偏差在高速旋转的电机中就可能被放大为明显的角度或电流计算误差直接影响系统的控制精度和稳定性。德州仪器TI的C2000系列微控制器尤其是像TMS320F2837xS这样的多核高性能型号其ADC子系统设计得非常灵活和强大。它内置了多个独立的ADC模块如ADCA, ADCB, ADCC, ADCD每个模块都有一套完整的SOCStart-of-Conversion配置机制。实现同步操作本质上就是对这些SOC的触发源TRIGSEL和采样窗口ACQPS进行精心编排。很多人刚开始接触时可能会有一个误解要实现同步所有ADC的SOC配置必须完全一样并且只能使用一个触发源。但实际上根据官方技术手册的说明只要满足特定条件使用多个触发源同样可以实现同步操作这为复杂的定时采样序列设计提供了更大的灵活性。这篇文章我就结合手册里的理论、代码示例以及我自己在多个电机控制项目中的实际踩坑经验来深入聊聊TMS320F2837xS的ADC同步操作特别是多触发源配置的细节、实现方法、注意事项以及那些手册里不会明说但实际调试中一定会遇到的“坑”。无论你是正在评估F2837xS用于新项目还是正在调试现有的多ADC采样电路相信这些内容都能给你带来直接的帮助。2. ADC同步操作的基本原理与核心约束在深入多触发源配置之前我们必须先夯实基础彻底理解F2837xS ADC实现同步操作的根本原理和硬性约束。这就像盖房子要先打地基地基不稳后面所有精巧的设计都可能崩塌。2.1 什么是真正的“同步”在F2837xS的语境下ADC的同步操作有非常明确的定义它指的是两个或更多ADC模块的转换阶段Conversion Phase在时间上精确对齐。一个完整的ADC采样周期包含两个主要阶段采样/保持SH阶段和转换阶段。同步关注的是转换阶段的起止时刻对齐。为什么是转换阶段而不是采样阶段因为采样阶段由ACQPS控制的时长是可以独立配置的不同通道可能因为信号源阻抗不同而需要不同的采样时间。但只要转换阶段在时间上对齐即使采样窗口开始和结束的时间点不同我们仍然认为多个ADC在“同步”工作因为核心的模数转换过程是同时进行的。这种设计给予了系统更大的灵活性。2.2 实现同步的黄金法则根据技术手册要实现两个ADC模块例如ADCA和ADCB的同步操作必须满足以下两个核心条件之一条件A针对同一组SOC例如SOC0所有ADC模块中该SOC的配置必须满足触发源TRIGSEL相同采样窗口持续时间ACQPS相同转换分辨率12位或16位模式相同条件B针对使用不同触发源的SOC组只要每个ADC模块内由同一触发源触发的所有SOC都拥有相同的ACQPS设置那么即使不同ADC模块的SOC由不同的触发源触发只要这些触发事件在时间上满足一定关系整体上依然可以保持同步。这是实现多触发源同步操作的理论基础。简单来说“同步”是以“触发事件”为单元来组织的。同一个触发信号如ePWM1的SOCA所启动的一系列SOC转换在各个ADC之间必须保持配置一致主要是ACQPS才能保证这些由同一事件触发的转换是同步的。2.3 同步的“敌人”什么会导致异步理解了同步的条件也就知道了什么会破坏同步。常见的导致异步操作的情况包括软件强制触发Software Force手册明确警告无法通过软件同时触发所有ADC。即使你写循环挨个触发微小的指令执行时间差也会导致启动时刻不同从而引发异步。这是绝对要避免在需要严格同步的场景中使用的方法。转换分辨率不同12位模式和16位模式的转换时间转换阶段持续时间是不同的。如果一个ADC工作在12位模式另一个在16位模式即使同时触发它们的转换结束时间也会不同从而破坏后续SOC的同步序列。SOC数量不均且触发溢出当两个ADC模块配置的SOC数量不同例如ADCA有3个SOCADCB只有2个并且使用同一个周期性触发源时如果触发周期过快在ADC模块尚未完成全部SOC转换时就来了下一个触发就会导致两个模块的SOC序列错位进入异步状态。这在电机控制中配置不同采样率的信号时尤其需要注意。3. 多触发源同步配置的实战详解手册中“Synchronous Operation with Multiple Trigger Sources”一节给出了一个经典的例子我们来逐行解析并补充实际工程中需要的上下文和配置细节。3.1 示例场景还原与代码解读假设我们有一个电机控制应用需要采集两路电流用于Clark变换要求严格同步由ePWM3的SOCB事件触发与PWM中心点对齐。一路直流母线电压采样率可以低一些由CPU Timer1定时触发。我们希望ADCA和ADCB同步工作。配置如下// 配置 SOC0用于同步采样电流A相 (ADCA) 和电流B相 (ADCB) // 使用同一个触发源 ePWM3_SOCB (TRIGSEL 10)且ACQPS相同 AdcaRegs.ADCSOC0CTL.bit.CHSEL 4; // ADCA SOC0 采样 ADCINA4 (假设接A相电流) AdcaRegs.ADCSOC0CTL.bit.ACQPS 19; // 采样窗口 (191)个 SYSCLK周期 20个周期 AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 触发源: ePWM3 SOCB AdcbRegs.ADCSOC0CTL.bit.CHSEL 0; // ADCB SOC0 采样 ADCINB0 (假设接B相电流) AdcbRegs.ADCSOC0CTL.bit.ACQPS 19; // 必须与ADCA的SOC0 ACQPS相同 AdcbRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 必须与ADCA的SOC0 TRIGSEL相同 // 配置 SOC1用于同步采样另一组信号例如预留或另一套传感器 // 同样使用 ePWM3_SOCB 触发但ACQPS可以与前一组SOC不同 AdcaRegs.ADCSOC1CTL.bit.CHSEL 4; // ADCA SOC1 采样 ADCINA4 (可能是同一通道的过采样) AdcaRegs.ADCSOC1CTL.bit.ACQPS 30; // SOC1使用更长的采样窗口31个SYSCLK周期 AdcaRegs.ADCSOC1CTL.bit.TRIGSEL 10; // 触发源: ePWM3 SOCB (与SOC0相同) AdcbRegs.ADCSOC1CTL.bit.CHSEL 1; // ADCB SOC1 采样 ADCINB1 AdcbRegs.ADCSOC1CTL.bit.ACQPS 30; // 必须与ADCA的SOC1 ACQPS相同 AdcbRegs.ADCSOC1CTL.bit.TRIGSEL 10; // 必须与ADCA的SOC1 TRIGSEL相同 // 配置 SOC2用于异步相对于SOC0/1采样母线电压 // 使用不同的触发源 CPU Timer1 (TRIGSEL 2) AdcaRegs.ADCSOC2CTL.bit.CHSEL 0; // ADCA SOC2 采样 ADCINA0 (母线电压) AdcaRegs.ADCSOC2CTL.bit.ACQPS 19; // 采样窗口20个周期 AdcaRegs.ADCSOC2CTL.bit.TRIGSEL 2; // 触发源: CPU Timer1 AdcbRegs.ADCSOC2CTL.bit.CHSEL 2; // ADCB SOC2 采样 ADCINB2 (可能是温度传感器) AdcbRegs.ADCSOC2CTL.bit.ACQPS 19; // 注意虽然触发源不同但此SOC2的ACQPS在ADCA和ADCB必须相同 AdcbRegs.ADCSOC2CTL.bit.TRIGSEL 2; // 触发源: CPU Timer1关键点解析SOC分组SOC0和SOC1被ePWM3 SOCB触发它们构成一组SOC2被CPU Timer1触发构成另一组。组内同步在同一组内即由同一触发源触发的SOC所有ADC模块的对应SOC必须具有相同的ACQPS。例如所有ADC的SOC0ePWM3触发的ACQPS都是19所有ADC的SOC1ePWM3触发的ACQPS都是30所有ADC的SOC2CPU Timer1触发的ACQPS都是19。组间独立不同组的SOC其ACQPS可以不同。例如SOC0的ACQPS19SOC1的ACQPS30这是允许的因为它们属于同一个触发源下的不同SOC序列。同步的本质当ePWM3 SOCB事件发生时ADCA和ADCB的SOC0会同时开始它们的采样保持阶段。由于它们的ACQPS相同采样窗口同时结束并同时进入转换阶段从而实现SOC0的同步转换。SOC1同理。而CPU Timer1触发时会同步启动ADCA和ADCB的SOC2。重要提示这里的“同时”是在硬件逻辑层面的精度在单个SYSCLK周期内。只要配置满足条件硬件会保证同步启动无需软件干预。3.2 时序图分析与理解手册中的图10-18清晰地展示了这个过程。即使ePWM3 SOCB和CPU Timer1的触发信号在时间上是任意关系可能同时也可能一前一后但只要触发事件到来各自组内的SOC转换在ADCA和ADCB之间都是对齐的。我们可以这样想象每个触发源都像是一个独立的“发令枪”。ePWM3 SOCB这把枪一响所有ADC的“运动员”SOC0和SOC1同时起跑开始采样并且因为训练计划ACQPS一样它们也会同时撞线完成转换。CPU Timer1是另一把发令枪它命令另一组运动员SOC2比赛。两组比赛互不干扰但各自组内的运动员步调一致。3.3 非重叠转换一种特殊的同步等效场景手册还提到了“Non-overlapping Conversions”非重叠转换。这其实是一种利用时间差来规避同步约束的巧妙方法。当你能确保两个ADC的转换周期在时间上完全错开永不重叠时即使它们的SOC配置触发源、ACQPS不同其系统表现也等效于同步操作因为不存在资源冲突和时序干扰。典型的应用场景是交错采样。例如用两个相位差180度的ePWM事件ePWM3_SOCA和ePWM3_SOCB分别触发ADCA和ADCB的SOC0。由于触发时刻天然错开半个周期你可以为两个ADC配置不同的、更适合各自信号源的ACQPS值。// ePWM3 SOCA 和 SOCB 相位差180度 AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 10; // ADCA 由 ePWM3 SOCB 触发 AdcbRegs.ADCSOC0CTL.bit.TRIGSEL 9; // ADCB 由 ePWM3 SOCA 触发 // ACQPS 可以根据需要设置不同的值这种方法不是严格意义上的硬件同步但通过精心的时序设计达到了“功能同步”的效果提高了系统设计的灵活性。但它的风险在于一旦ePWM的相位关系因故障改变就可能出现转换重叠导致数据采集混乱。因此它适用于时序关系非常稳定、可控的场景。4. 同步操作中的关键参数配置与计算要实现可靠且高精度的同步采样仅仅配置对触发源是远远不够的。采样窗口ACQPS和转换分辨率的设置同样至关重要设置不当会直接导致同步失效或采样精度下降。4.1 采样窗口ACQPS的计算与选择原则ACQPS寄存器值决定了采样保持阶段的持续时间其实际时间为(ACQPS 1) * T(SYSCLK)。这个时间必须足够长让外部信号通过驱动电路对ADC内部的采样电容Ch充电到足够的精度。手册提供了基于RC充电模型的估算公式但实践中我们更依赖以下原则和步骤绝对最小值首先必须遵守数据手册中规定的最小SH窗口时间。对于F2837xS这个值通常在几十纳秒量级。使用低于此值的ACQPS会导致采样不完整精度无法保证。驱动电路能力这是决定ACQPS的主要因素。你需要评估信号源阻抗Rs、ADC输入引脚寄生电容Cs以及PCB走线的影响。驱动运放必须有足够的带宽和输出电流能力。经验法则对于由运放直接驱动的低阻抗信号Rs很小ACQPS可以设置得较小例如14-25对应75-130ns 200MHz。对于通过电阻分压、滤波网络等高阻抗源驱动的信号则需要更长的采样窗口。计算与仿真公式估算按照手册提供的公式代入你的电路参数Rs, Cs和芯片参数Ron, Ch, Cp计算所需的τ和k最终得到最小t(SH)。然后根据系统时钟频率换算成ACQPS值。务必向上取整CEILING并减1。SPICE仿真更可靠的方法是在TI官网找到ADC的输入模型IBIS或SPICE模型在你的电路仿真软件中搭建包含驱动电路和ADC输入模型的完整链路进行瞬态仿真直接观察采样电容上的电压建立过程确保在SH窗口结束前电压稳定到所需精度如1/2 LSB以内。统一性要求对于需要同步的SOC即同一触发源下的对应SOC所有ADC的ACQPS必须设置为相同的值。因此你的ACQPS配置必须以满足所有同步通道中要求最苛刻即需要最长采样时间的那个信号为准。实操心得在电机控制板上电流采样通常通过运放和RC滤波电路接入ADC。我通常会先用公式估算一个值然后在实验室用示波器观察ADC输入引脚在采样时刻的电压建立情况。如果发现建立不完整波形有毛刺或未平缓就逐步增大ACQPS直到波形稳定。最后将这个验证过的、较大的ACQPS值统一应用到所有需要同步的电流采样SOC上。4.2 转换分辨率12位 vs 16位对同步的影响这是一个非常关键的约束点。F2837xS的ADC可以在12位或16位分辨率下工作但16位模式的转换时间比12位模式长。异步根源同步要求转换阶段的起止对齐。如果ADCA工作在12位模式ADCB工作在16位模式那么即使它们同时开始转换ADCB也会更晚结束。这会导致两个后果1) 两个ADC的忙状态标志位ADCBSY不同步2) 如果使用连续触发或链式SOC后续SOC的启动时序会完全错乱。如何实现不同分辨率的“同步”采样手册给出了一个“变通”方案但本质上是一种分时复用的策略将所有ADC设置为同一种分辨率比如12位进行一次同步触发采样。等待所有转换完成。通过软件将所有ADC切换到另一种分辨率比如16位。注意不能使用软件强制触发来启动转换。使用另一个硬件触发源如另一个ePWM事件或定时器再次触发进行第二次同步采样。这样在每次触发事件发生时所有ADC的分辨率是相同的因此转换阶段是同步的。通过两次触发你获得了两种分辨率下的同步采样数据尽管它们在时间上略有间隔。这种方法适用于对绝对同步性要求不是极端严格但又需要不同分辨率采样的场景。例如先用12位模式高速同步采样电流再用16位模式高度采样电压。4.3 触发源TRIGSEL的选择与配置触发源的选择决定了采样发生的时刻对于同步控制至关重要。ePWM模块这是最常用、最精确的触发源。ePWM的SOCA/SOCB事件可以与PWM波形精确绑定例如在计数器的零值、周期值或比较值匹配时产生非常适合电机控制中的中心对齐或边沿对齐采样以消除PWM开关噪声。配置步骤配置ePWM模块的时基、计数模式。配置ePWM的SOCStart-of-Conversion子模块选择产生SOC事件的触发条件如CTR0, CTRPRD, CTRCMPA等。使能SOCA或SOCB信号输出到ADC。优势硬件自动生成时序精确与PWM载波同步抖动极小。CPU Timer可以作为周期性采样触发源灵活性高但精度和实时性略低于ePWM。适合对采样时刻要求不严格的后台数据采集。ADCINTADC中断可以将一个ADC的转换完成中断作为另一个ADC的触发源实现链式或顺序采样。但需注意必须将ADCINTSOCSEL1/2寄存器在所有ADC上配置为相同值且不能使用软件触发来启动链。外部引脚/X-BAR可以通过GPIO或输入X-BAR引入外部事件作为触发源适用于需要与外部系统同步的场景。注意事项绝对避免使用软件强制触发ADC_startConversion()来启动需要同步的转换序列。如前所述软件无法保证同时性。如果需要软件启动同步一个替代方案是配置一个GPIO通过X-BAR连接到ADC触发源在软件中同时置位该GPIO通过写同一个GPIO数据寄存器利用硬件X-BAR来产生近乎同步的硬件触发信号。5. 同步采样Simultaneous Sampling的终极实现“同步操作”保证了多个ADC的转换阶段对齐而“同步采样”则是一个更强的目标让多个ADC的采样保持SH阶段也在同一时刻开始和结束从而捕获完全同一瞬间的多路信号。这对于需要瞬时功率计算、空间矢量合成的应用如三相电机相电流采样是必需的。F2837xS的每个ADC模块内部并没有独立的双S/H电路但它通过一个简单而有效的方法实现了同步采样将所有需要同步采样的ADC SOC配置为使用完全相同的触发源和相同的ACQPS。5.1 实现步骤假设我们需要同步采样四路信号ADCINA3, ADCINB5, ADCINC5, ADCIND2使用ePWM3_SOCB作为触发源。// 配置所有四个ADC的SOC0使用相同的触发源(ePWM3 SOCB)和相同的ACQPS AdcaRegs.ADCSOC0CTL.bit.CHSEL 3; // ADCA SOC0 - ADCINA3 AdcaRegs.ADCSOC0CTL.bit.ACQPS 19; // 20 SYSCLK cycles AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 10; // ePWM3 SOCB AdcbRegs.ADCSOC0CTL.bit.CHSEL 5; // ADCB SOC0 - ADCINB5 AdcbRegs.ADCSOC0CTL.bit.ACQPS 19; // 必须相同 AdcbRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 必须相同 AdccRegs.ADCSOC0CTL.bit.CHSEL 5; // ADCC SOC0 - ADCINC5 AdccRegs.ADCSOC0CTL.bit.ACQPS 19; // 必须相同 AdccRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 必须相同 AdcdRegs.ADCSOC0CTL.bit.CHSEL 2; // ADCD SOC0 - ADCIND2 AdcdRegs.ADCSOC0CTL.bit.ACQPS 19; // 必须相同 AdcdRegs.ADCSOC0CTL.bit.TRIGSEL 10; // 必须相同当ePWM3_SOCB触发事件到来时四个ADC的SOC0会同时开始采样、同时结束采样、同时开始转换。所有结果将分别存储在各自ADC的ADCRESULT0寄存器中。5.2 关键前提与陷阱ADC必须处于空闲状态这是手册强调但容易被忽略的一点。同步采样的前提是触发事件到来时所有涉及的ADC模块都必须处于空闲非忙碌状态。如果某个ADC还在进行上一次转换那么它无法响应新的触发同步就会失败。解决方案确保你的触发周期例如ePWM周期大于最坏情况下所有SOC转换完成所需的总时间。对于单个SOC总时间 ≈ (ACQPS1 转换时间) * T(SYSCLK)。对于多个SOC的序列需要计算整个序列的完成时间。结果读取虽然采样和转换是同步的但CPU读取结果寄存器是顺序操作。如果你需要对这些同步采样的数据进行联合运算如克拉克变换建议在ADC转换完成中断ADCINT1服务程序中一次性连续读取所有ADC的结果寄存器以减少读取操作间的时间差。通道间偏移校准即使实现了完美的硬件同步采样不同ADC通道之间仍可能存在增益和偏移误差。对于需要高精度比例关系的应用如三相电流必须在软件中进行校准。通常的做法是在系统启动时施加零电流或已知电压采集各通道数据计算偏移量在运行过程中定期或在特定条件下进行在线校准。6. 常见问题排查与调试技巧实录理论配置看起来清晰但实际调试中总会遇到各种问题。下面是我在项目中总结的一些常见故障现象和排查思路。6.1 问题现象同步采样数据存在固定相位差现象描述在电机控制中同步采样的两相电流本该相位差120度但计算出的角度总有一个固定的偏移。排查思路检查硬件连接首先用示波器同时测量两路电流传感器的输出以及ADC输入引脚确认模拟信号本身是同步的且没有因为PCB走线长度不同导致信号延迟。验证触发配置确认ADCA和ADCB的SOC是否配置了完全相同的TRIGSEL值。一个常见的低级错误是拼写错误例如AdcaRegs.ADCSOC0CTL.bit.TRIGSEL 10;而AdcbRegs.ADCSOC0CTL.bit.TRIGSEL 9;。检查ACQPS确认需要同步的SOC的ACQPS值是否完全相同。即使TRIGSEL相同ACQPS不同也会导致采样窗口结束时间不同虽然转换阶段可能对齐但采样时刻已有偏差。检查ePWM配置确认用于触发的ePWM模块的SOC信号是否真正使能并输出。检查ePWM的时基周期和触发点设置确保它按预期产生脉冲。使用调试器检查寄存器在调试模式下暂停CPU直接查看ADCSOCxCTL寄存器的值确认配置已正确写入。6.2 问题现象部分ADC通道数据偶尔丢失或错乱现象描述系统大部分时间正常但偶尔会发现某个ADC通道的数据没有更新或者数据寄存器里是旧值。排查思路触发溢出Trigger Overflow这是SOC数量不均等时最容易出现的问题。如果ADCA配置了3个SOCADCB配置了2个SOC使用同一个ePWM快速触发。当ePWM的触发周期小于ADCA完成3个转换所需的时间时ADCA还在处理SOC2下一个触发已经到来。此时ADCB已经空闲会立即启动它的SOC0而ADCA则要等当前的SOC2完成后再从SOC0开始。两者序列完全错开数据对应关系混乱。解决方法确保触发周期T_trigger max(T_conversion_total_A, T_conversion_total_B, ...)。总转换时间需要根据SOC数量、ACQPS和分辨率计算。中断冲突或优先级如果使用了ADC转换完成中断来读取数据并且中断服务程序ISR执行时间过长可能会错过下一次中断导致数据未被及时读取而被覆盖。或者更高优先级的中断打断了ADC ISR。解决方法优化ISR代码只做最必要的操作如读取数据到缓冲区、设置标志位。复杂的处理放到主循环中。合理设置中断优先级。内存访问冲突在双核F2837xS上如果两个CPU核都尝试访问同一个ADC的结果寄存器虽然硬件允许无冲突读取但软件逻辑可能因此混乱。确保每个ADC模块的数据由固定的CPU核或DMA来处理。6.3 问题现象采样值噪声大或精度不达标现象描述同步采样的数据波动大信噪比低尤其在信号变化快时更明显。排查思路ACQPS设置过小这是最常见的原因。采样窗口时间不足导致采样电容未充分充电到稳定值。按照第4.1节的方法重新计算并增大ACQPS值。模拟前端驱动能力不足检查驱动ADC输入的运放。其压摆率Slew Rate和带宽是否足够输出阻抗是否足够低在采样瞬间运放需要为ADC的采样电容提供瞬态大电流。可以在运放输出和ADC输入之间串联一个小的电阻如10-100欧姆并并联一个到地的电容如几十pF组成一个小的RC滤波有助于减少反射和振铃但需要重新评估建立时间。电源和地噪声ADC的模拟电源VDDA和参考电压VREFHI是否干净使用示波器检查这些引脚上的噪声。确保使用了足够的去耦电容通常推荐一个10uF钽电容并联一个0.1uF陶瓷电容尽可能靠近芯片引脚。数字噪声耦合高速的数字信号特别是PWM输出会通过电源或地平面耦合到模拟部分。确保PCB布局良好模拟地和数字地单点连接模拟电源使用磁珠或电感隔离。6.4 调试技巧与工具使用利用CCS的寄存器查看和图形化工具Code Composer Studio (CCS)可以实时显示外设寄存器的值。你可以单步执行代码观察配置是否正确写入。其图形化工具Graph可以直观地绘制出ADC结果缓冲区的数据便于观察波形和噪声。使用GPIO翻转进行时序测量这是一个非常实用的底层调试方法。在ADC转换开始中断入口和结束中断出口时用软件翻转一个空闲的GPIO引脚然后用示波器观察这个引脚的电平变化。你可以测量出从ePWM触发事件到ADC中断响应的延迟。ADC中断服务程序的执行时间。多个ADC中断是否真的同时发生对于同步采样它们的中断标志位应该几乎同时置位。检查ADC状态寄存器ADCINTFLG中断标志、ADCBSY忙状态等寄存器能直接反映ADC的工作状态。在调试时可以在主循环中打印或观察这些寄存器的值判断转换是否正常启动和完成。从官方例程开始TI的C2000Ware提供了丰富的ADC示例如adc_ex10_multiple_soc_epwm.c。在理解本文原理的基础上从一个能正常工作的例程出发逐步修改成你自己的配置是最高效、最稳妥的方式。