You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32 DFSDM数据分辨率配置及右移功能技术咨询

STM32 L476RG DFSDM配置问题:PDM转PCM数据异常

硬件与项目背景

使用Nucleo-L476RG开发板 + STM32CubeIDE开发,外接MEMS麦克风(AN-000048),计划以立体声模式(仅启用单通道)通过DFSDM模块将麦克风输出的PDM数据转换为PCM格式。

当前DFSDM配置

  • 麦克风时钟:系统时钟(80MHz)经125分频后输出640KHz信号
  • 通道配置:通道0,PDM/SPI输入模式,内部时钟驱动
  • DMA配置:外设到内存方向,字(32位)数据宽度,循环传输模式
  • 滤波器0配置:绑定通道0常规数据注入,连续转换模式,启用DMA与快速模式;采用Sinc3滤波器,Fosr=16、Iosr=1;根据RM0351手册表159,理论输出范围应为±4096(12位数据+1位符号位)
  • 采样频率:按奈奎斯特定理,理论最大采样频率为20KHz

异常现象

实际读取的缓冲区数据不符合预期:无负值,数值集中在30-32k区间(对应15位无符号/16位有符号范围)。已知DFSDM最高支持31位分辨率,输出数据最高可达24位,猜测右移选项用于分辨率超过24位的场景,但不确定具体逻辑;即使丢弃8位LSB保留24位数据,仍无法得到预期的13位有效分辨率。

咨询问题

  1. 如何正确设置DFSDM的数据分辨率?
  2. DFSDM的右移功能具体作用是什么?
  3. 正常配置下,缓冲区应该输出怎样的数据?

相关代码

#define BUFFER_SIZE 1024    // Always FFT_SAMPLES*2
#define FFT_SAMPLES 512 // Always BUFFER_SIZE/2

DFSDM_Filter_HandleTypeDef hdfsdm1_filter0;
DFSDM_Channel_HandleTypeDef hdfsdm1_channel0;
DMA_HandleTypeDef hdma_dfsdm1_flt0;

UART_HandleTypeDef huart2;

int32_t Buff[BUFFER_SIZE] = {0};
float FFT_In[BUFFER_SIZE] = {0};
// More declarations but not necessary for the doubt
…

int main(void)
{

// STM32Cube Inits 

  HAL_Delay(1000);

  HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, Buff, BUFFER_SIZE);

// Code to prepare FFT

  while(1){


      if(!flag){

        int i, j = 0;

        for(i = 0; i < BUFFER_SIZE; i++){
            FFT_In[i] = Buff[i];
        }


        // FFT and UART code


        HAL_DFSDM_FilterRegularStart_DMA(&hdfsdm1_filter0, Buff, BUFFER_SIZE);

        flag = true;
      }

    }

}

…

// Called when the buffer is completely full
void HAL_DFSDM_FilterRegConvCpltCallback(DFSDM_Filter_HandleTypeDef *hdfsdm_filter)
{
    buffer_full = true;
    HAL_DFSDM_FilterRegularStop_DMA(hdfsdm_filter);
    flag = false;

}

问题分析与解答

1. DFSDM数据分辨率设置

DFSDM的输出有效位数由滤波器参数和数据对齐/移位配置共同决定:

  • 依据RM0351手册,Sinc3滤波器在Fosr=16、Iosr=1时,有效输出为13位(12位数据+1位符号位),对应范围±4096。
  • 在STM32CubeIDE的DFSDM滤波器配置中:
    • 选择右对齐:滤波器输出的有效位会放在结果的最低位,高位自动符号扩展(有符号模式),能直接匹配理论输出范围;
    • 若误选左对齐,有效位会被移至32位存储单元的高位,导致数值被放大,出现你看到的30-32k区间值;
    • 同时需确保通道配置中Input type设为Signed(有符号),否则符号位会被当作数据位处理,导致无负值输出。

2. 右移功能的作用

右移功能核心作用有两点:

  • 对齐数据宽度:当滤波器有效输出位数小于存储宽度(比如用32位缓冲区存储13位有效数据),右移可将有效位调整到合适位置,方便后续处理;
  • 滤除低位噪声:对于高分辨率输出(超过24位),右移可丢弃低位无效噪声,同时将有效位对齐到标准数据宽度(如16位、24位);
  • 注意:右移操作在符号扩展之后执行,需根据有效输出位数计算移位值——比如你当前场景有效位13位,若要将数据对齐到16位,右移位数应为32 - 16 = 16?不,正确逻辑是:若希望13位有效数据占满16位范围,右移位数应为16 - 13 = 3,但实际建议先设为0验证基础输出,再按需调整。

3. 正常缓冲区输出数据

按你的配置,正常情况下缓冲区应输出符号扩展后的32位有符号数,有效范围为**-4096到+4095**:

  • 对应十六进制:+4095为0x00000FFF,-4096为0xFFFFF000;
  • 若设置了右移,数据会被移位后符号扩展,比如右移19位,+4095会变为0x00000001,-4096会变为0xFFFFFFFF,需根据后续处理需求选择是否启用。

修复建议

  1. 检查通道配置:将Input type设为Signed,确保符号位被正确识别;
  2. 调整滤波器配置:设置Data alignment为Right aligned,Output data shift设为0,验证基础输出是否符合±4096范围;
  3. 确认DMA配置:保持数据宽度为Word(32位),与int32_t缓冲区类型匹配;
  4. 检查硬件连接:确保麦克风CLK、DATA引脚正确连接到DFSDM通道0的对应引脚。

内容的提问来源于stack exchange,提问作者paalma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 15:27:50