使用STM32F407ZGT6的I2S驱动麦克风模块INMP441

INMP441接收

INMP441是一款高性能,低功耗,数字输出,带底部端口的全向MEMS麦克风。该完整的INMP441解决方案由一个MEMS传感器,信号组成调节,模数转换器,抗混叠滤波器,电源管理和行业标准的24位I²S接口。I²S接口允许INMP441直接连接到数字处理器,如DSP和微控制器,无需使用用于系统中的音频编解码器。INMP441具有高信噪比,是一款出色的选择近场应用。 INMP441具有扁平宽带频率响应,导致自然声音高清晰度。

接口定义:

SCK: I²S接口的串行数据时钟
WS : 用于I²S接口的串行数据字选择
L/R: 左/右声道选择。
设置为低电平时,麦克风在I²S帧的左声道输出信号。
设置为高电平时,麦克风在右声道输出信号
SD: I²S接口的串行数据输出。
VCC: 输入电源,1.8V至3.3V.
GND: 电源地

使用SerialPlot 软件显示

在这里插入图片描述
在这里插入图片描述

CUBEMX配置

开启串口
在这里插入图片描述
开启I2S
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

代码编写

/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2s.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "control.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
uint8_t		Res,buf,flag=0;

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

int fputc(int c,FILE* s)
{
	HAL_UART_Transmit(&huart1,(const uint8_t*)&c,1,0xFFFF );
	return c;
}

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */

uint32_t dma[4];
uint32_t va124;

int va132;
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
unsigned cb_cnt=0;

//I2S接受完成回调函数
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s){
	if(hi2s == &hi2s2){
		cb_cnt++;
		va124 = (dma[0]<<8)+(dma[1]>>8);
		if(va124 & 0x800000){
			va132 = 0xff000000 | va124;
		}
		else{
			va132 = va124;
		}
		//以采样频率的十分之一,串口发送采样值
		if(cb_cnt%10 == 0){
			printf("%d\r\n",va132/32);
		}
		//if(flag==2)
		//HAL_I2S_DMAStop(&hi2s2);
		HAL_I2S_Receive(&hi2s2,(uint16_t*)dma,4,100);
		
	}
}
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();
  MX_I2S2_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
	//HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)dma,4);	
	HAL_UART_Receive_IT(&huart2, &Res, 1); //用于开启中断
	HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)dma,4);	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
while (1)
{
    HAL_Delay(10);
    
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */



参考文献:使用STM32的I2S协议读取麦克风INMP441

2024年9月20日补充
发现版本之间的问题
https://www.bilibili.com/video/BV1m4e1eQERC/
最后因为需要使用到sd卡存储 INMP441一直在采集数据 创建单个.txt文件的时候并不会产生错误 但是需要先创建文件夹 再在文件夹中进行写入.txt文件的时候就出现的问题
解决 方法 将INMP441在创建文件夹时候进行停止

 	//DMA传输中止
				HAL_DMA_Abort(hi2s2.hdmarx);
    //DMA传输开启 I2S重启
				MX_DMA_Init();
				MX_I2S2_Init();
				HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)dma,4);
			
