上周搞了个IIS的麦克风,用32做个音频采集,把数据发往电脑,处理后可保存为wav格式,具体处理方式可查看wav格式的头文件。
单片机源程序如下:
- #include "stm32f10x.h"
- #include "stm32f10x_spi.h"
- #include "stm32f10x_rcc.h"
- #include "stm32f10x_dac.h"
- #include "stm32f10x_gpio.h"
- #include "stm32f10x_tim.h"
- #include "stm32f10x_crc.h"
- #include "stm32f10x_dma.h"
- #include "stm32f10x_usart.h"
- #include "misc.h"
- #include "pbdata.h"
- #include "pdm_filter.h"
- int Rx_buffer[64];
- int Tx_buffer[64];
- int DualSine12bit[64];
- PDMFilter_InitStruct pdmf;
- void I2S_DMA_Config(void)
- {
- DMA_InitTypeDef DMA_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //??DMA2
- DMA_DeInit(DMA1_Channel4);
-
- DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t)&(SPI2->DR); //
- DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Tx_buffer ; //
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //
- DMA_InitStructure.DMA_BufferSize =64; //
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //
- DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; //
- DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; //
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
- DMA_Init(DMA1_Channel4, &DMA_InitStructure);
- /* Enable DMA1 channel1 IRQ Channel */
- DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); //开启 DMA传输完成中断
- /* Enable DMA1 channel1 */
- SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
- DMA_Cmd(DMA1_Channel4, ENABLE);
-
- NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- //I2S音频总线配置
- void I2S_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- GPIO_InitTypeDef GPIO_InitStructure;
- // Initialise and Configure the Mode for I2S
- I2S_InitTypeDef I2S_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE );
- // Enable I2S peripheral clocks
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- SPI_I2S_DeInit(SPI2);
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_12|GPIO_Pin_13; //端口
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; //IO复用输出
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //IO口悬空输入
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- GPIO_SetBits(GPIOB,GPIO_Pin_13|GPIO_Pin_12);
-
- I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
- I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
- I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
- I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_16k;
- I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
- I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
- I2S_Init(SPI2, &I2S_InitStructure);
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);
- SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Rx,ENABLE); //SPI2
- I2S_Cmd(SPI2, ENABLE);
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
-
- NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void PDMFilter_Configuration(void)
- {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_CRC, ENABLE);
- pdmf.Fs=8000;
- pdmf.LP_HZ=10;
- pdmf.HP_HZ=14000;
- pdmf.In_MicChannels=1;
- pdmf.Out_MicChannels=1;
- PDM_Filter_Init(&pdmf);
- }
- //音频数据低通滤波
- void T16T12(void)
- {
- int i;
- PDM_Filter_64_LSB((uint8_t*)Tx_buffer,(uint16_t*)Rx_buffer,(uint16_t) 50,(PDMFilter_InitStruct*)&pdmf);
- for(i=0;i<64;i++)
- {
- Rx_buffer[i]=~Rx_buffer[i];
- }
-
- }
- void DMA1_Channel4_IRQHandler(void)
- {
- //DMA一次通道数据获取搬运完成
- if (DMA_GetITStatus(DMA1_IT_TC4))
- {
- DMA_Cmd(DMA1_Channel4, DISABLE);
-
- T16T12(); //24位转12位函数
- DMA_ClearITPendingBit(DMA1_IT_TC4);
- // DMA1_Channel4->CNDTR = 64;
- DMA_Cmd(DMA1_Channel4, ENABLE);
- SPI_I2S_ITConfig( SPI2, SPI_I2S_IT_RXNE, ENABLE );//
- }
- }
- void SPI2_IRQHandler(void)
- {
- if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) == SET)
- {
- SPI_I2S_ClearITPendingBit( SPI2,SPI_I2S_IT_RXNE );
- SPI_I2S_ITConfig( SPI2, SPI_I2S_IT_RXNE, DISABLE );//
-
- }
- }
- void usart2_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_USART_TX_InitStructure;
- GPIO_InitTypeDef GPIO_USART_RX_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- DMA_InitTypeDef DMA_InitStructure; //定义DMA初始化结构体DMA_InitStructure
- USART_InitTypeDef USART_InitStructure;
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
-
- // ??USART_TX
- GPIO_USART_TX_InitStructure.GPIO_Pin = GPIO_Pin_2;
- GPIO_USART_TX_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_USART_TX_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
-
- GPIO_Init(GPIOA, &GPIO_USART_TX_InitStructure);
-
- // ??USART_RX
- GPIO_USART_RX_InitStructure.GPIO_Pin = GPIO_Pin_3;
- GPIO_USART_RX_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_USART_TX_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_USART_RX_InitStructure);
- USART_InitStructure.USART_BaudRate = 115200;
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;
- USART_InitStructure.USART_StopBits = USART_StopBits_1;
- USART_InitStructure.USART_Parity = USART_Parity_No;
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
-
- USART_Init(USART2, &USART_InitStructure);
- USART_Cmd(USART2, ENABLE);
- DMA_DeInit(DMA1_Channel7); //重置DMA 2通道配置
- DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART2->DR; //外设地址
- DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Rx_buffer; //内存地址
- DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
- DMA_InitStructure.DMA_BufferSize =64; //DMA缓存大小:BufferSize
- DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不递增
- DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址寄存器递增
- DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Word ; //外设数据宽度
- DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word ; //内存数据宽度
- DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常缓存模式
- DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //设置DMA通道优先级为高
- DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止DMA通道设置为内存至内存传输
- DMA_Init(DMA1_Channel7, &DMA_InitStructure); //初始化
- DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);//传输完成中断
- DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);//传输错误中断
- USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);
- USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
- DMA_Cmd(DMA1_Channel7, ENABLE);
- NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void DMA1_Channel7_IRQHandler(void)
- {
- //DMA一次通道数据获取搬运完成
- if (DMA_GetITStatus(DMA1_IT_TC7))
- {
- DMA_Cmd(DMA1_Channel7, DISABLE);
-
- DMA_ClearITPendingBit(DMA1_IT_TC7);
- DMA_ClearITPendingBit(DMA1_IT_TE7);
- // DMA1_Channel7->CNDTR = 128;
- DMA_Cmd(DMA1_Channel7, ENABLE);
- }
- }
- int main(void)
- {
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- PDMFilter_Configuration();
- I2S_Configuration();
- I2S_DMA_Config();
- usart2_Configuration();
- // USART_SendData(USART2, 'A');
- while (1)
- {
- }
- }
复制代码
- /* Includes ------------------------------------------------------------------*/
- #include "main.h"
- #include "pdm_filter.h"
- #include "waverecorder.h"
- #include "ff.h"
- /** @addtogroup STM32F4-Discovery_Audio_Player_Recorder
- * @{
- */
- /* Private typedef -----------------------------------------------------------*/
- /* Private define ------------------------------------------------------------*/
- /* SPI Configuration defines */
- #if 1
- #define SPI_SCK_PIN GPIO_Pin_13
- #define SPI_SCK_GPIO_PORT GPIOB
- #define SPI_SCK_GPIO_CLK RCC_APB2Periph_GPIOB
- #define SPI_SCK_SOURCE GPIO_PinSource13
- #define SPI_WS_PIN GPIO_Pin_12
- #define SPI_WS_GPIO_PORT GPIOB
- #define SPI_WS_GPIO_CLK RCC_APB2Periph_GPIOB
- #define SPI_WS_SOURCE GPIO_PinSource12
- #define SPI_MOSI_PIN GPIO_Pin_15
- #define SPI_MOSI_GPIO_PORT GPIOB
- #define SPI_MOSI_GPIO_CLK RCC_APB2Periph_GPIOB
- #define SPI_MOSI_SOURCE GPIO_PinSource15
- #endif
-
- /* Audio recording frequency in Hz */
- #define REC_FREQ 8000
- /* PDM buffer input size */
- #define INTERNAL_BUFF_SIZE 64
- /* PCM buffer output size */
- #define PCM_OUT_SIZE 16
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- extern __IO uint16_t Time_Rec_Base;
- __IO uint8_t Command_index=1;
- extern __IO uint32_t WaveCounter;
- extern FIL fil;
- extern __IO uint8_t LED_Toggle;
- uint16_t RAM_Buf[RAM_BUFFER_SIZE];
- uint16_t RAM_Buf1 [RAM_BUFFER_SIZE];
- uint16_t buf_idx = 0, buf_idx1 =0;
- uint16_t *writebuffer;
- uint16_t counter = 0;
- uint8_t WaveRecStatus = 0;
- /* Current state of the audio recorder interface intialization */
- static uint32_t AudioRecInited = 0;
- PDMFilter_InitStruct Filter;
- /* Audio recording Samples format (from 8 to 16 bits) */
- uint32_t AudioRecBitRes = 16;
- uint16_t RecBuf[PCM_OUT_SIZE], RecBuf1[PCM_OUT_SIZE];
- uint8_t RecBufHeader[512], Switch = 0;
- __IO uint32_t Data_Status =0;
- /* Audio recording number of channels (1 for Mono or 2 for Stereo) */
- uint32_t AudioRecChnlNbr = 1;
- /* Main buffer pointer for the recorded data storing */
- uint16_t* pAudioRecBuf;
- /* Current size of the recorded buffer */
- uint32_t AudioRecCurrSize = 0;
- uint16_t bytesWritten;
- /* Temporary data sample */
- static uint16_t InternalBuffer[INTERNAL_BUFF_SIZE];
- static uint32_t InternalBufferSize = 0;
- /* Private function prototypes -----------------------------------------------*/
- static void WaveRecorder_GPIO_Init(void);
- static void WaveRecorder_SPI_Init(uint32_t Freq);
- static void WaveRecorder_NVIC_Init(void);
- extern FATFS fatfs; /* File system object */
- /* Private functions ---------------------------------------------------------*/
- /**
- * @brief Initialize wave recording
- * @param AudioFreq: Sampling frequency
- * BitRes: Audio recording Samples format (from 8 to 16 bits)
- * ChnlNbr: Number of input microphone channel
- * @retval None
- */
- uint32_t WaveRecorderInit(uint32_t AudioFreq, uint32_t BitRes, uint32_t ChnlNbr)
- {
- /* Check if the interface is already initialized */
-
- /* Enable CRC module */
- RCC->AHBENR |= RCC_AHBENR_CRCEN;
-
- /* Filter LP & HP Init */
- Filter.LP_HZ = 8000;
- Filter.HP_HZ = 10;
- Filter.Fs = 16000;
- Filter.Out_MicChannels = 1;
- Filter.In_MicChannels = 1;
-
- PDM_Filter_Init((PDMFilter_InitStruct *)&Filter);
-
- /* Configure the GPIOs */
- WaveRecorder_GPIO_Init();
-
- /* Configure the interrupts (for timer) */
- WaveRecorder_NVIC_Init();
-
- /* Configure the SPI */
- WaveRecorder_SPI_Init(AudioFreq);
-
- /* Set the local parameters */
- AudioRecBitRes = BitRes;
- AudioRecChnlNbr = ChnlNbr;
-
- /* Set state of the audio recorder to initialized */
-
- /* Return 0 if all operations are OK */
- return 0;
-
- }
- /**
- * @brief Start audio recording
- * @param pbuf: pointer to a buffer
- * size: Buffer size
- * @retval None
- */
- uint8_t WaveRecorderStart(uint16_t* pbuf, uint32_t size)
- {
- /* Check if the interface has already been initialized */
- if (!AudioRecInited)
- {
- /* Store the location and size of the audio buffer */
- pAudioRecBuf = pbuf;
- AudioRecCurrSize = size;
-
- /* Enable the Rx buffer not empty interrupt */
- SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
- /* The Data transfer is performed in the SPI interrupt routine */
- /* Enable the SPI peripheral */
- I2S_Cmd(SPI2, ENABLE);
-
- /* Return 0 if all operations are OK */
- return 0;
- }
- else
- {
- /* Cannot perform operation */
- return 1;
- }
- }
- /**
- * @brief Stop audio recording
- * @param None
- * @retval None
- */
- uint32_t WaveRecorderStop(void)
- {
- /* Check if the interface has already been initialized */
- if (AudioRecInited)
- {
-
- /* Stop conversion */
- I2S_Cmd(SPI2, DISABLE);
-
- /* Return 0 if all operations are OK */
- return 0;
- }
- else
- {
- /* Cannot perform operation */
- return 1;
- }
- }
- /**
- * @brief This function handles AUDIO_REC_SPI global interrupt request.
- * @param None
- * @retval None
- */
- void SPI2_IRQHandler(void)
- {
- u16 volume;
- u16 app;
- /* Check if data are available in SPI Data register */
- if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
- {
-
- app = SPI_I2S_ReceiveData(SPI2);
- InternalBuffer[InternalBufferSize++] = HTONS(app);
-
- /* Check to prevent overflow condition */
- if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
- {
- InternalBufferSize = 0;
-
- volume = 60;
-
- PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume , (PDMFilter_InitStruct *)&Filter);
- Data_Status = 1;
- }
- }
- SPI_I2S_ClearITPendingBit(SPI2,SPI_I2S_IT_RXNE);
- }
- /**
- * @brief Initialize the wave header file
- * @param pHeadBuf:Pointer to a buffer
- * @retval None
- */
- uint32_t WavaRecorderHeaderInit(uint8_t* pHeadBuf)
- {
- uint16_t count = 0;
- /* write chunkID, must be 'RIFF' ------------------------------------------*/
- pHeadBuf[0] = 'R';
- pHeadBuf[1] = 'I';
- pHeadBuf[2] = 'F';
- pHeadBuf[3] = 'F';
- /* Write the file length */
- /* The sampling time 8000 Hz
- To recorde 10s we need 8000 x 10 x 2 (16-Bit data) */
- pHeadBuf[4] = 0x00;
- pHeadBuf[5] = 0xE2;
- pHeadBuf[6] = 0x04;
- pHeadBuf[7] = 0x00;
-
- /* Write the file format, must be 'WAVE' */
- pHeadBuf[8] = 'W';
- pHeadBuf[9] = 'A';
- pHeadBuf[10] = 'V';
- pHeadBuf[11] = 'E';
- /* Write the format chunk, must be'fmt ' */
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
IISchuankou.7z
(218.45 KB, 下载次数: 215)
|