1. Reference schematic diagram
1、INMP441
2、STM32
Note that the 4th pin of INMP441 is used to select the left or right channel.
2. Code generation
The code is generated using cubemx
1. iis settings
2. DMA settings
3. Generate code
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: 0x00000004
first 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;
}