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

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

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

  1. /* USER CODE BEGIN Header */
  2. /**
  3. ******************************************************************************
  4. * @file : main.c
  5. * @brief : Main program body
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under Ultimate Liberty license
  13. * SLA0044, the "License"; You may not use this file except in compliance with
  14. * the License. You may obtain a copy of the License at:
  15. * www.st.com/SLA0044
  16. *
  17. ******************************************************************************
  18. */
  19. /* USER CODE END Header */
  20.  
  21. /* Includes ------------------------------------------------------------------*/
  22. #include "main.h"
  23. #include "crc.h"
  24. #include "dma.h"
  25. #include "i2s.h"
  26. //#include "pdm2pcm.h"
  27. #include "usb_device.h"
  28. #include "gpio.h"
  29.  
  30. /* Private includes ----------------------------------------------------------*/
  31. /* USER CODE BEGIN Includes */
  32. #include "usbd_cdc_if.h"
  33. #include <stdio.h>
  34. #include "pdm_filter.h"
  35. #include "arm_math.h"
  36. /* USER CODE END Includes */
  37.  
  38. /* Private typedef -----------------------------------------------------------*/
  39. /* USER CODE BEGIN PTD */
  40. /*
  41. ---- 12khz
  42. % Discrete-Time IIR Filter (real)
  43. % -------------------------------
  44. % Filter Structure : Direct-Form I, Second-Order Sections
  45. % Number of Sections : 3
  46. % Stable : Yes
  47. % Linear Phase : No
  48.  
  49. SOS Matrix:
  50. 1 -2 1 1 1.195433962890738 0.69059892324149696
  51. 1 -2 1 1 0.94280904158206325 0.33333333333333331
  52. 1 -2 1 1 0.84028692165132668 0.18834516088404465
  53.  
  54. Scale Values:
  55. 0.12379124008768976
  56. 0.097631072937817504
  57. 0.087014559808179473
  58.  
  59. --- 2khz
  60. % Generated by MATLAB(R) 8.3 and the Signal Processing Toolbox 6.21.
  61. % Generated on: 23-Jul-2019 18:13:58
  62.  
  63. % Coefficient Format: Decimal
  64.  
  65. % Discrete-Time IIR Filter (real)
  66. % -------------------------------
  67. % Filter Structure : Direct-Form I, Second-Order Sections
  68. % Number of Sections : 3
  69. % Stable : Yes
  70. % Linear Phase : No
  71.  
  72. SOS Matrix:
  73. 1 -2 1 1 -1.6812394272942188 0.81976044292731376
  74. 1 -2 1 1 -1.454243586251585 0.57406191508395488
  75. 1 -2 1 1 -1.349079994888392 0.46023366403769816
  76.  
  77. Scale Values:
  78. 0.8752499675553832
  79. 0.75707637533388505
  80. 0.70232841473152252
  81. */
  82.  
  83. #define numStages 3 // 6 order
  84. #define FILTER_SAMPLES 2*160
  85. float32_t FilterDataIn[FILTER_SAMPLES]={};
  86. float32_t FilterDataOut[FILTER_SAMPLES]={};
  87.  
  88. static float32_t testInput_f32_50Hz_200Hz[FILTER_SAMPLES]; /* input samping points */
  89. static float32_t testOutput[FILTER_SAMPLES]; /* output */
  90. static float32_t IIRStateF32[*numStages]; /* tmp buf=numTaps + blockSize - 1*/
  91.  
  92. #if 1 // 12khz hpf
  93. const float32_t IIRCoeffs32HP[*numStages] = {
  94. 1.0f, -2.0f, 1.0f, -1.195433962890738f, -0.69059892324149696f,
  95. 1.0f, -2.0f, 1.0f, -0.94280904158206325f, -0.33333333333333331f,
  96. 1.0f, -2.0f, 1.0f, -0.84028692165132668f, -0.18834516088404465f
  97. };
  98. const float32_t ScaleValue = 0.12379124008768976f * 0.097631072937817504f * 0.087014559808179473f;
  99. #else // 2khz hpf, people can hear the sound, just high pitch.
  100. const float32_t IIRCoeffs32HP[*numStages] = {
  101. 1.0f, -2.0f, 1.0f, 1.6812394272942188, -0.81976044292731376,
  102. 1.0f, -2.0f, 1.0f, 1.454243586251585, -0.57406191508395488,
  103. 1.0f, -2.0f, 1.0f, 1.349079994888392, -0.46023366403769816
  104. };
  105. const float32_t ScaleValue = 0.8752499675553832f * 0.75707637533388505f * 0.70232841473152252f;
  106. #endif
  107.  
  108. void arm_copy_u162f32(
  109. int16_t * pSrc,
  110. float32_t * pDst,
  111. uint32_t blockSize)
  112. {
  113. uint32_t blkCnt; /* loop counter */
  114.  
  115. #ifndef ARM_MATH_CM0
  116.  
  117. /* Run the below code for Cortex-M4 and Cortex-M3 */
  118.  
  119. /*loop Unrolling */
  120. blkCnt = blockSize >> 2u;
  121.  
  122. /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
  123. ** a second loop below computes the remaining 1 to 3 samples. */
  124. while(blkCnt > 0u)
  125. {
  126. /* C = A */
  127. /* Copy and then store the results in the destination buffer */
  128. *pDst++ = *pSrc++;
  129. *pDst++ = *pSrc++;
  130. *pDst++ = *pSrc++;
  131. *pDst++ = *pSrc++;
  132.  
  133. /* Decrement the loop counter */
  134. blkCnt--;
  135. }
  136.  
  137. /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
  138. ** No loop unrolling is used. */
  139. blkCnt = blockSize % 0x4u;
  140.  
  141. #else
  142.  
  143. /* Run the below code for Cortex-M0 */
  144.  
  145. /* Loop over blockSize number of values */
  146. blkCnt = blockSize;
  147.  
  148. #endif /* #ifndef ARM_MATH_CM0 */
  149.  
  150. while(blkCnt > 0u)
  151. {
  152. /* C = A */
  153. /* Copy and then store the results in the destination buffer */
  154. *pDst++ = *pSrc++;
  155.  
  156. /* Decrement the loop counter */
  157. blkCnt--;
  158. }
  159. }
  160.  
  161. void arm_copy_f322u16(
  162. float32_t * pSrc,
  163. int16_t * pDst,
  164. uint32_t blockSize)
  165. {
  166. uint32_t blkCnt; /* loop counter */
  167.  
  168. #ifndef ARM_MATH_CM0
  169.  
  170. /* Run the below code for Cortex-M4 and Cortex-M3 */
  171.  
  172. /*loop Unrolling */
  173. blkCnt = blockSize >> 2u;
  174.  
  175. /* First part of the processing with loop unrolling. Compute 4 outputs at a time.
  176. ** a second loop below computes the remaining 1 to 3 samples. */
  177. while(blkCnt > 0u)
  178. {
  179. /* C = A */
  180. /* Copy and then store the results in the destination buffer */
  181. *pDst++ = (int16_t)*pSrc++;
  182. *pDst++ = (int16_t)*pSrc++;
  183. *pDst++ = (int16_t)*pSrc++;
  184. *pDst++ = (int16_t)*pSrc++;
  185.  
  186. /* Decrement the loop counter */
  187. blkCnt--;
  188. }
  189.  
  190. /* If the blockSize is not a multiple of 4, compute any remaining output samples here.
  191. ** No loop unrolling is used. */
  192. blkCnt = blockSize % 0x4u;
  193.  
  194. #else
  195.  
  196. /* Run the below code for Cortex-M0 */
  197.  
  198. /* Loop over blockSize number of values */
  199. blkCnt = blockSize;
  200.  
  201. #endif /* #ifndef ARM_MATH_CM0 */
  202.  
  203. while(blkCnt > 0u)
  204. {
  205. /* C = A */
  206. /* Copy and then store the results in the destination buffer */
  207. *pDst++ = (int16_t)*pSrc++;
  208.  
  209. /* Decrement the loop counter */
  210. blkCnt--;
  211. }
  212. }
  213.  
  214. /* USER CODE END PTD */
  215.  
  216. /* Private define ------------------------------------------------------------*/
  217. /* USER CODE BEGIN PD */
  218.  
  219. /* USER CODE END PD */
  220.  
  221. /* Private macro -------------------------------------------------------------*/
  222. /* USER CODE BEGIN PM */
  223.  
  224. /* USER CODE END PM */
  225.  
  226. /* Private variables ---------------------------------------------------------*/
  227.  
  228. /* USER CODE BEGIN PV */
  229.  
  230. /* USER CODE END PV */
  231.  
  232. /* Private function prototypes -----------------------------------------------*/
  233. void SystemClock_Config(void);
  234. /* USER CODE BEGIN PFP */
  235.  
  236. /* USER CODE END PFP */
  237.  
  238. /* Private user code ---------------------------------------------------------*/
  239. /* USER CODE BEGIN 0 */
  240. #define PDM_2_PCM_SAM (2*64)
  241. #define PDM_SAM_POINTS (2*640)
  242. #define PCM_SAM_POINTS (2*160)
  243. typedef struct {
  244. int pdmIdx;
  245. int pcmIdx;
  246. uint16_t PDMBuf[][PDM_SAM_POINTS];
  247. int16_t PCMBuf[PCM_SAM_POINTS];
  248. }MicrophoneBufStruct;
  249.  
  250. MicrophoneBufStruct MicrophoreBuf = {};
  251. PDMFilter_InitStruct Filter;
  252.  
  253. void HAL_I2S_DMA_RxM0CpltCallback(DMA_HandleTypeDef *hdma);
  254. void HAL_I2S_DMA_RxM1CpltCallback(DMA_HandleTypeDef *hdma);
  255. void HAL_I2S_DMA_Rx_Error_CpltCallback(DMA_HandleTypeDef *hdma);
  256. int UsbTxErr = ;
  257. uint8_t printBuf[PCM_SAM_POINTS*]={};
  258. int tests = ;
  259.  
  260. static int32_t idx = ;
  261. /* USER CODE END 0 */
  262.  
  263. /**
  264. * @brief The application entry point.
  265. * @retval int
  266. */
  267. int main(void)
  268. {
  269. /* USER CODE BEGIN 1 */
  270. /* USER CODE END 1 */
  271.  
  272. /* MCU Configuration--------------------------------------------------------*/
  273.  
  274. /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  275. HAL_Init();
  276.  
  277. /* USER CODE BEGIN Init */
  278.  
  279. /* USER CODE END Init */
  280.  
  281. /* Configure the system clock */
  282. SystemClock_Config();
  283.  
  284. /* USER CODE BEGIN SysInit */
  285.  
  286. /* USER CODE END SysInit */
  287.  
  288. /* Initialize all configured peripherals */
  289. MX_GPIO_Init();
  290. MX_DMA_Init();
  291. MX_I2S2_Init();
  292. MX_USB_DEVICE_Init();
  293. MX_CRC_Init();
  294. // MX_PDM2PCM_Init();
  295. /* USER CODE BEGIN 2 */
  296. HAL_Delay();
  297. /* USER CODE END 2 */
  298.  
  299. /* Infinite loop */
  300. /* USER CODE BEGIN WHILE */
  301. __HAL_RCC_GPIOB_CLK_ENABLE();
  302. //PB0 : FOR MEAS IIS SAMPING TIME
  303. GPIO_InitTypeDef GPIO_InitStruct = {};
  304. GPIO_InitStruct.Pin = GPIO_PIN_0;
  305. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  306. GPIO_InitStruct.Pull = GPIO_PULLUP;
  307. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  308. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  309. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  310.  
  311. /* Filter LP & HP Init */ //Õâ¸öÂ˲¨Æ÷Ч¹û±È½Ï²î£¬×Ô¼ºÂ˲¨²ÅÐУ¬³öÏÖÔëÉùºÍÌø±ä¡£
  312. Filter.HP_HZ = ;
  313. Filter.LP_HZ = ;
  314. Filter.Fs = ;
  315. Filter.Out_MicChannels = ;
  316. Filter.In_MicChannels = ;
  317. PDM_Filter_Init((PDMFilter_InitStruct *)&Filter);
  318.  
  319. hi2s2.hdmarx->XferCpltCallback = HAL_I2S_DMA_RxM0CpltCallback;
  320. hi2s2.hdmarx->XferM1CpltCallback = HAL_I2S_DMA_RxM1CpltCallback;
  321. hi2s2.hdmarx->XferErrorCallback = HAL_I2S_DMA_Rx_Error_CpltCallback;
  322. HAL_DMAEx_MultiBufferStart_IT(hi2s2.hdmarx, (uint32_t)&hi2s2.Instance->DR,
  323. (uint32_t)&MicrophoreBuf.PDMBuf[], (uint32_t)&MicrophoreBuf.PDMBuf[], PDM_SAM_POINTS);
  324. HAL_I2S_DMAResume(&hi2s2);
  325. /* Enable Rx DMA Request */
  326. SET_BIT(hi2s2.Instance->CR2, SPI_CR2_RXDMAEN);
  327.  
  328. // HAL_I2S_Receive_DMA (&hi2s2, MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS);
  329. static char printBuf[]={};
  330. static int cur_buf = ;
  331. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  332.  
  333. arm_biquad_casd_df1_inst_f32 S = {};
  334. arm_biquad_cascade_df1_init_f32(&S, numStages, (float32_t *)&IIRCoeffs32HP[], (float32_t *)&IIRStateF32[]);
  335. while ()
  336. {
  337. uint16_t *srcBuf = ;
  338. int16_t *dstBuf = ;
  339.  
  340. if(MicrophoreBuf.pdmIdx == -) continue;
  341.  
  342. dstBuf = MicrophoreBuf.PCMBuf;
  343.  
  344. srcBuf = MicrophoreBuf.PDMBuf[MicrophoreBuf.pdmIdx];
  345. MicrophoreBuf.pdmIdx = -;
  346. for(int i=; i<PDM_SAM_POINTS; i++)
  347. {
  348. uint16_t a = srcBuf[i];
  349. srcBuf[i] = HTONS(a);
  350. }
  351. uint16_t volumeGain = ;
  352. int num = ;
  353.  
  354. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  355. for(int i=; i<PDM_SAM_POINTS; i=i+PDM_2_PCM_SAM)
  356. {
  357. num += PDM_Filter_64_LSB((uint8_t *)&srcBuf[i], (uint16_t *)&dstBuf[i/], volumeGain , (PDMFilter_InitStruct *)&Filter);
  358. }
  359. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  360.  
  361. // USE IIR FILTER HERE
  362. #if 1
  363. //HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, 1);
  364. arm_copy_u162f32(dstBuf, FilterDataIn, FILTER_SAMPLES);
  365. arm_biquad_cascade_df1_f32(&S, FilterDataIn, FilterDataOut, FILTER_SAMPLES);
  366. arm_scale_f32(FilterDataOut, ScaleValue, FilterDataOut, FILTER_SAMPLES);
  367. arm_copy_f322u16(FilterDataOut, dstBuf, FILTER_SAMPLES);
  368. //HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, 0);
  369. #endif
  370.  
  371. #if 0 // send raw data to pc
  372. if(USBD_OK != CDC_Transmit_FS((uint8_t *)dstBuf, *PCM_SAM_POINTS) )
  373. {
  374. UsbTxErr++;
  375. // HAL_Delay(1);
  376. // CDC_Transmit_FS((uint8_t *)dstBuf, PCM_SAM_POINTS);
  377. }
  378. #endif
  379.  
  380. #if 1 // calc fire trigger.
  381. float32_t calcRst = 0.0f;
  382. uint8_t triggerFired = ;
  383. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  384. for(int i=; i<; i++)
  385. {
  386. int offset = i*FILTER_SAMPLES/;
  387. arm_abs_f32(FilterDataOut + offset, FilterDataOut + offset, FILTER_SAMPLES/);
  388. arm_mean_f32(FilterDataOut+ offset, FILTER_SAMPLES/, &calcRst);
  389. if(((int)calcRst >) && (triggerFired == ))
  390. {
  391. triggerFired = ;
  392. break;
  393. }
  394. }
  395. HAL_GPIO_WritePin( GPIOB, GPIO_PIN_0, );
  396. uint8_t cmd[] = { ,,,,
  397. ,,,,
  398. ,,,, , ,};
  399. cmd[] = triggerFired<<; // 0x80 null, 0x81 sound, 0x82 acc, 0x83 all.
  400. cmd[] = (uint8_t)(((int)calcRst) & 0xff);
  401. cmd[] = (uint8_t)(((int)calcRst) >> );
  402. if(USBD_OK != CDC_Transmit_FS((uint8_t *)cmd, sizeof(cmd) ) )
  403. {
  404. UsbTxErr++;
  405. }
  406.  
  407. #endif
  408.  
  409. }
  410. /* USER CODE END WHILE */
  411.  
  412. /* USER CODE BEGIN 3 */
  413.  
  414. /* USER CODE END 3 */
  415. }
  416.  
  417. /**
  418. * @brief System Clock Configuration
  419. * @retval None
  420. */
  421. void SystemClock_Config(void)
  422. {
  423. RCC_OscInitTypeDef RCC_OscInitStruct = {};
  424. RCC_ClkInitTypeDef RCC_ClkInitStruct = {};
  425. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {};
  426.  
  427. /** Configure the main internal regulator output voltage
  428. */
  429. __HAL_RCC_PWR_CLK_ENABLE();
  430. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  431. /** Initializes the CPU, AHB and APB busses clocks
  432. */
  433. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  434. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  435. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  436. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  437. RCC_OscInitStruct.PLL.PLLM = ;
  438. RCC_OscInitStruct.PLL.PLLN = ;
  439. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  440. RCC_OscInitStruct.PLL.PLLQ = ;
  441. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  442. {
  443. Error_Handler();
  444. }
  445. /** Initializes the CPU, AHB and APB busses clocks
  446. */
  447. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  448. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  449. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  450. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  451. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  452. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  453.  
  454. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  455. {
  456. Error_Handler();
  457. }
  458. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;
  459. PeriphClkInitStruct.PLLI2S.PLLI2SN = ;
  460. PeriphClkInitStruct.PLLI2S.PLLI2SR = ;
  461. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  462. {
  463. Error_Handler();
  464. }
  465. }
  466.  
  467. /* USER CODE BEGIN 4 */
  468. static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
  469. {
  470. /* Clear DBM bit */
  471. hdma->Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
  472.  
  473. /* Configure DMA Stream data length */
  474. hdma->Instance->NDTR = DataLength;
  475.  
  476. /* Memory to Peripheral */
  477. if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
  478. {
  479. /* Configure DMA Stream destination address */
  480. hdma->Instance->PAR = DstAddress;
  481.  
  482. /* Configure DMA Stream source address */
  483. hdma->Instance->M0AR = SrcAddress;
  484. }
  485. /* Peripheral to Memory */
  486. else
  487. {
  488. /* Configure DMA Stream source address */
  489. hdma->Instance->PAR = SrcAddress;
  490.  
  491. /* Configure DMA Stream destination address */
  492. hdma->Instance->M0AR = DstAddress;
  493. }
  494. }
  495.  
  496. void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
  497. {
  498. uint16_t *srcBuf = MicrophoreBuf.PDMBuf[];
  499. int16_t *dstBuf = MicrophoreBuf.PCMBuf;
  500.  
  501. // HAL_I2S_Receive_DMA (&hi2s2, MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS);
  502.  
  503. // if(idx == 0){
  504. // MicrophoreBuf.pdmIdx = 0;
  505. // //HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[1], PDM_SAM_POINTS);
  506. // }
  507. // else if(idx % 2 == 1){
  508. // MicrophoreBuf.pdmIdx = 1;
  509. // // HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[0], PDM_SAM_POINTS);
  510. // }
  511. // else{
  512. // MicrophoreBuf.pdmIdx = 0;
  513. // // HAL_I2S_Receive_DMA (&hi2s2, (uint16_t*)MicrophoreBuf.PDMBuf[1], PDM_SAM_POINTS);
  514. // }
  515. // idx++;
  516. }
  517.  
  518. void HAL_I2S_DMA_RxM0CpltCallback(DMA_HandleTypeDef *hdma)
  519. {
  520. MicrophoreBuf.pdmIdx = ;
  521. }
  522.  
  523. void HAL_I2S_DMA_RxM1CpltCallback(DMA_HandleTypeDef *hdma)
  524. {
  525. MicrophoreBuf.pdmIdx = ;
  526. }
  527.  
  528. void HAL_I2S_DMA_Rx_Error_CpltCallback(DMA_HandleTypeDef *hdma)
  529. {
  530.  
  531. }
  532. /* USER CODE END 4 */
  533.  
  534. /**
  535. * @brief This function is executed in case of error occurrence.
  536. * @retval None
  537. */
  538. void Error_Handler(void)
  539. {
  540. /* USER CODE BEGIN Error_Handler_Debug */
  541. /* User can add his own implementation to report the HAL error return state */
  542.  
  543. /* USER CODE END Error_Handler_Debug */
  544. }
  545.  
  546. #ifdef USE_FULL_ASSERT
  547. /**
  548. * @brief Reports the name of the source file and the source line number
  549. * where the assert_param error has occurred.
  550. * @param file: pointer to the source file name
  551. * @param line: assert_param error line source number
  552. * @retval None
  553. */
  554. void assert_failed(uint8_t *file, uint32_t line)
  555. {
  556. /* USER CODE BEGIN 6 */
  557. /* User can add his own implementation to report the file name and line number,
  558. tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  559. /* USER CODE END 6 */
  560. }
  561. #endif /* USE_FULL_ASSERT */
  562.  
  563. /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

  1. /**
  2. ******************************************************************************
  3. * File Name : I2S.c
  4. * Description : This file provides code for the configuration
  5. * of the I2S instances.
  6. ******************************************************************************
  7. * @attention
  8. *
  9. * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  10. * All rights reserved.</center></h2>
  11. *
  12. * This software component is licensed by ST under Ultimate Liberty license
  13. * SLA0044, the "License"; You may not use this file except in compliance with
  14. * the License. You may obtain a copy of the License at:
  15. * www.st.com/SLA0044
  16. *
  17. ******************************************************************************
  18. */
  19.  
  20. /* Includes ------------------------------------------------------------------*/
  21. #include "i2s.h"
  22.  
  23. /* USER CODE BEGIN 0 */
  24.  
  25. /* USER CODE END 0 */
  26.  
  27. I2S_HandleTypeDef hi2s2;
  28. DMA_HandleTypeDef hdma_spi2_rx;
  29.  
  30. /* I2S2 init function */
  31. void MX_I2S2_Init(void)
  32. {
  33.  
  34. hi2s2.Instance = SPI2;
  35. hi2s2.Init.Mode = I2S_MODE_MASTER_RX;
  36. hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
  37. hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;
  38. hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  39. hi2s2.Init.AudioFreq = ;//I2S_AUDIOFREQ_32K;
  40. hi2s2.Init.CPOL = I2S_CPOL_HIGH;//I2S_CPOL_LOW;
  41. hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
  42. hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
  43. if (HAL_I2S_Init(&hi2s2) != HAL_OK)
  44. {
  45. Error_Handler();
  46. }
  47. }
  48.  
  49. void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)
  50. {
  51.  
  52. GPIO_InitTypeDef GPIO_InitStruct = {};
  53. if(i2sHandle->Instance==SPI2)
  54. {
  55. /* USER CODE BEGIN SPI2_MspInit 0 */
  56.  
  57. /* USER CODE END SPI2_MspInit 0 */
  58. /* I2S2 clock enable */
  59. __HAL_RCC_SPI2_CLK_ENABLE();
  60.  
  61. __HAL_RCC_GPIOC_CLK_ENABLE();
  62. __HAL_RCC_GPIOB_CLK_ENABLE();
  63. /**I2S2 GPIO Configuration
  64. PC3 ------> I2S2_SD
  65. PB10 ------> I2S2_CK
  66. PB12 ------> I2S2_WS
  67. */
  68. GPIO_InitStruct.Pin = GPIO_PIN_3;
  69. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  70. GPIO_InitStruct.Pull = GPIO_NOPULL;
  71. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  72. GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  73. HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
  74.  
  75. GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_12;
  76. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  77. GPIO_InitStruct.Pull = GPIO_NOPULL;
  78. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  79. GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
  80. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  81.  
  82. /* I2S2 DMA Init */
  83. /* SPI2_RX Init */
  84. hdma_spi2_rx.Instance = DMA1_Stream3;
  85. hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;
  86. hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
  87. hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
  88. hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;
  89. hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
  90. hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;//DMA_PDATAALIGN_HALFWORD;
  91. hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;
  92. //hdma_spi2_rx.Init.Mode = DMA_NORMAL;
  93. hdma_spi2_rx.Init.Priority = DMA_PRIORITY_HIGH;
  94. hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
  95. if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)
  96. {
  97. Error_Handler();
  98. }
  99.  
  100. __HAL_LINKDMA(i2sHandle,hdmarx,hdma_spi2_rx);
  101.  
  102. /* USER CODE BEGIN SPI2_MspInit 1 */
  103.  
  104. /* USER CODE END SPI2_MspInit 1 */
  105. }
  106. }
  107.  
  108. void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)
  109. {
  110.  
  111. if(i2sHandle->Instance==SPI2)
  112. {
  113. /* USER CODE BEGIN SPI2_MspDeInit 0 */
  114.  
  115. /* USER CODE END SPI2_MspDeInit 0 */
  116. /* Peripheral clock disable */
  117. __HAL_RCC_SPI2_CLK_DISABLE();
  118.  
  119. /**I2S2 GPIO Configuration
  120. PC3 ------> I2S2_SD
  121. PB10 ------> I2S2_CK
  122. PB12 ------> I2S2_WS
  123. */
  124. HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3);
  125.  
  126. HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_12);
  127.  
  128. /* I2S2 DMA DeInit */
  129. HAL_DMA_DeInit(i2sHandle->hdmarx);
  130. /* USER CODE BEGIN SPI2_MspDeInit 1 */
  131.  
  132. /* USER CODE END SPI2_MspDeInit 1 */
  133. }
  134. }
  135.  
  136. /* USER CODE BEGIN 1 */
  137.  
  138. /* USER CODE END 1 */
  139.  
  140. /************************ (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. Excel帮助类

    Excel帮助类操作 public class ExcelHelper { /// <summary> /// 将xls导入List /// </summary> /// &l ...

  2. MTPuTTy使用

    在开发过程中我们常常会有连接远程 lunix 服务器的需求,这个时候我们需要一个工具来帮助我们做这件事,而这类工具就是远程连接工具.常见的工具有XShell,SecureCRT,Putty等.这里我选 ...

  3. html+css快速入门教程(3)

    练习: 1.画盒子 2.相框 5 基础选择器 5.1 id选择器 ID选择器与类选择器的定义与引用方式类似,只是定义的符号不一样.ID通常表示唯一值,因此,ID选择器在CSS 中通常只出现一次.如果出 ...

  4. mackdown基础语法

    目录 前言 二.Markdown基本语法 前言 由于有些语法无法在博客园展示,推荐使用Typora解锁全套,下载地址:https://www.typora.io/ Markdown是一种可以使用普通文 ...

  5. 记一次服务器被植入挖矿木马cpu飙升200%解决过程

    线上服务器用的是某讯云的,欢快的完美运行着Tomcat,MySQL,MongoDB,ActiveMQ等程序.突然一则噩耗从前线传来:网站不能访问了. 此项目是我负责,我以150+的手速立即打开了服务器 ...

  6. Spring Boot入门系列(十七)整合Mybatis,创建自定义mapper 实现多表关联查询!

    之前讲了Springboot整合Mybatis,介绍了如何自动生成pojo实体类.mapper类和对应的mapper.xml 文件,并实现最基本的增删改查功能.mybatis 插件自动生成的mappe ...

  7. 想做时间管理大师?你可以试试Mybatis Plus代码生成器

    1. 前言 对于写Crud的老司机来说时间非常宝贵,一些样板代码写不但费时费力,而且枯燥无味.经常有小伙伴问我,胖哥你怎么天天那么有时间去搞新东西,透露一下秘诀呗. 好吧,今天就把Mybatis-pl ...

  8. Netty 源码解析(三): Netty 的 Future 和 Promise

    今天是猿灯塔“365篇原创计划”第三篇. 接下来的时间灯塔君持续更新Netty系列一共九篇 Netty 源码解析(一): 开始 Netty 源码解析(二): Netty 的 Channel 当前:Ne ...

  9. css3支持动画吗?css3可以用于网页动画的展现吗

    CSS3 主要可以分为几个模块:边框和背景,渐变,文字特效,字体,2D/3D转换,动画(过渡动画和动画),选择器,盒模型,多列布局,用户界面. css3动画有2类:一种是transition的,另一种 ...

  10. 洛谷 P1131 [ZJOI2007]时态同步 树形DP

    题目描述 分析 我们从根节点开始搜索,搜索到叶子节点,回溯的时候进行维护 先维护节点的所有子节点到该节点最大边权(边权为叶子节点到同时到达它所需要时间) 然后维护答案,答案为最大边权减去所有到子节点的 ...