[STM32H7] H723 芯片使用 ADC3 过采样时出现参数错误

[复制链接]
64|16
我的牙白 发表于 2026-3-4 22:11 | 显示全部楼层 |阅读模式

9465669a7f8c61aa35.png
我将 ADC3 配置为 16 倍过采样,但实际得到的过采样倍数却是翻倍的 ——ADC3 通道 1 测得值为 5V(实际应为 2.5V)、ADC3 通道 4 测得值为 3.3V(实际应为 1.65V)。
在初始化函数void MX_ADC3_Init(void)中,我配置的参数是:
hadc3.Init.Oversampling.Ratio = 16;
hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;
我跟踪了HAL_ADC_Init()函数的源码,发现这段逻辑:
#if defined(ADC_VER_V5_V90)
if (hadc->Instance == ADC3)
{
/* Configuration of Oversampler: */
/* - Oversampling Ratio */
/* - Right bit shift */
/* - Triggered mode */
/* - Oversampling mode (continued/resumed) */
MODIFY_REG(hadc->Instance->CFGR2,
ADC_CFGR2_OVSR |
ADC_CFGR2_OVSS |
ADC_CFGR2_TROVS |
ADC_CFGR2_ROVSM,
ADC_CFGR2_ROVSE |
hadc->Init.Oversampling.Ratio |
hadc->Init.Oversampling.RightBitShift |
hadc->Init.Oversampling.TriggeredMode |
hadc->Init.Oversampling.OversamplingStopReset
);
}
else
{
当Ratio设为 16 时,代码直接将该值写入CFGR2寄存器,最终导致实际过采样倍数变成了 32 倍。
我将Ratio手动改为0x0C后,得到了预期的采样结果。


duo点 发表于 2026-3-5 12:19 | 显示全部楼层
ADC_CFGR2_OVSR在寄存器中不是直接存储倍数,而是存储 索引值 或 编码值。
flycamelaaa 发表于 2026-3-5 12:20 | 显示全部楼层
HAL 库的 MODIFY_REG 操作可能未正确转换 Ratio 值,而是直接将其写入寄存器,导致实际配置的过采样倍数翻倍。
jcky001 发表于 2026-3-5 12:21 | 显示全部楼层
16 倍过采样对应的 OVSR 值应该是 3而不是 16。
probedog 发表于 2026-3-5 12:22 | 显示全部楼层
RightBitShift 用于右移过采样后的结果,以避免溢出。对于 16 倍过采样,通常右移 4 位,因为 2^4=16。
又见江南雨 发表于 2026-3-5 12:23 | 显示全部楼层
本帖最后由 又见江南雨 于 2026-3-5 12:25 编辑

在 MX_ADC3_Init() 中,不要直接设置 Ratio=16,而是:
c
hadc3.Init.Oversampling.Ratio = ADC_OVERSAMPLING_RATIO_16;  // 使用 HAL 定义的宏(如果存在)
// 或者手动设置为 3(如果 HAL 没有定义宏)
// hadc3.Init.Oversampling.Ratio = 3;

hadc3.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4;

如果 HAL 库没有提供 ADC_OVERSAMPLING_RATIO_16 宏,可以直接使用数值 3
spicy 发表于 2026-3-5 12:23 | 显示全部楼层
可以直接操作寄存器
公羊子丹 发表于 2026-3-5 17:56 | 显示全部楼层
你这情况大概率是STM32H723的ADC3寄存器配置有专属坑,CFGR2里的OVSR位域不是直接写数值的,我怀疑库函数对ADC3的适配没做位域转换,你可以查下手册里OVSR的位定义,看看16倍对应的实际寄存器值是不是就是0x0C。
周半梅 发表于 2026-3-6 08:03 | 显示全部楼层
哈哈,这波属于是库函数给ADC3开小灶开错了,我之前用H7的ADC2没这问题,没想到ADC3单独写了段逻辑还写崩了。你改了0x0C之后,除了采样值正常,采样速度和稳定性有没有受影响啊?
帛灿灿 发表于 2026-3-6 08:04 | 显示全部楼层
我建议你再测测不同过采样倍数的情况,比如8倍、32倍,都手动改对应的寄存器值试试,看看是不是只有16倍出问题,还是所有倍数都存在翻倍的情况,这样也能确认是不是这个寄存器写入逻辑的通用问题。
童雨竹 发表于 2026-3-6 08:06 | 显示全部楼层
你检查过HAL库的版本吗?我遇到过好几次ST的库函数小bug,都是新版本修复的,说不定这个ADC3过采样的问题在最新的HAL库里面已经改好了,你可以更个库再重新测试下,省得每次都手动改寄存器值。
万图 发表于 2026-3-6 08:08 | 显示全部楼层
其实ST的H7系列ADC外设分不同版本,ADC3大概率是和其他ADC核不一样,库函数里单独加的那段判断逻辑画蛇添足了,直接把数值写进去没做位映射,你可以把那段ADC3的专属配置代码注释掉,和其他ADC一样处理试试。
Wordsworth 发表于 2026-3-6 08:09 | 显示全部楼层
我很好奇你这情况只出现在过采样模式吗?如果关掉过采样,ADC3的普通采样模式测出来的电压值准不准?还有你用的是单次采样还是连续采样,会不会采样模式也和这个寄存器配置冲突了?
Bblythe 发表于 2026-3-6 08:10 | 显示全部楼层
这问题解决得挺巧的,手动改寄存器值能临时解决,但项目里这么用总觉得不踏实。我建议你把这个问题反馈给ST官方,或者去ST的社区看看有没有其他人遇到同款问题,说不定有更规范的解决方法。
Pulitzer 发表于 2026-3-6 08:11 | 显示全部楼层
我之前用F4的ADC过采样也遇到过数值不准的情况,不过是移位位数配错了,没想到H7的ADC3是寄存器写入的问题。你改完0x0C后,有没有测试过多通道同时采样的情况,其他通道会不会还有偏移?
Uriah 发表于 2026-3-6 08:12 | 显示全部楼层
你跟踪HAL源码的时候,有没有看那段ADC3的配置代码里,除了Ratio,移位位数和触发模式的写入是不是也有问题?虽然这次移位4位是对的,但保不齐其他参数也有隐藏的配置坑,最好一起核查下。
Clyde011 发表于 2026-3-6 08:13 | 显示全部楼层
讲真ST的库函数有时候真的让人头大,尤其是H7这种复杂芯片,外设专属逻辑特别容易出问题。你可以做个小测试,把ADC3的配置代码改成和ADC1/ADC2一样的逻辑,看看会不会恢复正常。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

134

帖子

0

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