[PSOC™] 【CY8CKIT-062S2-AI 测评】--MIC拾音

[复制链接]
224|3
dirty123 发表于 2025-11-23 11:26 | 显示全部楼层 |阅读模式
PCM, pd, ic, DM,
本帖最后由 dirty123 于 2025-11-23 11:29 编辑

        本篇实现MICMIC拾音功能。

一.硬件原理
        开发板板载两个PDM(脉冲密度调制)微型数字麦克风,在开发板背面边角侧。引脚有PDM_CLK时钟脚和PDM_DATA数字脚,硬件原理如下


        此麦克风使用到PDM (脉冲密度调制)和PCM (脉冲编码调制)。PDM信号是高速的单比特流,无法被传统的音频处理器(DSP)或软件直接识别和处理,因此需要转换为标准的PCM格式。PCM作为数字音频领域的绝对标准,几乎所有软件、硬件和文件格式(如WAV、FLAC)都直接支持PCM数据,便于进行滤波、混音、均衡器等复杂的数字信号处理。这个过程本质上是数字信号处理中的采样率转换和数据重构,核心步骤有两步:
采样率转换(抽取 - Decimation)        
目的是将极高的PDM采样率(如3.072 MHz)降低到标准PCM采样率(如48 kHz)。这个降低的比率称为“抽取因子”,例如从3.072 MHz到48 kHz的抽取因子是64:1。直接简单地丢弃样本会造成严重的信号失真,因此必须配合第二步的滤波操作。
低通滤波与噪声整形      
这是转换的核心。PDM信号中包含的大量高频量化噪声必须被滤除。转换过程通常使用一种高效的CIC(级联积分梳状)滤波器​ 来实现
。该滤波器会计算一小段时间窗口(例如64个PDM时钟周期)内“1”的密度,并将这个密度值转换成一个多比特的幅度值输出。这样,既完成了数据的转换,也将大部分高频噪声滤除了。

        PDM侧重于高效率的模数转换和传输,PCM侧重于通用的处理和兼容性。

二.工程代码准备
1.创建工程
        选择外设里音频PDM PCM Audio,如下


2.VSCode创建的工程如下


3.工程代码梳理
1.宏定义与按键事件
(1)参数阈值引脚等宏定义
  1. /*******************************************************************************
  2. * Macros
  3. ********************************************************************************/
  4. /* Define how many samples in a frame */
  5. #define FRAME_SIZE                  (1024)
  6. /* Noise threshold hysteresis */
  7. #define THRESHOLD_HYSTERESIS        3u
  8. /* Volume ratio for noise and print purposes */
  9. #define VOLUME_RATIO                (4*FRAME_SIZE)
  10. /* Desired sample rate. Typical values: 8/16/22.05/32/44.1/48kHz */
  11. #define SAMPLE_RATE_HZ              8000u
  12. /* Decimation Rate of the PDM/PCM block. Typical value is 64 */
  13. #define DECIMATION_RATE             64u
  14. /* Audio Subsystem Clock. Typical values depends on the desire sample rate:
  15. - 8/16/48kHz    : 24.576 MHz
  16. - 22.05/44.1kHz : 22.579 MHz */
  17. #define AUDIO_SYS_CLOCK_HZ          24576000u
  18. /* PDM/PCM Pins */
  19. #define PDM_DATA                    P10_5
  20. #define PDM_CLK                     P10_4


(2)pdm、pcm配置。主要采样率、编码率与模式(立体声,使用左右mic)等。
  1. /* HAL Config */
  2. const cyhal_pdm_pcm_cfg_t pdm_pcm_cfg =
  3. {
  4.     .sample_rate     = SAMPLE_RATE_HZ,
  5.     .decimation_rate = DECIMATION_RATE,
  6.     .mode            = CYHAL_PDM_PCM_MODE_STEREO,
  7.     .word_length     = 16,  /* bits */
  8.     .left_gain       = 0,   /* dB */
  9.     .right_gain      = 0,   /* dB */
  10. };


