[STM32F7] STM32F7xx HAL 驱动 HAL_ADC_Start_IT() 缺少 ADC2 软件触发启动分支

[复制链接]
45|6
HomeKit 发表于 2026-6-23 11:35 | 显示全部楼层 |阅读模式
STM32F7xx 系列 ADC 的 HAL 驱动存在问题:HAL_ADC_Start_IT() 函数里没有适配 ADC2 外设软件触发启动的判断分支。
对应代码从 1128 行开始:
else
{
/* if instance of handle correspond to ADC1 and no external trigger present enable software conversion of regular channels */
if((hadc->Instance == ADC1) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
{
/* Enable the selected ADC software conversion for regular group */
hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
}
/* if dual mode is selected, ADC3 works independently. */
/* check if the mode selected is not triple */
if( HAL_IS_BIT_CLR(ADC->CCR, ADC_CCR_MULTI_4) )
{
/* if instance of handle correspond to ADC3 and no external trigger present enable software conversion of regular channels */
if((hadc->Instance == ADC3) && ((hadc->Instance->CR2 & ADC_CR2_EXTEN) == RESET))
{
/* Enable the selected ADC software conversion for regular group */
hadc->Instance->CR2 |= (uint32_t)ADC_CR2_SWSTART;
}
}
我认为该函数理应加入 ADC2 的判断逻辑,但这份驱动源码中没有对 ADC2 做任何处理。

亚瑟 发表于 2026-6-23 14:57 | 显示全部楼层
HAL_ADC_Start_IT()里加个判断ADC2的分支,看CR2寄存器是否设置了软件启动位,没有就设置ADC2_CR2_SWSTART。记得检查ADC2的时钟是否开启哦。
甜心puppy 发表于 2026-6-23 16:18 | 显示全部楼层
你发现这个坑就对了,F7的HAL库确实只给ADC1和ADC3写了软件触发分支,ADC2就是被漏掉的,手动加一个判断就能跑。
七毛钱 发表于 2026-6-23 16:26 | 显示全部楼层
修改完HAL源码后,记得把编译选项里的USE_HAL_DRIVER宏定义检查一下,避免编译器用了未修改的预编译库版本。
今天会画卧蚕吗 发表于 2026-6-23 16:26 | 显示全部楼层
这个bug说白了就是ST在适配双ADC和三ADC模式时,把ADC2当成从机处理了,独立使用的场景他们压根没做case覆盖。
内政奇才 发表于 2026-6-23 16:26 | 显示全部楼层
给你个建议,直接弃用HAL_ADC_Start_IT,自己写一个start函数只干两件事:开中断再置SWSTART,避开源码所有判断逻辑。
茉璃夏 发表于 2026-6-23 16:49 | 显示全部楼层
你改了之后如果ADC2能正常工作,记得把SWSTART写操作的代码再确认一下,别跟ADC1混用同一个CR2位域,毕竟寄存器本身是一样写的。
豌豆爹 发表于 2026-6-23 17:20 | 显示全部楼层
这个bug在F7系列的1.2.x版本HAL里就已经存在,你现在用的如果是更新版驱动还没修复,ST的errata里也不提这事,全靠自己踩。
进入猫次元 发表于 2026-6-23 17:51 | 显示全部楼层
临时绕过方案:直接在你调用HAL_ADC_Start_IT之前,手动置位ADC2->CR2的SWSTART位,别依赖HAL去帮你做这个判断。
麻花油条 发表于 2026-6-23 18:20 | 显示全部楼层
注意如果ADC2配了外部触发,那本来就不该走软件启动分支,你要先确认你的配置里EXTEN确实是0,否则不是HAL的问题。
classroom 发表于 2026-6-23 18:52 | 显示全部楼层
你如果用的是ADC2的注入组而不是规则组,那SWSTART本来就无效,得走JSWSTART位,这个分支HAL压根没写,你得自己补
cr315 发表于 2026-6-23 19:22 | 显示全部楼层
多ADC同步模式下,ADC2的CR2_SWSTART位会被主ADC覆盖,如果你同时开了ADC1和ADC2,单独启ADC2软件触发是没用的。
duo点 发表于 2026-6-23 19:55 | 显示全部楼层
这种HAL层级缺失在中断回调里也会体现,如果ADC2中断开了但HAL_ADC_IRQHandler里没对应清标志,你软件触发了也进不了回调。
flycamelaaa 发表于 2026-6-23 20:26 | 显示全部楼层
建议你把ADC2的初始化配置里EXTEN设成外部触发,别依赖软件启动,这样绕开HAL这个判断分支,反而代码更通用。
jcky001 发表于 2026-6-23 20:27 | 显示全部楼层
你改完函数后注意把ADC2的DMA使能情况也检查下,软件触发跟DMA循环模式配合时,寄存器启动顺序不一样,容易多触发一次。
onlycook 发表于 2026-6-23 21:28 | 显示全部楼层
其实CubeMX生成的代码里,ADC2初始化默认就不配外部触发,但HAL_ADC_Start_IT又找不到它,这不就是官方工具和驱动之间的矛盾。
powerantone 发表于 2026-6-23 21:59 | 显示全部楼层
如果项目里用了三个ADC同时工作,只有ADC2要软件触发,那你改驱动的时候别影响到ADC1和ADC3的原有逻辑,加个独立else if最稳。
probedog 发表于 2026-6-23 22:29 | 显示全部楼层
有人试过把ADC2的句柄传给ADC1的启动函数来绕过,但这样中断回调里取到的实例指针是错的,别这么干,老老实实改驱动。
solty 发表于 2026-6-24 10:24 | 显示全部楼层
查一下你调用的HAL_ADC_Start_IT前面有没有先调用HAL_ADCEx_Calibration_Start,校准没完成时SWSTART写入会被忽略,有时候是顺序问题。
CarterERO 发表于 2026-6-24 11:04 | 显示全部楼层
HAL_ADC_Start_IT里添加ADC2的判断分支,先确认CR2寄存器的EXTEN位是0,再设置ADC2_CR2_SWSTART,小心寄存器配置冲突。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

162

主题

162

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部
0