STM32 drives INMP441 microphone to realize left and right channel sound collection

1. Reference schematic diagram

1、INMP441

insert image description here

2、STM32

insert image description here
Note that the 4th pin of INMP441 is used to select the left or right channel.
insert image description here

2. Code generation

The code is generated using cubemx

1. iis settings

insert image description here

2. DMA settings

insert image description here

3. Generate code

insert image description here

3. Code modification

1. First define an array

	#define BUFFER_SIZE (4)
	static uint32_t simpleBuf[BUFFER_SIZE];
	/* USER CODE BEGIN PV */
	uint32_t val24;
	int val32;
/* USER CODE END PV */

2. Define the receiving completion interrupt function

/* USER CODE BEGIN 0 */
unsigned cb_cnt=0;
//I2S接收完成回调函数
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
    
    
	if(hi2s==&hi2s2){
    
    
		cb_cnt++;//回调次数计数
		//将两个32整型合并为一个
		//dat32 example: 0000fffb 00004f00
		val24=(dma[0]<<8)+(dma[1]>>8);
		//将24位有符号整型扩展到32位
		if(val24 & 0x800000){
    
    //negative
			val32=0xff000000 | val24;
		}else{
    
    //positive
			val32=val24;
		}
		//以采样频率的十分之一,串口发送采样值
		if(cb_cnt%10==0)
			printf("%d\r\n",val32);
	}
}
/* USER CODE END 0 */

3. Start receiving

HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)simpleBuf,BUFFER_SIZE);	

4. Complete code

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* 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 "stm32f1xx_hal.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

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

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

/* USER CODE END PM */

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

/* USER CODE BEGIN PV */
uint32_t dma[4];
uint32_t val24;
int val32;
/* 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++;//回调次数计数
		//将两个32整型合并为一个
		//dat32 example: 0000fffb 00004f00
		val24=(simpleBuf[0]<<8)+(simpleBuf[1]>>8);
		//将24位有符号整型扩展到32位
		if(val24 & 0x800000){
    
    //negative
			val32=0xff000000 | val24;
		}else{
    
    //positive
			val32=val24;
		}
		//以采样频率的十分之一,串口发送采样值
		if(cb_cnt%10==0)
			printf("%d\r\n",val32);
	}
}
/* 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_USART1_UART_Init();
  MX_DMA_Init();
  MX_I2S2_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  //开启DMA传输
  HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)simpleBuf,BUFFER_SIZE);		
  while (1)
  {
    
    
  	HAL_Delay(10);
	
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
//后面都是Cube自动生成的代码,省略

5. Code Analysis

According to the above description, the unit of the last parameter size is determined by the length of the data frame. The data format previously set in Cube is 24 Bits Data on 32 Bits Frame, so the total length of DMA read data is size×4 bytes. The previously defined DMA buffer is a uint32_t array with a length of 4, and the data format in the buffer is: 前2个元素表示左声道数据, 后2个表示右声道数据.
The single-channel data format is: first byte: 0x00000004first byte: 0x00004500. By val24=(dma[0]<<8)+(dma[1]>>8);compositing 0x00fffb4f , and then distinguishing between positive and negative:

if(val24 & 0x800000){
    
    
			val32=0xff000000 | val24;
		}else{
    
    
			val32=val24;
		}

Guess you like

Origin blog.csdn.net/qq_15181569/article/details/131224833