本文是数字麦克风笔记文章的单片机程序。一些朋友私信我,调试出问题。

我就把源码贴出来吧,可能主要问题是DMA的配置。

尤其双DMA时候,需要手动启动I2S的接收DMA,HAL库没有这个接口,不看datasheet是找不到这个毛病的,这也是HAL库用多了引起的问题,一些特底层的问题大家都不愿意去搞了。

/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "crc.h"
#include "dma.h"
#include "i2s.h"
//#include "pdm2pcm.h"
#include "usb_device.h"
#include "gpio.h" /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include <stdio.h>
#include "pdm_filter.h"
#include "arm_math.h"
/* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/*
---- 12khz
% Discrete-Time IIR Filter (real)
% -------------------------------
% Filter Structure : Direct-Form I, Second-Order Sections
% Number of Sections : 3
% Stable : Yes
% Linear Phase : No SOS Matrix:
1 -2 1 1 1.195433962890738 0.69059892324149696
1 -2 1 1 0.94280904158206325 0.33333333333333331
1 -2 1 1 0.84028692165132668 0.18834516088404465 Scale Values:
0.12379124008768976
0.097631072937817504
0.087014559808179473 --- 2khz
% Generated by MATLAB(R) 8.3 and the Signal Processing Toolbox 6.21.
% Generated on: 23-Jul-2019 18:13:58 % Coefficient Format: Decimal % Discrete-Time IIR Filter (real)
% -------------------------------
% Filter Structure : Direct-Form I, Second-Order Sections
% Number of Sections : 3
% Stable : Yes
% Linear Phase : No SOS Matrix:
1 -2 1 1 -1.6812394272942188 0.81976044292731376
1 -2 1 1 -1.454243586251585 0.57406191508395488
1 -2 1 1 -1.349079994888392 0.46023366403769816 Scale Values:
0.8752499675553832
0.75707637533388505
0.70232841473152252
*/ #define numStages 3 // 6 order
#define FILTER_SAMPLES 2*160
float32_t FilterDataIn[FILTER_SAMPLES]={};
float32_t FilterDataOut[FILTER_SAMPLES]={}; static float32_t testInput_f32_50Hz_200Hz[FILTER_SAMPLES]; /* input samping points */
static float32_t testOutput[FILTER_SAMPLES]; /* output */
static float32_t IIRStateF32[*numStages]; /* tmp buf=numTaps + blockSize - 1*/ #if 1 // 12khz hpf
const float32_t IIRCoeffs32HP[*numStages] = {
1.0f, -2.0f, 1.0f, -1.195433962890738f, -0.69059892324149696f,
1.0f, -2.0f, 1.0f, -0.94280904158206325f, -0.33333333333333331f,
1.0f, -2.0f, 1.0f, -0.84028692165132668f, -0.18834516088404465f
};
const float32_t ScaleValue = 0.12379124008768976f * 0.097631072937817504f * 0.087014559808179473f;
#else // 2khz hpf, people can hear the sound, just high pitch.
const float32_t IIRCoeffs32HP[*numStages] = {
1.0f, -2.0f, 1.0f, 1.6812394272942188, -0.81976044292731376,
1.0f, -2.0f, 1.0f, 1.454243586251585, -0.57406191508395488,
1.0f, -2.0f, 1.0f, 1.349079994888392, -0.46023366403769816
};
const float32_t ScaleValue = 0.8752499675553832f * 0.75707637533388505f * 0.70232841473152252f;
#endif void arm_copy_u162f32(
int16_t * pSrc,
float32_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counter */ #ifndef ARM_MATH_CM0 /* Run the below code for Cortex-M4 and Cortex-M3 */ /*loop Unrolling */
blkCnt = blockSize >> 2u; /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while(blkCnt > 0u)
{
/* C = A */
/* Copy and then store the results in the destination buffer */
*pDst++ = *pSrc++;
*pDst++ = *pSrc++;
*pDst++ = *pSrc++;
*pDst++ = *pSrc++; /* Decrement the loop counter */
blkCnt--;
} /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4u; #else /* Run the below code for Cortex-M0 */ /* Loop over blockSize number of values */
blkCnt = blockSize; #endif /* #ifndef ARM_MATH_CM0 */ while(blkCnt > 0u)
{
/* C = A */
/* Copy and then store the results in the destination buffer */
*pDst++ = *pSrc++; /* Decrement the loop counter */
blkCnt--;
}
} void arm_copy_f322u16(
float32_t * pSrc,
int16_t * pDst,
uint32_t blockSize)
{
uint32_t blkCnt; /* loop counter */ #ifndef ARM_MATH_CM0 /* Run the below code for Cortex-M4 and Cortex-M3 */ /*loop Unrolling */
blkCnt = blockSize >> 2u; /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
** a second loop below computes the remaining 1 to 3 samples. */
while(blkCnt > 0u)
{
/* C = A */
/* Copy and then store the results in the destination buffer */
*pDst++ = (int16_t)*pSrc++;
*pDst++ = (int16_t)*pSrc++;
*pDst++ = (int16_t)*pSrc++;
*pDst++ = (int16_t)*pSrc++; /* Decrement the loop counter */
blkCnt--;
} /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
** No loop unrolling is used. */
blkCnt = blockSize % 0x4u; #else /* Run the below code for Cortex-M0 */ /* Loop over blockSize number of values */
blkCnt = blockSize; #endif /* #ifndef ARM_MATH_CM0 */ while(blkCnt > 0u)
{
/* C = A */
/* Copy and then store the results in the destination buffer */
*pDst++ = (int16_t)*pSrc++; /* Decrement the loop counter */
blkCnt--;
}
} /* 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 */ /* 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 */
#define PDM_2_PCM_SAM (2*64)
#define PDM_SAM_POINTS (2*640)
#define PCM_SAM_POINTS (2*160)
typedef struct {
int pdmIdx;
int pcmIdx;
uint16_t PDMBuf[][PDM_SAM_POINTS];
int16_t PCMBuf[PCM_SAM_POINTS];
}MicrophoneBufStruct; MicrophoneBufStruct MicrophoreBuf = {};
PDMFilter_InitStruct Filter; void HAL_I2S_DMA_RxM0CpltCallback(DMA_HandleTypeDef *hdma);
void HAL_I2S_DMA_RxM1CpltCallback(DMA_HandleTypeDef *hdma);
void HAL_I2S_DMA_Rx_Error_CpltCallback(DMA_HandleTypeDef *hdma);
int UsbTxErr = ;
uint8_t printBuf[PCM_SAM_POINTS*]={};
int tests = ; static int32_t idx = ;
/* 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_I2S2_Init();
MX_USB_DEVICE_Init();
MX_CRC_Init();
// MX_PDM2PCM_Init();
/* USER CODE BEGIN 2 */
HAL_Delay();
/* USER CODE END 2 */ /* Infinite loop */
/* USER CODE BEGIN WHILE */
__HAL_RCC_GPIOB_CLK_ENABLE();
//PB0 : FOR MEAS IIS SAMPING TIME
GPIO_InitTypeDef GPIO_InitStruct = {};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, ); /* Filter LP & HP Init */ //Õâ¸öÂ˲¨Æ÷Ч¹û±È½Ï²î£¬×Ô¼ºÂ˲¨²ÅÐУ¬³öÏÖÔëÉùºÍÌø±ä¡£
Filter.HP_HZ = ;
Filter.LP_HZ = ;
Filter.Fs = ;
Filter.Out_MicChannels = ;
Filter.In_MicChannels = ;
PDM_Filter_Init((PDMFilter_InitStruct *)&Filter); hi2s2.hdmarx->XferCpltCallback = HAL_I2S_DMA_RxM0CpltCallback;
hi2s2.hdmarx->XferM1CpltCallback = HAL_I2S_DMA_RxM1CpltCallback;
hi2s2.hdmarx->XferErrorCallback = HAL_I2S_DMA_Rx_Error_CpltCallback;
HAL_DMAEx_MultiBufferStart_IT(hi2s2.hdmarx, (uint32_t)&hi2s2.Instance->DR,
(uint32_t)&MicrophoreBuf.PDMBuf[], (uint32_t)&MicrophoreBuf.PDMBuf[], PDM_SAM_POINTS);
HAL_I2S_DMAResume(&hi2s2);
/* Enable Rx DMA Request */
SET_BIT(hi2s2.Instance->CR2, SPI_CR2_RXDMAEN); // HAL_I2S_Receive_DMA (&hi2s2, MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS);
static char printBuf[]={};
static int cur_buf = ;
HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, ); arm_biquad_casd_df1_inst_f32 S = {};
arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32HP[], (float32_t *)&IIRStateF32[]);
while ()
{
uint16_t *srcBuf = ;
int16_t *dstBuf = ; if(MicrophoreBuf.pdmIdx == -) continue; dstBuf = MicrophoreBuf.PCMBuf; srcBuf = MicrophoreBuf.PDMBuf[MicrophoreBuf.pdmIdx];
MicrophoreBuf.pdmIdx = -;
for(int i=; i<PDM_SAM_POINTS; i++)
{
uint16_t a = srcBuf[i];
srcBuf[i] = HTONS(a);
}
uint16_t volumeGain = ;
int num = ; HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
for(int i=; i<PDM_SAM_POINTS; i=i+PDM_2_PCM_SAM)
{
num += PDM_Filter_64_LSB((uint8_t *)&srcBuf[i], (uint16_t *)&dstBuf[i/], volumeGain , (PDMFilter_InitStruct *)&Filter);
}
HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, ); // USE IIR FILTER HERE
#if 1
//HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, 1);
arm_copy_u162f32(dstBuf, FilterDataIn, FILTER_SAMPLES);
arm_biquad_cascade_df1_f32(&S, FilterDataIn, FilterDataOut, FILTER_SAMPLES);
arm_scale_f32(FilterDataOut, ScaleValue, FilterDataOut, FILTER_SAMPLES);
arm_copy_f322u16(FilterDataOut, dstBuf, FILTER_SAMPLES);
//HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, 0);
#endif #if 0 // send raw data to pc
if(USBD_OK != CDC_Transmit_FS((uint8_t *)dstBuf, *PCM_SAM_POINTS) )
{
UsbTxErr++;
// HAL_Delay(1);
// CDC_Transmit_FS((uint8_t *)dstBuf, PCM_SAM_POINTS);
}
#endif #if 1 // calc fire trigger.
float32_t calcRst = 0.0f;
uint8_t triggerFired = ;
HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
for(int i=; i<; i++)
{
int offset = i*FILTER_SAMPLES/;
arm_abs_f32(FilterDataOut + offset, FilterDataOut + offset, FILTER_SAMPLES/);
arm_mean_f32(FilterDataOut+ offset, FILTER_SAMPLES/, &calcRst);
if(((int)calcRst >) && (triggerFired == ))
{
triggerFired = ;
break;
}
}
HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
uint8_t cmd[] = { ,,,,
,,,,
,,,, , ,};
cmd[] = triggerFired<<; // 0x80 null, 0x81 sound, 0x82 acc, 0x83 all.
cmd[] = (uint8_t)(((int)calcRst) & 0xff);
cmd[] = (uint8_t)(((int)calcRst) >> );
if(USBD_OK != CDC_Transmit_FS((uint8_t *)cmd, sizeof(cmd) ) )
{
UsbTxErr++;
} #endif }
/* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* USER CODE END 3 */
} /**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {}; /** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
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 = ;
RCC_OscInitStruct.PLL.PLLN = ;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = ;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses 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();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
PeriphClkInitStruct.PLLI2S.PLLI2SN = ;
PeriphClkInitStruct.PLLI2S.PLLI2SR = ;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
} /* USER CODE BEGIN 4 */
static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
/* Clear DBM bit */
hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM); /* Configure DMA Stream data length */
hdma->Instance->NDTR = DataLength; /* Memory to Peripheral */
if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
{
/* Configure DMA Stream destination address */
hdma->Instance->PAR = DstAddress; /* Configure DMA Stream source address */
hdma->Instance->M0AR = SrcAddress;
}
/* Peripheral to Memory */
else
{
/* Configure DMA Stream source address */
hdma->Instance->PAR = SrcAddress; /* Configure DMA Stream destination address */
hdma->Instance->M0AR = DstAddress;
}
} void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
uint16_t *srcBuf = MicrophoreBuf.PDMBuf[];
int16_t *dstBuf = MicrophoreBuf.PCMBuf; // HAL_I2S_Receive_DMA (&hi2s2, MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS); // if(idx == 0){
// MicrophoreBuf.pdmIdx = 0;
// //HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[1], PDM_SAM_POINTS);
// }
// else if(idx % 2 == 1){
// MicrophoreBuf.pdmIdx = 1;
// // HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS);
// }
// else{
// MicrophoreBuf.pdmIdx = 0;
// // HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[1], PDM_SAM_POINTS);
// }
// idx++;
} void HAL_I2S_DMA_RxM0CpltCallback(DMA_HandleTypeDef *hdma)
{
MicrophoreBuf.pdmIdx = ;
} void HAL_I2S_DMA_RxM1CpltCallback(DMA_HandleTypeDef *hdma)
{
MicrophoreBuf.pdmIdx = ;
} void HAL_I2S_DMA_Rx_Error_CpltCallback(DMA_HandleTypeDef *hdma)
{ }
/* 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 */ /* 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,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

/**
******************************************************************************
* File Name : I2S.c
* Description : This file provides code for the configuration
* of the I2S instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/ /* Includes ------------------------------------------------------------------*/
#include "i2s.h" /* USER CODE BEGIN 0 */ /* USER CODE END 0 */ I2S_HandleTypeDef hi2s2;
DMA_HandleTypeDef hdma_spi2_rx; /* I2S2 init function */
void MX_I2S2_Init(void)
{ hi2s2.Instance = SPI2;
hi2s2.Init.Mode = I2S_MODE_MASTER_RX;
hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
hi2s2.Init.AudioFreq = ;//I2S_AUDIOFREQ_32K;
hi2s2.Init.CPOL = I2S_CPOL_HIGH;//I2S_CPOL_LOW;
hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
if (HAL_I2S_Init(&hi2s2) != HAL_OK)
{
Error_Handler();
}
} void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)
{ GPIO_InitTypeDef GPIO_InitStruct = {};
if(i2sHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */ /* USER CODE END SPI2_MspInit 0 */
/* I2S2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE(); __HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2S2 GPIO Configuration
PC3 ------> I2S2_SD
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS
*/
GPIO_InitStruct.Pin = GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /* I2S2 DMA Init */
/* SPI2_RX Init */
hdma_spi2_rx.Instance = DMA1_Stream3;
hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;
hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//DMA_PDATAALIGN_HALFWORD;
hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;
//hdma_spi2_rx.Init.Mode = DMA_NORMAL;
hdma_spi2_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
{
Error_Handler();
} __HAL_LINKDMA(i2sHandle,hdmarx,hdma_spi2_rx); /* USER CODE BEGIN SPI2_MspInit 1 */ /* USER CODE END SPI2_MspInit 1 */
}
} void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)
{ if(i2sHandle->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspDeInit 0 */ /* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE(); /**I2S2 GPIO Configuration
PC3 ------> I2S2_SD
PB10 ------> I2S2_CK
PB12 ------> I2S2_WS
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3); HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_12); /* I2S2 DMA DeInit */
HAL_DMA_DeInit(i2sHandle->hdmarx);
/* USER CODE BEGIN SPI2_MspDeInit 1 */ /* USER CODE END SPI2_MspDeInit 1 */
}
} /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/


