ST意法半导体
直播中

小麦地

13年用户 1725经验值
私信 关注
[问答]

STM32F723ZET6使用ADC捕获标准正弦波并通过USB主动上报,正弦波重新拟合后存在凹陷峰怎么解决?

捕获5KHZ频率的正弦波,使用的是100khz定时器2溢出事件触发ADC采样,采样144cyc,使用DMA方式传输ADC采样数据(软件触发和连续采样都试过没有对波形产生帮助)。之后通过高速USB带内置PHY功能的模拟串口通信把数据上报。上报方式是每次adc采样存下一个点,累计达到1000个点进行一次HS上报。



上位机最好收到的波形如下:


之前通过标准的信号发生器输出1khz正弦波也会存在这样的波形,测试固定数据USB上报不存在数据丢失问题。请问是ADC采样存在数据丢失问题吗?要如何改进?还是数据上报和ADC采集有冲突?



回帖(1)

无人岛

2025-6-24 17:57:06

对于STM32F723ZET6在ADC捕获5kHz正弦波并通过USB上报时出现的凹陷峰问题,结合你的描述,这是一个典型的嵌入式系统实时数据传输问题,涉及ADC采样精度、DMA传输可靠性、实时系统优先级冲突、以及USB传输时序等多个环节。以下是系统性分析和解决步骤:




1. 根本原因定位


问题核心是周期性数据丢失或采样点错位,导致拟合波形在固定位置塌陷:



  • 采样率不足或不稳定:100kHz采样率理论可支持5kHz信号(奈奎斯特频率 > 10kHz),但实际采样率若因中断延迟等抖动,会导致部分点丢失。

  • DMA传输阻塞:DMA在搬运数据时若被高优先级中断打断,可能导致ADC新采样点覆盖未搬运的数据。

  • USB传输阻塞ADC:每次累积1000点上报的HS传输耗时较长(~1ms),期间ADC仍在采样,若DMA缓冲区设计不当,新数据会覆盖旧数据。

  • 中断冲突:TIM2触发中断、DMA中断、USB中断优先级冲突,导致采样时序混乱。




2. 关键优化措施


(1) 优化ADC与DMA配置


// 采用双缓冲DMA + 精确触发
hdma_adc.Init.Mode = DMA_CIRCULAR;        // 循环模式
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE;
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_adc.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_adc.XferCpltCallback = DMATransferComplete; // 半缓冲中断


  • 启用DMA双缓冲模式:将缓冲区分为两块(如各500点),一块用于ADC写入时另一块用于USB读取,避免覆盖。

  • 降低采样周期:144 cycles @72MHz≈2μs,100ksps需10μs间隔,确认TIM2触发周期是否精确为10μs(预分频值、计数器重载值)。


(2) USB传输优化


// 改为小包高频次传输
#define USB_PACKET_SIZE 64 // 单包64字节(32点)
uint16_t adc_buffer[2][500]; // 双缓冲,每块500点

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
  // 当半缓冲完成时触发USB传输
  USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS,
                           adc_buffer[active_buffer],
                           USB_PACKET_SIZE);
  active_buffer = !active_buffer; // 切换缓冲区
}


  • 减小单次上报点数:从1000点改为64~256点/包,缩短USB占用时间(避免堵塞DMA)。

  • 使用USB HS传输:STM32F7的USB HS理论带宽480Mbps,实际需优化端点描述符保证优先级。


(3) 中断优先级调整


确保关键时序链的优先级:


NVIC_SetPriority(TIM2_IRQn, 0);      // TIM2触发最高优先级
NVIC_SetPriority(DMA2_Stream0_IRQn, 1); // DMA传输次高
NVIC_SetPriority(OTG_HS_IRQn, 3);    // USB较低优先级


  • 禁用全局中断时间最小化:在DMA/USB关键代码段用__disable_irq()/__enable_irq()严格控制时间。


(4) 时钟与采样率验证



  • 确认TIM2时钟源:TIM2应使用APB1 Timer Clock(通常与系统同频),确认其分频系数使计数器周期=10μs。

  • 测量实际采样率:用示波器观察ADC的EOC(End of Conversion)信号,验证是否严格每10μs触发一次。




3. 硬件层面检查



  • ADC参考电压稳定性:确保VREF+无噪声干扰(并联10μF+0.1μF电容)。

  • 信号输入阻抗匹配:在ADC输入前加电压跟随器(OPAMP),避免信号源内阻影响采样保持。

  • 接地隔离:使用独立模拟地平面(AGND),与数字地(DGND)单点连接。




4. 调试与验证方法


(1) 静态数据测试


// 产生本地正弦波代替ADC输入
for(int i=0; i<1000; i++) {
  adc_buffer[i] = 2048 + 2047 * sin(2 * PI * i / 200); // 模拟5kHz信号
}


  • 若此时波形完整,则问题在ADC/DMA;若仍有凹陷,问题在USB或上位机。


(2) 逻辑分析仪抓取时序



  • 同时捕获以下信号:

    • TIM2触发脉冲(通道1)

    • ADC EOC信号(通道2)

    • DMA传输请求(通道3)

    • USB传输起始信号(通道4)



观察凹陷点是否对应DMA/USB活动导致的EOC缺失。




5. 备用方案


若仍无法解决凹陷峰:



  • 使用多ADC交替采样:启用STM32的Dual Interleaved Mode,将采样率提升至200ksps,提高冗余度。

  • 降低信号频率:测试1kHz信号观察问题是否消失(排除高频混叠影响)。

  • 改用SPI/I2S+外部ADC:如使用ADS8668(18位、1MSPS)提升抗干扰能力。




总结


凹陷峰本质是采样点丢失的周期性表现,优先优化方向为:



  1. 启用DMA双缓冲模式,隔离ADC采样与USB传输。

  2. 减小USB单包长度至≤256点,单次传输时间控制在100μs内。

  3. 提升TIM2/DMA中断优先级,确保采样时序绝对优先。

  4. 实测TIM2触发信号与EOC间隔,确认硬件级采样率稳定性。


通过上述步骤可系统性消除数据链路的堵塞点。最终调整后的系统能稳定捕获5kHz正弦波,保证波形拟合完整性。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分