当前位置: 首页 > web >正文

PDM协议---音频数据接收

PDM协议基础

什么是PDM?
  • PDM(Pulse Density Modulation脉冲密度调制 是一种通过脉冲密度表示模拟信号幅度的数字调制方式。

  • 核心原理

    • 麦克风将模拟信号(声音)转换为 单比特数据流,每个时钟周期输出1位(0或1)。

    • 数据流中 1的密度 反映输入信号的幅度(例如:高密度1 = 高电压,低密度1 = 低电压)。

PDM vs PCM 
特性PDMPCM(脉冲编码调制)
数据形式单比特流(1位/时钟周期)多比特样本(如16位/样本)
转换方式直接输出密度调制信号需采样、量化、编码
应用场景数字麦克风、低功耗设备音频存储、高保真音频处理
PDM数据格式

时钟与数据关系

时钟与数据关系
  • PDM数据流 由 时钟(CLK) 和 数据(DATA) 信号组成:

    • CLK:主控生成的方波时钟(如2 MHz)。

    • DATA:在每个时钟周期输出1位(0或1),密度反映信号幅度。

  • (2) ASCII时序图
    CLK  : _|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_|‾|_  (2 MHz方波)
    DATA : 0 1 0 1 1 1 0 1 1 0 1 1 1 1 0 1  (示例数据流)
    采样点: ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑  (在CLK上升沿采样DATA)
  • 上升沿采样:通常在时钟上升沿读取数据位。

  • 数据密度:在固定时间段内,统计1的数量(例如:8个时钟周期内有5个1 → 表示高电平)

PDM麦克风硬件连接

典型电路
PDM麦克风引脚物奇7036连接说明
VDD3.3V/1.8V电源(需电平匹配)
GNDGND共地
CLKGPIO_PDM_CLK主控输出的时钟信号
DATAGPIO_PDM_DATA麦克风输出的数据流
注意事项
  • 时钟频率:常见1–3.2 MHz(需参考麦克风规格书)。

  • 电平匹配:确保麦克风与主控的电压域一致(如1.8V或3.3V)。

  • 去耦电容:在VDD和GND之间添加0.1μF电容,减少电源噪声。

 上手Demo(基于物奇7036)

目标:配置PDM接口,采集数据并转换为PCM格式。
(1) 硬件初始化
#include "wq7036_pdm.h"  // 物奇7036的PDM驱动头文件// 定义PDM缓冲区
#define PDM_BUFFER_SIZE  256
uint16_t pdm_buffer[PDM_BUFFER_SIZE];
int16_t pcm_buffer[PDM_BUFFER_SIZE];  // 转换后的PCM数据void pdm_init() {// 1. 使能PDM外设时钟CLK_EnablePDM(true);// 2. 配置GPIO复用为PDM功能GPIO_SetFunc(GPIO_PDM_CLK, GPIO_FUNC_PDM_CLK);GPIO_SetFunc(GPIO_PDM_DATA, GPIO_FUNC_PDM_DATA);// 3. 配置PDM控制器PDM_Config_t pdm_cfg = {.mode = PDM_MASTER,           // 主模式(输出时钟).clk_freq = 2000000,          // 2 MHz时钟.sample_rate = 16000,         // 16 kHz采样率.data_width = 16,             // 16位数据.osr = 64,                    // 过采样率(OSR=64).data_edge = PDM_RISING_EDGE  // 上升沿采样};PDM_Init(&pdm_cfg);// 4. 配置DMA传输PDM_SetupDMA(pdm_buffer, PDM_BUFFER_SIZE);
}
(2) PDM转PCM函数
// 简易PDM转PCM(需优化为高效实现)
void pdm_to_pcm(uint16_t *pdm, int16_t *pcm, uint32_t len) {for (int i = 0; i < len; i++) {int sum = 0;// 统计每个OSR周期内的1的数量for (int j = 0; j < 64; j++) {  // OSR=64sum += (pdm[i] >> j) & 0x1;}// 转换为有符号16位PCM(范围:-32768 ~ +32767)pcm[i] = (int16_t)((sum - 32) * 1024);  // 调整增益}
}
(3) 主程序
int main() {// 初始化PDMpdm_init();// 启动PDM采集PDM_Start();while (1) {// 等待DMA完成传输if (PDM_DMA_Ready()) {// 转换PDM到PCMpdm_to_pcm(pdm_buffer, pcm_buffer, PDM_BUFFER_SIZE);// 处理PCM数据(例如存储或传输)process_audio(pcm_buffer, PDM_BUFFER_SIZE);// 重启DMA传输PDM_StartDMA(pdm_buffer, PDM_BUFFER_SIZE);}}return 0;
}

4. 调试与验证

(1) 示波器检测
  • CLK信号:确认是否为2MHz方波。

  • DATA信号:发声时应有明显的脉冲密度变化。

(2) 数据打印

process_audio函数中打印PCM数据,观察是否随声音变化:

void process_audio(int16_t *pcm, uint32_t len) {for (int i = 0; i < len; i++) {printf("%d\n", pcm[i]);}
}

http://www.xdnf.cn/news/3151.html

相关文章:

  • 「动态规划」线性DP:最长上升子序列(LIS)|编辑距离 / LeetCode 300|72(C++)
  • 浅谈C# record关键字
  • CSS:选择器-基本选择器
  • linux联接服务器SSH-局域网内网穿透分享
  • VR 汽车线束培训:探索高效学习新路径​
  • 线性微分方程与非线性微分方程
  • 工业控制「混合架构」PK大战 —— 神经网络 + MPC vs 模糊 PID+MPC 的场景选型与实战指南
  • 数据转储(go)
  • 网络原理 - 12(HTTP/HTTPS - 3 - 响应)
  • 人工智能数学基础(六):数理统计
  • [Android]任务列表中有两个相机图标
  • 2025上海车展 | 移远通信推出自研NG-eCall QuecOpen方案,助力汽车安全新标准加速落地
  • 青少年抑郁症患者亚群结构和功能连接耦合的重构
  • 2025年“深圳杯”数学建模挑战赛B题-LED显示屏颜色转换设计与校正
  • Java从入门到精通 - Java入门
  • 极光PDF编辑器:高效编辑,轻松管理PDF文档
  • 相机的基础架构
  • TwinCAT数据类型,%MX,%MD这些特殊符号
  • 解决 RN Switch 组件在安卓端样式很丑的问题
  • MySQL 基本查询(一)
  • SNR8016语音模块详解(STM32)
  • Python中的内置函数
  • Django 自定义celery-beat调度器,查询自定义表的Cron表达式进行任务调度
  • K8S - GitOps 入门实战 - 自动发布与秒级回滚
  • 运维仙途 第1章 灵机突现探监控
  • 【文献速递】邻位连接技术(PLA)在细胞器相互作用中的应用
  • 汽车免拆诊断案例 | 2015款奔驰C200L车发动机起动延迟
  • AI预测3D新模型百十个定位预测+胆码预测+去和尾2025年4月30日第68弹
  • springboot集成Lucene详细使用
  • NVIDIA DRIVE AGX平台:引领智能驾驶安全新时代