数字麦克风PDM信号采集与STM32 I2S接口应用--笔记目录:

数字麦克风PDM信号采集与STM32 I2S接口应用(一)

https://www.cnblogs.com/pingwen/p/11298675.html

数字麦克风PDM信号采集与STM32 I2S接口应用(二)

https://www.cnblogs.com/pingwen/p/11301935.html

数字麦克风PDM信号采集与STM32 I2S接口应用(三)

https://www.cnblogs.com/pingwen/p/11794081.html

数字麦克风PDM转PCM与STM32 I2S接口应用----重要文档列表

https://www.cnblogs.com/pingwen/p/11302452.html

数字麦克风PDM信号采集与STM32 I2S接口应用(四)--单片机源码

https://www.cnblogs.com/pingwen/p/13371144.html

数字麦克风PDM信号采集与STM32 I2S接口应用(四)--单片机源码的更多相关文章

  1. 数字麦克风PDM信号采集与STM32 I2S接口应用

    数字麦克风采用MEMS技术,将声波信号转换为数字采样信号,由单芯片实现采样量化编码,一般而言数字麦克风的输出有PDM麦克风和PCM麦克风,由于PDM麦克风结构.工艺简单而大量应用,在使用中要注意这二者 ...

  2. 数字麦克风PDM信号采集与STM32 I2S接口应用(二)

    在使用STM32的数字麦克风I2S接口时,计算采样率让人头疼,芯片手册上没有明确的说法,而手册上的计算方法经过测试确和实验不符.借助搜索引擎,大部分资料都是来自于开发板卖家或开发板论坛,主要是咪头采集 ...

  3. 数字麦克风PDM信号采集与STM32 I2S接口应用--笔记目录

    数字麦克风采用MEMS技术,将声波信号转换为数字采样信号,由单芯片实现采样量化编码,一般而言数字麦克风的输出有PDM麦克风和PCM麦克风,由于PDM麦克风结构.工艺简单而大量应用,在使用中要注意这二者 ...

  4. 数字麦克风PDM信号采集与STM32 I2S接口应用(三)

    本文是数字麦克风笔记文章的数据处理篇. 读取数字麦克风的信号,需要嵌入式驱动和PC应用的结合,驱动负责信号采集,应用代码负责声音分析. 一般而言,在完成特征分析和实验之后,把优化过的代码固化到嵌入式端 ...

  5. 数字麦克风PDM转PCM与STM32 I2S接口应用----重要文档列表

    数字麦克风PDM脉冲到PCM信号需要一个二次采样,ST 提过了PDM2PCM的软件包,可以完成上面的工作.软件包源码没有开源,使用手册也简洁的让人抓狂,我觉得可能是因为ST更高级的MCU直接带了硬解码 ...

  6. ADI高速信号采集芯片与JESD204B接口简介

    ADI高速信号采集芯片与JESD204B接口简介 JESD204B接口 介绍: JEDEC Standard No. 204B (JESD204B)—A standardized serial int ...

  7. DirectShow音频采集pcm,实时编码AAC,附源码

    定期送福利,今天给大家送上Windows中利用DirectShow采集microphone音频,并将采集到的pcm数据,利用FAAC库编码成AAC,进行本地存储或者网络传输. 直接贴代码,解析看注释: ...

  8. STM32时钟系统的配置寄存器和源码分析

    一.时钟系统 概述 时钟是单片机运行的基础,时钟信号推动单片机内各个部分执行相应的指令,时钟系统就是CPU的脉搏,决定cpu速率. STM32有多个时钟来源的选择,为什么 STM32 要有多个时钟源呢 ...

  9. 手把手教你使用LabVIEW人工智能视觉工具包快速实现图像读取与采集(含源码)

    目录 前言 一.工具包位置 二.图像采集与色彩空间转换 1.文件读写 2.实现图片读取 3.使用算子cvtColor实现颜色空间转换 三.从摄像头采集图像 1.Camera类 2.属性节点 3.实现摄 ...