<think>好的,我现在需要帮助用户配置STM32F407通过I2S驱动INMP441麦克风。首先,我需要回顾一下I2S协议的基本知识,确保自己理解正确。I2S主要用于数字音频数据传输,包含三个信号线:时钟线SCK(也叫BCLK)、帧时钟WS(LRCLK)和数据线SD。INMP441是数字麦克风,使用I2S输出,所以需要正确配置STM32I2S模块来匹配其通信参数。 接下来,用户的具体需求是使用STM32F407I2S模块与INMP441通信。首先,我需要确定硬件连接是否正确。查阅INMP441的数据手册,确认其引脚定义:通常VDD是电源,GND接地,LRCLK是帧时钟,BCLK是位时钟,DATA是数据输出,SEL用来选择主从模式。STM32作为主设备,需要提供BCLK和LRCLK信号,所以SEL应该接高电平,让麦克风作为从设备。 然后是STM32I2S配置。STM32F407I2S支持主模式,需要设置时钟参数。INMP441的典型工作频率是例如44.1kHz的采样率,数据格式可能是16位或32位。需要确认麦克风的时钟需求,可能需要在CubeMX中配置I2S的时钟分频,以得到正确的SCK和WS频率。例如,主时钟通常由PLLI2S生成,分频后得到BCLK和LRCLK。 数据格式方面,INMP441的输出可能是24位数据,左对齐或右对齐。STM32I2S模块需要配置相同的数据格式,比如设置为I2S_DATA_FORMAT_24B。同时,需要注意DMA的配置,确保数据能够正确传输到内存,避免溢出或错误。 代码部分,可能需要使用HAL库函数,比如HAL_I2S_Transmit_DMA,并设置好回调函数处理数据。用户可能需要启用I2S和DMA的中断,并正确处理数据接收。此外,参考用户提供的引用[1],他们提到了使用串口返回数据到上位机,所以可能需要配置USART,将采集的音频数据通过串口发送出去。 可能的陷阱包括时钟配置错误导致通信失败,数据对齐方式不匹配,或者DMA缓冲区设置不当。需要提醒用户检查这些点,并在调试时使用示波器测量SCK和WS信号,确保频率正确。 最后,生成相关问题时要考虑用户可能的后续问题,比如如何优化传输速率、处理数据时的滤波方法,或者如何实现双麦克风同步采集等。确保问题覆盖配置、调试和应用场景,帮助用户深入理解整个流程。</think>### STM32F407通过I2S驱动INMP441麦克风配置指南 #### 一、硬件连接 INMP441引脚与STM32F407对应关系: - **L/RCLK** (WS):连接至I2S_WS引脚(如PB12) - **BCLK** (SCK):连接至I2S_CK引脚(如PB10) - **DOUT** (SD):连接至I2S_SD引脚(如PC3) - **SEL**:接高电平(主模式选择) - **VDD**:3.3V供电 - **GND**:共地 #### 二、CubeMX配置步骤 1. **启用I2S外设** 选择对应I2S接口(如SPI2/I2S2),模式设为`Full-Duplex Master`,时钟源选择`PLLI2S`。 2. **参数配置** ```c // 采样率44.1kHz,24位数据,主模式 hi2s2.Instance = SPI2; hi2s2.Init.Mode = I2S_MODE_MASTER_TX; hi2s2.Init.Standard = I2S_STANDARD_PHILIPS; hi2s2.Init.DataFormat = I2S_DATAFORMAT_24B; hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE; hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_44K; hi2s2.Init.CPOL = I2S_CPOL_LOW; ``` 3. **DMA配置** 添加DMA通道,方向设为`Memory to Peripheral`,模式为`Circular`,数据宽度选择`Half Word`(配合24位数据对齐)。 #### 三、代码实现关键片段 ```c // 启动I2S接收 HAL_I2S_Receive_DMA(&hi2s2, (uint16_t*)pDataBuf, BUFFER_SIZE); // DMA传输完成回调函数 void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s) { // 处理音频数据(如通过串口发送) USART_Transmit((uint8_t*)pDataBuf, BUFFER_SIZE*2); // 24bit转16bit示例 } ``` #### 四、调试要点 1. **时钟验证** 使用示波器测量WS频率应为$f_{ws}=44.1\text{kHz}$,BCLK频率为$f_{bclk}=f_{ws} \times 64 = 2.8224\text{MHz}$(24位数据+32位帧)。 2. **数据对齐** INMP441输出为24位补码格式,需在STM32中处理符号扩展或进行位移操作: $$ \text{有效值} = (\text{原始数据} \gg 8) \times 3.3/2^{23} $$ [^1]: 参考实现中STM32通过I2S+USB高速传输实现过1M采样率音频采集。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值