尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

STM32 双 ADC 同步 + 注入通道:同步采样看趋势,过流插队保命

STM32 双 ADC 同步 + 注入通道:同步采样看趋势,过流插队保命 我前阵子做一块伺服驱动板FOC 算法需要同步采三相电流加母线电压。前期直接用双 ADC 同步模式电压和电流同刻采出来算出来的转矩稳得一批。但板子打回来做安规测试时出了岔子堵转过流那一下MCU 还没来得及反应驱动芯片先报故障把桥臂锁了——我的过流保护是靠主循环里轮询规则通道数据做的等轮询到那一帧过流早过去了几十毫秒保护形同虚设。复盘才想明白双 ADC 同步模式管的是看得准但管不了来得急。规则通道在后台稳稳扫波形等它扫完一圈你才读到电流这个延迟对正常控制够用对过流保护就太慢了。得把注入通道搬进来——给过流信号开一条硬件 VIP 通道规则同步采样正在跑过流一来立刻插队采一下保护点采完自动回去接着同步采样。两个玩法拧一块才是完整的同步采集 紧急保护架构。一、两套采集为什么要同时存在单看双 ADC 同步ADC1 主机 ADC2 从机同一个触发沿同时采样结果打包进 32 位 CDRDMA 以 Word 宽度搬走。它解决的是多路零相位差适合连续、等间隔、要算相位的场景——FOC 的三相电流、功率计的 U/I、差分 IQ 都靠它。单看注入通道规则组忙着连续采注入组平时不动一旦注入触发来了硬件暂停当前规则转换、插队采一下紧急信号存进自己的 JDRx完事自动回到规则组。它解决的是随时插一脚适合过流、过压、按键这些优先级高的采样。把两个合起来分工就清楚了规则组双 ADC 同步负责看趋势——连续、同步、算功率/转矩数据走 CDR 和 DMA。注入组同步注入负责保命——过流/过压瞬间插队采保护点数据走 JDRx进中断直接关 PWM。一个 ADC 模块ADC1ADC2 这个 common pair同时干这两件事互不污染规则数据在 CDR注入数据在 JDRx。二、CubeMX 怎么配这次配置步骤多一点因为两个 ADC 各要配规则 注入两组外加公共区选对双模式。1. ADCs_Common_Settings公共区Mode下拉选Combined Regular Simultaneous Injected SimultaneousADC_DUALMODE_SIMUL_INJE。★ 这是本篇最关键的配置。如果只选规则同步Regular Simultaneous注入变成普通的单 ADC 注入两个 ADC 的注入通道各采各的触发紧急保护采样之间也有相位差——保护这种事差几微秒可能就烧了。DMA Access Mode选DMA access mode 1规则同步走 CDR→DMA。Delay between 2 sampling phases默认 0。2. ADC1主机规则组通道勾上同步采样要用的几路比如 IN0母线电压、IN1相电流 U。External Trigger Conversion SourceTIM1_TRGO规则组触发Edge Rising。Continuous Disable。3. ADC1主机注入组勾Injected Conversion ModeNumber Of Conversions填注入通道数比如 1过流保护点。JEXTSEL 另一个触发源比如TIM1_TRGO2或比较器输出 / EXTI★ 别和规则组抢同一个 TIM1_TRGO。JEXTEN Rising Edge必须开注入触发没沿就不启动。注入组 Rank、采样时间独立配。NVIC 里打开 ADC 的JEOC注入转换完成中断。4. ADC2从机规则组 注入组规则组勾配对的那几路IN2相电流 V、IN3相电流 W跟着主机同步。★从机的注入组也要配勾Injected Conversion Mode同样填通道数JEXTSEL配成和主机相同的注入触发源这样注入触发一来两个 ADC 一起暂停、一起采自己的注入通道同步插队。只配主机注入、从机注入留空同步注入时从机那一路保护点采不到。5. DMA挂在 ADC1 上给 ADC1 加 DMAMode CircularData Width Word32 位。注入组不走 DMA用中断读 JDRxDMA 只服务规则组的 CDR。三、最少的代码规则组用HAL_ADCEx_MultiModeStart_DMA启动双 ADC 同步版本注入组用HAL_ADCEx_InjectedStart_IT启动——而且主机从机都要启动#defineDUAL_BUF_LEN128#defineOC_THRESH3500// 过流阈值(按实际标定)uint32_tadc_dual_buf[DUAL_BUF_LEN];// CDR 打包: 低16ADC1, 高16ADC2intmain(void){HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_DMA_Init();MX_ADC1_Init();// 主机: 规则注入都配MX_ADC2_Init();// 从机: 规则注入都配MX_TIM1_Init();HAL_TIM_Base_Start(htim1);// 规则组触发源HAL_ADCEx_MultiModeStart_DMA(hadc1,(uint32_t*)adc_dual_buf,DUAL_BUF_LEN);HAL_ADCEx_InjectedStart_IT(hadc1);// 主机注入待命HAL_ADCEx_InjectedStart_IT(hadc2);// ★ 从机注入也要启动, 否则同步注入时从机不采while(1){if(dual_ready){dual_ready0;for(inti0;iDUAL_BUF_LEN;i){uint16_tv_busadc_dual_buf[i]0xFFFF;// ADC1 低16: 母线电压uint16_tv_iu(adc_dual_buf[i]16)0xFFFF;// ADC2 高16: 相电流Ufoc_update(v_bus,v_iu);// 同步数据算FOC}}}}// 规则同步完成(主机完成整组完成)voidHAL_ADC_ConvCpltCallback(ADC_HandleTypeDef*hadc){if(hadc-InstanceADC1)dual_ready1;}// 注入同步完成 —— 过流插队到了, 进这里保命voidHAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef*hadc){if(hadc-InstanceADC1){// 只需判主机, 回调里把两路注入值都读出来uint16_toc1HAL_ADCEx_InjectedGetValue(hadc1,ADC_INJECTED_RANK_1);// 主机保护点uint16_toc2HAL_ADCEx_InjectedGetValue(hadc2,ADC_INJECTED_RANK_1);// 从机保护点(同步采)if(oc1OC_THRESH||oc2OC_THRESH){motor_emergency_stop();// 过流! 立刻封PWM, 比主循环轮询快一个数量级}}}这段在干嘛TIM1 一来触发ADC1ADC2 同步采规则组三相母线CDR→DMA 搬走给 FOC 用与此同时注入组由另一个触发源比如比较器判过流驱动一旦过流硬件暂停规则序列、两个 ADC 同步插队采保护点进中断读 JDRx 判阈值超了直接关 PWM。规则采样在后台稳稳跑过流保护靠硬件插队实时响应两边谁也不耽误。★ 注意注入回调里判hadc-Instance ADC1主机就够了但在里面把hadc1和hadc2的注入值都读出来——两个 ADC 是同步注入的各自 JDRx 里都有值。你只 Start 了主机注入却想在回调里读从机 JDR从机压根没采读出来是旧值或 0。四、真正会坑你的几个点1. Dual Mode 选成 REGSIMULT。最高频的坑也是本篇独有的。你图省事选了 Combined Regular Simultaneous结果规则同步了、注入却不同步——两个 ADC 的注入通道各等各的触发过流保护采样之间也有 skew关键时刻差几微秒就晚了。要规则 注入都同步就选SIMUL_INJE。2. 从机注入组没配 / 没启动。只在 ADC1 里勾了注入、Start 了 ADC1 注入ADC2 的注入组是空的也没 Start。同步注入触发一来从机那一路保护点根本没采你读hadc2的 JDR 永远是 0。两个 ADC 的注入组都要勾、都要HAL_ADCEx_InjectedStart_IT。3. 注入数据搅进规则 DMA 缓冲。有人看注入也有数据就想把它和规则数据拼一起搬。错。注入结果在各自 JDRx规则在 CDR/DMA两套完全独立。注入 ISR 里只读HAL_ADCEx_InjectedGetValue别去碰adc_dual_buf否则规则波形数据被你写乱。4. 注入打断规则期间 DMA 缓冲错位。同步注入时规则序列被硬件暂停CDR 的 DMA 传输也跟着停恢复后继续。这个暂停对你拼接规则缓冲基本无感DMA 只是停了一下但★ 如果你在注入 ISR 里又去读/写adc_dual_buf就可能拿到半截数据。铁律注入 ISR 只读 JDR绝不碰规则 DMA 缓冲。5. 注入触发源和规则触发源抢同一信号。规则用 TIM1_TRGO注入也配 TIM1_TRGO两个触发打架同步节奏全乱。注入换 TIM1_TRGO2、另一定时器、或比较器/EXTI别和规则组抢同一个 TRGO。6. 注入触发太频繁打断同步采样。过流信号抖干扰毛刺、触点弹跳注入一个接一个来规则同步 DMA 被反复暂停FOC 要的连续波形采不全转矩算出来跳。触发源前面加硬件滤波 / 软件去抖或只在运行态使能注入中断保护完进故障态就关掉。7. CDR 高低 16 位读反。低 16 位 ADC1主机、高 16 位 ADC2从机。16取电压和0xFFFF取电流写反三相电流和母线电压张冠李戴FOC 直接飞车。拆包顺序别反。8. 主从 ADC 都要单独校准。HAL_ADCEx_Calibration_Start(hadc1)和hadc2两个都做。只校准主机从机的偏移误差没消除同步采样两路基准不一致算出来的功率/转矩带固定偏差。9. DMA 宽度还是 Half Word。双 ADC 同步的规则 DMA 必须 Word32 位和注入无关——注入不占 DMA。你要是按单 ADC 习惯设成 Half Word每次只搬 16 位ADC2 那一路高 16 位整段丢相电流 V/W 永远 0 或乱跳。10. 想用 AUTO_INJECT 代替外部触发插队。CubeMX 里Auto Injected Conversion开了会在每个规则序列结束后自动跑注入组——这是尾巴附加不是随时插队过流来了也得等当前规则序列扫完才采保护延迟又回来了。要随时插队就别开 AUTO_INJECT靠 JEXTSEL 触发源驱动。五、完整例程骨架把启动三连和两组回调拼起来TIM1 触发双 ADC 规则同步CDR→DMA 给 FOC注入组由独立触发源驱动同步插队JDRx→中断保命主机从机都 Start。规则看趋势、注入保命一个 ADC 模块干两件事。HAL_TIM_Base_Start(htim1);HAL_ADCEx_MultiModeStart_DMA(hadc1,(uint32_t*)adc_dual_buf,DUAL_BUF_LEN);HAL_ADCEx_InjectedStart_IT(hadc1);// 主机注入HAL_ADCEx_InjectedStart_IT(hadc2);// 从机注入(同步插队)// 之后: 主循环拆包CDR算FOC; HAL_ADCEx_InjectedConvCpltCallback里读JDR保命双 ADC 同步让你看得准注入通道让你来得急——同步采样负责稳态精度和功率过流插队负责那几十微秒里的保命两套采集在一个 ADC 模块里各司其职才是工业级电机驱动该有的采集架构。适合电机 FOC同步采三相母线算转矩过流随时插队保命、数字电源同步算功率、过压过流即时保护、任何既要连续同步采样、又要紧急采样的场景。不适合只用得上其中一项的——纯同步用双 ADC 规则同步模式就够了纯过流保护用单 ADC 注入通道也够没必要把两套都开。铁律三条Dual Mode 选 SIMUL_INJE规则注入都同步主机从机的注入组都要配、都要 Start_IT规则数据走 CDR-DMA、注入数据走 JDRx-中断两套绝不混。
返回列表