(3)按键中断回调。主要是通过事件置标志位,在主函数调高噪声阈值(noise_threshold)

  1. void button_isr_handler(void *arg, cyhal_gpio_event_t event)
  2. {
  3.     (void) arg;
  4.     (void) event;

  5.     button_flag = true;
  6. }
  7. cyhal_gpio_callback_data_t cb_data =
  8.     {
  9.         .callback = button_isr_handler,
  10.         .callback_arg = NULL
  11. };
2.main函数
(1)系统与时钟、串口、用户LED、按键初始化



(2)pdm、pcm初始化。



        这里有注册pdm_pcm_isr_handler回调,检查MIC用数据,在回调里置标志位

  1. void pdm_pcm_isr_handler(void *arg, cyhal_pdm_pcm_event_t event)
  2. {
  3.     (void) arg;
  4.     (void) event;

  5.     pdm_pcm_flag = true;
  6. }

(3)主函数实现

        检查microphone有数据,计算音量。根据当前音量与比率,打印多少个“-”。根据音量是否超过(噪声)阈值,使用户led来亮/灭。通过按键,来调高(噪声)阈值.实现代码如下
  1.     for(;;)
  2.     {
  3.         /* Check if any microphone has data to process */
  4.         if (pdm_pcm_flag)
  5.         {
  6.             /* Clear the PDM/PCM flag */
  7.             pdm_pcm_flag = 0;

  8.             /* Reset the volume */
  9.             volume = 0;

  10.             /* Calculate the volume by summing the absolute value of all the
  11.              * audio data from a frame */
  12.             for (uint32_t index = 0; index < FRAME_SIZE; index++)
  13.             {
  14.                 volume += abs(audio_frame[index]);
  15.             }

  16.             /* Prepare line to report the volume */
  17.             printf("\n\r");

  18.             /* Report the volume */
  19.             for (uint32_t index = 0; index < (volume/VOLUME_RATIO); index++)
  20.             {
  21.                 printf("-");
  22.             }

  23.             /* Turn ON the LED when the volume is higher than the threshold */
  24.             if ((volume/VOLUME_RATIO) > noise_threshold)
  25.             {
  26.                 cyhal_gpio_write((cyhal_gpio_t) CYBSP_USER_LED, CYBSP_LED_STATE_ON);
  27.             }
  28.             else
  29.             {
  30.                 cyhal_gpio_write((cyhal_gpio_t) CYBSP_USER_LED, CYBSP_LED_STATE_OFF);
  31.             }

  32.             /* Setup to read the next frame */
  33.             cyhal_pdm_pcm_read_async(&pdm_pcm, audio_frame, FRAME_SIZE);
  34.         }

  35.         /* Reset the noise threshold if User Button is pressed */
  36.         if (button_flag)
  37.         {
  38.             /* Reset button flag */
  39.             button_flag = false;

  40.             /* Get the current volume and add a hysteresis as the new threshold */
  41.             noise_threshold = (volume/VOLUME_RATIO) + THRESHOLD_HYSTERESIS;

  42.             /* Report the new noise threshold over UART */
  43.             printf("\n\rNoise threshold: %lu\n\r", (unsigned long) noise_threshold);
  44.         }

  45.         cyhal_syspm_sleep();

  46.     }
  47. }


三.调试测验
1.编译烧录


2.打开串口,查看日志
        随着外接声音的高低,出现打印“-”的长短,用户led灯伴随亮/灭。



        至此,实现麦克风拾音功能。



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
OKAKAKO 发表于 2025-11-25 21:34 | 显示全部楼层
MIC拾音了解学习一下
星辰大海不退缩 发表于 2025-11-27 13:09 | 显示全部楼层
音频设计电路还是很关键的
EPTmachine 发表于 2025-11-27 20:55 | 显示全部楼层
感谢分享音频相关的示例
您需要登录后才可以回帖 登录 | 注册

本版积分规则

30

主题

153

帖子

1

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