久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费
標(biāo)題:
STM32單片機(jī)實現(xiàn)IIS音頻采集,串口助手接收
[打印本頁]
作者:
hanabisama
時間:
2019-3-19 13:57
標(biāo)題:
STM32單片機(jī)實現(xiàn)IIS音頻采集,串口助手接收
上周搞了個IIS的麥克風(fēng),用32做個音頻采集,把數(shù)據(jù)發(fā)往電腦,處理后可保存為wav格式,具體處理方式可查看wav格式的頭文件。
單片機(jī)源程序如下:
#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復(fù)用輸出
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);
}
//音頻數(shù)據(jù)低通濾波
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一次通道數(shù)據(jù)獲取搬運(yùn)完成
if (DMA_GetITStatus(DMA1_IT_TC4))
{
DMA_Cmd(DMA1_Channel4, DISABLE);
T16T12(); //24位轉(zhuǎn)12位函數(shù)
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初始化結(jié)構(gòu)體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; //外設(shè)地址
DMA_InitStructure.DMA_MemoryBaseAddr =(uint32_t)Rx_buffer; //內(nèi)存地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize =64; //DMA緩存大小:BufferSize
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外設(shè)地址寄存器不遞增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //內(nèi)存地址寄存器遞增
DMA_InitStructure.DMA_PeripheralDataSize =DMA_PeripheralDataSize_Word ; //外設(shè)數(shù)據(jù)寬度
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Word ; //內(nèi)存數(shù)據(jù)寬度
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在正常緩存模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; //設(shè)置DMA通道優(yōu)先級為高
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //禁止DMA通道設(shè)置為內(nèi)存至內(nèi)存?zhèn)鬏?
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一次通道數(shù)據(jù)獲取搬運(yùn)完成
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)
{
}
}
復(fù)制代碼
/* 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黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
IISchuankou.7z
(218.45 KB, 下載次數(shù): 215)
2019-3-19 16:37 上傳
點擊文件名下載附件
IIS串口傳輸
下載積分: 黑幣 -5
作者:
admin
時間:
2019-3-19 16:38
樓主能分享下原理圖嗎?
作者:
sheepppppp2
時間:
2019-3-19 16:59
好東西,感謝分享!!
作者:
hanabisama
時間:
2019-3-19 20:50
沒原理圖,用的開發(fā)板,買的mems麥克風(fēng)做音頻采集,音頻處理部分在電腦做的,這里只是采集,如果有誰對PDM軟解在行的也教教我。
作者:
嗯。。。。
時間:
2019-8-6 11:12
你好,想問一下,STM32F767可以用你的這種方法進(jìn)行音頻采集嗎?能不能簡單指教一下,
作者:
MLTcola
時間:
2020-3-8 15:27
樓主,我想請教一下您關(guān)于音頻傳輸?shù)诫娔X的問題
作者:
billaj
時間:
2020-3-9 21:57
厲害了樓主,我現(xiàn)在就在頭疼這個I2S,還有SPDIF,頭發(fā)開始掉了。。。
作者:
待續(xù)lin
時間:
2020-5-21 15:23
感謝分享,謝謝樓主
作者:
zaikaolu
時間:
2020-9-18 21:01
請問stmf103c8t6可以么
作者:
金鐘趙
時間:
2021-2-17 10:55
您好,請問下,這個錄音數(shù)據(jù)的格式可以設(shè)置為32位雙聲道嗎?
作者:
小白kd
時間:
2021-3-30 10:32
你好樓主 最近在做stm32用iis傳輸音頻數(shù)據(jù),可以
指導(dǎo)一二嗎
作者:
陽光小子11
時間:
2021-10-19 15:00
你好樓主,我最近也在做用STM32做音頻采集,我想請問下你用的MEMS麥克風(fēng)型號和是使用的STM43F4開發(fā)板嘛?
作者:
fengzi2021
時間:
2021-11-11 21:46
歇息分享,想問下可以如何調(diào)整音量,在錄制時
歡迎光臨 (http://www.zg4o1577.cn/bbs/)
Powered by Discuz! X3.1
主站蜘蛛池模板:
久久精品二区
|
日韩视频在线一区二区
|
国产一级一级毛片
|
国产精品久久久久久久久久久免费看
|
九九av
|
久久精品国产久精国产
|
中文字幕高清av
|
欧美性大战久久久久久久蜜臀
|
日韩欧美国产精品综合嫩v 一区中文字幕
|
一区二区在线免费观看视频
|
精品国产视频
|
久久久久久国产精品久久
|
亚洲视频三
|
黄色操视频
|
视频在线一区
|
日韩国产中文字幕
|
成人妇女免费播放久久久
|
91九色视频在线
|
国产精品欧美一区二区三区不卡
|
日韩一二三区
|
亚洲电影成人
|
99亚洲精品
|
三级在线免费
|
www.日本国产
|
久久久久网站
|
精品久久一区
|
久久www免费视频
|
免费成人高清在线视频
|
欧美精品综合
|
伊人网站在线观看
|
伊人久久综合影院
|
久久91av
|
久久久久国产精品
|
亚洲成av人片在线观看无码
|
欧美久久久久
|
欧美中文一区
|
观看av
|
色综合久
|
一区二区视频在线
|
成人免费淫片aa视频免费
|
91久久看片
|