随机推荐

  1. Mongodb 批量更新

    >db.col.update({查询条件},{修改条件},{multi:true})

  2. bug和测试报告思维导图

    Bug定义: 1.不符合需求的 2.程序本身的报错 3.不符合用户使用习惯的 Bug生命周期: 当我们测试人员提交一个bug的时候,自始bug就有它的生命周期,从开始到结束, 把测试的过程和结果写成文 ...

  3. 00【笔记】 Shiro登陆过滤提示信息

    Shiro登陆过滤 提示信息 package top.yangbuyi.system.shiro; import com.alibaba.fastjson.JSONObject; import org ...

  4. DDoS压力测试工具t50

    site: https://sourceforge.net/projects/t50/ 例子:t50 192.168.1.1 --flood--protocol T50|TCP|UDP|ICMP--t ...

  5. java普通对象和json字符串的互转

    一.java普通对象和json字符串的互转 java对象---->json 首先创建一个java对象: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1 ...

  6. Nginx使用upstream实现负载均衡

    如果Nginx没有仅仅只能代理一台服务器的话,那它也不可能像今天这么火,Nginx可以配置代理多台服务器,当一台服务器宕机之后,仍能保持系统可用.具体配置过程如下: 1. 在http节点下,添加ups ...

  7. Redis系列(十):数据结构Set源码解析和SADD、SINTER、SDIFF、SUNION、SPOP命令

    1.介绍 Hash是以K->V形式存储,而Set则是K存储,空间节省了很多 Redis中Set是String类型的无序集合:集合成员是唯一的. 这就意味着集合中不能出现重复的数据.可根据应用场景 ...

  8. mysql根据一张表更新另一张表数据

    UPDATE channelcountry, appywproducts SET channelcountry.ChannelName = appywproducts.YWNameCN WHERE c ...

  9. ORA-39257: Data cannot be remapped for more than 10 columns.

    ORA-39257: Data cannot be remapped for more than 10 columns. 前言 还是脱敏数据相关的事情. 使用expdp的remap_data参数对指定 ...

  10. Python线程池与进程池

    Python线程池与进程池 前言 前面我们已经将线程并发编程与进程并行编程全部摸了个透,其实我第一次学习他们的时候感觉非常困难甚至是吃力.因为概念实在是太多了,各种锁,数据共享同步,各种方法等等让人十 ...