你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F407 ADC Dual regular simultaneous only 模式下最高采样率仅 96 kHz,960 kHz 无法工作,求助!

[复制链接]
BOEING777ER 提问时间:2025-5-4 11:56 / 未解决

一、平台及配置

  • MCU 型号 :STM32F407VG (Cortex‑M4)
  • ADC :ADC1 + ADC2,Dual regular simultaneous only 模式
  • 触发源 :TIM2 TRGO 外部触发
  • ADC 时钟 :PCLK2=96 MHz,ADC prescaler=DIV2 → f<sub>ADC</sub>=48 MHz
  • 采样时间 :15 ADC 时钟周期(最小)
  • 分辨率 :12 位
  • DMA :双通道交替存储 Regular 转换结果

二、理论计算

  • ADC 时钟

    fADC=PCLK2prescaler=96 MHz2=48 MHzf_{\rm ADC} = \dfrac{\rm PCLK2}{\rm prescaler} = \dfrac{96\,\text{MHz}}{2} = 48\,\text{MHz}f**ADC****=prescalerPCLK2****=296MHz****=48MHz**

  • 转换周期

    最短采样时间设为 15 ADC 周期,加上 12.5 周期的转换时间,总共

    Tconv=15+12.548 MHz≈0.571 μs T_{\rm conv} = \frac{15 + 12.5}{48\,\text{MHz}} \approx 0.571\ \mu\text{s}T**conv****=48MHz15+12.5****0.571 μs**

  • 理论最高采样率

    fsamp=1Tconv≈10.571 μs≈1.745 MSPS(每通道) f{\rm samp} = \frac{1}{T{\rm conv}} \approx \frac{1}{0.571\,\mu\text{s}} \approx 1.745\ \text{MSPS(每通道)}f**samp****=Tconv****1****0.571μs1****1.745 MSPS(每通道)**

Dual regular simultaneous only 模式下,ADC1+ADC2 同步启动,虽然同时采样,但各自的吞吐量仍与单 ADC 相同,即每路 ≈1.745 MSPS。


三、实测现象

  • 触发频率 ≤ 96 kHz

    使用 TIM2 TRGO≤96 kHz 时,ADC1+ADC2 在 Dual regular simultaneous only 模式下可稳定响应,每路采样率≈96 kHz,DMA 半/全传输中断按期望触发,数据正常。

  • 触发频率 = 960 kHz

    尽管示波器确认 TIM2 TRGO 输出仍为 960 kHz,ADC 接收不到触发信号,DMA 不产生中断,中断回调不再执行,采样彻底失效。


备注 :实测最高只能到 ≈96 kHz,而非理论的 ≈1.7 MSPS。可能原因包括:采样时间配置未真正生效(仍在用 480 周期)、HAL/DMA 调用了额外开销、ADC 启动同步仲裁逻辑等。

四、已排查项

  1. CubeMX/HAL 配置确认:Dual regular simultaneous only、采样时间 15、ADC prescaler DIV2;
  2. TIM2 已配置 Master Mode = Update → TRGO,每周期触发一次 ADC;
  3. DMA 流/通道、FIFO、半/全中断配置正确,无死锁或缓存溢出;
  4. 关掉其他外设、提高 DMA 优先级,均无改善;
  5. 软件触发模式下,理论速率下限仍远低于 960 kHz。

五、求助方向

  1. Dual regular simultaneous only 模式 在硬件层面是否有隐藏的同步或仲裁开销?

  2. 除了采样时间和 f<sub>ADC</sub>,是否还有其他寄存器设置(如 ADC_CCR、中断/模拟看门狗)影响高速触发响应?

  3. TIMx TRGO 在高触发频率下是否存在精度或同步瓶颈?

  4. 若要接近 1 MSPS 级别,有哪些最佳实践或寄存器必须开启/关闭?

  5. 有没有前辈实测能在该模式下超 96 kHz 的经验?

  6. void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef *hadc)
    {
        if(hadc->Instance == ADC1)  // 以 ADC1 作为主 ADC(多模式中 ADC1 和 ADC2 同步)
        {
            // print_log("half\n");
            // //打印GetTick
            // print_log("GetTick: %d\n", HAL_GetTick());
            // 处理 adcBuffer 前半部分的数据:下标 0 到 ADC_BUFFER_SIZE/2 - 1
            processADCData(&adcBuffer[0], ADC_BUFFER_SIZE/2);
        }
    }
    
    void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
    {
        if(hadc->Instance == ADC1)
        {
            // print_log("full\n");
            // //打印GetTick
            // print_log("GetTick: %d\n", HAL_GetTick());
            // 处理 adcBuffer 后半部分的数据:下标 ADC_BUFFER_SIZE/2 到 ADC_BUFFER_SIZE - 1
            processADCData(&adcBuffer[ADC_BUFFER_SIZE/2], ADC_BUFFER_SIZE/2);
        }
    }
    
    void processADCData(uint32_t *buffer, uint32_t length)
    {
        // 例如每 40 个数据为一组(根据你的配置,每个通道40个样本)
        uint32_t groupSize = 4;  
        uint32_t numGroups = length / groupSize;
    
        for(uint32_t i = 0; i < numGroups; i++)
        {
            uint32_t startIndex = i * groupSize;
            // 假设每组中丢弃前1个,处理后3个有效样本
            uint32_t validSamples = 3;
            int32_t sumDiff = 0;
    
            for(uint32_t j = 1; j < 1 + validSamples; j++)
            {
                // 对于多模式 ADC,低16位是 ADC1 的数据,高16位是 ADC2 的数据
                uint16_t adc1_value = buffer[startIndex + j] & 0xFFFF;
                uint16_t adc2_value = (buffer[startIndex + j] >> 16) & 0xFFFF;
                int16_t diff = (int16_t)adc1_value - (int16_t)adc2_value;
                sumDiff += diff;
                // if(j == 39 && i < 3)
                // {
                //     print_log("ADC1: %d, ADC2: %d, Diff: %d\n", adc1_value, adc2_value, diff);
                // }
            }
            // 此处 sumDiff 为该组采集数据的累加结果,可根据需要存储或后续处理
            //processChannelResult(i, sumDiff);
            //发送给BUF_NUM_S0+i
            float sumDiff_f = (float)sumDiff;
         if(i < 16)
               sendDatatoBuf(BUF_NUM_S0+ i , (uint8_t*)&sumDiff_f, sizeof(sumDiff_f));
            // 例如打印结果
    //       if(i < 3)
             // print_log("Group %d: ADC1-ADC2 SumDiff = %d\n", i, sumDiff);
        }
    }
7.
8.
9.
收藏 评论0 发布时间:2025-5-4 11:56

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版