注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
深度迷茫的个人空间 https://home.eeworld.com.cn/space-uid-397487.html [收藏] [复制] [分享] [RSS]
日志

记录 STM32的I2S+ADAU7002+HOSIDEN的MIC

热度 1已有 2355 次阅读2019-11-17 18:22

最近自己玩的,手上有个MIC,打算玩一玩。
MIC是PDM输出,所有选了一个PDM转I2S的芯片(ADAU7002),话说这个芯片是WLCSP封装,特别不好焊,我买了两个,焊废了一个。
单片机是STM32F302CBT6,选了半天就这个便宜还有I2S接口,而且自带FPU。
原理图就是用的手册上的典型应用。
打算实现的功能是这样的,单片机I2S采集1024个数据,然后对数据进行FFT,FFT的结果可以送到串口输出或做其他处理。
I2S接收数据用的循环查询,没用中断和DMA,开始打算用DMA,跑起来的时候单片机会进硬件错误中断,没找到原因,就放下了,查询一遍的程序运行时间大概6.7us,算7us,两个声道就是14us,算15us,这样最大接收速率66K,满足一般音频48K采样率的要求。
存在一个大问题:由于我只有一个MIC,只有左声道或右声道,但是接收的数据里左右声道的数据虽然有差异,但很小,几乎可以忽略不计,一直找不到原因,怀疑是PDM转I2S这个过程的问题。
软件上,FFT用的官方库,就是Keil->Manage Run-Time Environment窗口->CMSIS->DSP勾选就OK了,程序要#include "arm_math.h"。I2S的初始化用CubeMx。
主要程序如下:
#define ARM_MATH_CM4
//#include "core_cm3.h"
#define __STATIC_INLINE static __inline
#define __CLZ                             __clz
#define __SSAT                            __ssat
#include "stm32f302xc.h"
#include "arm_math.h"
#define NPT  1024  //1024点FFT
#define Fs 8000 //音频采样率
#define PI2 6.28318530717959
float  testOutput_f32[NPT];
float  testOutput[NPT];
float  testInput_f[NPT];
uint8_t I2S_DMA_CMPLX;

short testInput_sl[NPT];
short testInput_sr[NPT];

void arm_rfft_fast_f32_app(float32_t *testInput_f);
extern I2S_HandleTypeDef hi2s2;
extern DMA_HandleTypeDef hdma_spi2_rx;

void FFTThread (void const *argument) {
I2S_DMA_CMPLX=0;
uint16_t data;
uint16_t lc=0,rc=0;
//hi2s2.Instance->CR2|= 0x00020;//CR2->RXDMAEN=1;
//hi2s2.Instance->CR2 |= 0x0040;//CR2->RXNEIE=1;
//hi2s2.Instance->I2SCFGR&= 0xFBFF;// I2SCFGR->I2SE=0;
hi2s2.Instance->I2SCFGR|= 0x0400;// I2SCFGR->I2SE=1;
while(1){
while(1)
{
while(!(hi2s2.Instance->SR & 0x01));
data = hi2s2.Instance->DR;
if(!(hi2s2.Instance->SR & 0x04))
{    
testInput_sr[rc++] = data;
}
else
{
testInput_sl[lc++] = data;
}
if((lc>=NPT)||(rc>=NPT))
{
//// HAL_UART_Transmit( &huart1, (unsigned char*)&testInput_f32.c, 1024*4,60000);
lc=0;rc=0;
break;
}
// osDelay(1);
// }
// for(i=0;i<512;i++)
// {
// HAL_UART_Transmit( &huart1, (unsigned char*)&testInput_f32.c[i*8+4], 4,60000);
// }
// i=0;
}
// HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)&testInput_f32.s,NPT*2);
for(data=0;data<NPT;data++)
{//这里假设音频最大电压3000mV
testInput_f[data] = testInput_sr[data]*(3000.0/0xffff);
}
arm_rfft_fast_f32_app(testInput_f); 
for(data=0;data<NPT;data++)
{
testInput_f[data] = testInput_sl[data]*(3000.0/0xffff);
}
arm_rfft_fast_f32_app(testInput_f); 
osThreadYield ();   // suspend thread
}
}


void arm_rfft_fast_f32_app(float32_t *testInput_f) 
  uint16_t i; 
char buf[20];
  arm_rfft_fast_instance_f32 S; 

  uint16_t fftSize = NPT;  
    uint8_t ifftFlag = 0;  

   arm_rfft_fast_init_f32(&S, fftSize); 

//  for(i=0; i<1024; i++) 
//  { 
//    /*3??? 50Hz 2500Hz 2550Hz */ 
//    testInput_f[i] = //1000*arm_sin_f32(PI2*i*50.0/Fs) + 
//               //2000*arm_sin_f32(PI2*i*1000.0/Fs)  + 
//               3000*arm_sin_f32(PI2*i*1000.0/Fs); 
//  } 

  arm_rfft_fast_f32(&S, testInput_f, testOutput_f32, ifftFlag); 

   arm_cmplx_mag_f32(testOutput_f32, testOutput, fftSize); 

testOutput[0]=testOutput[0]/fftSize;
// sprintf(buf,"%f\r\n", testOutput[0]); 
// USART1_send_string(buf);
for(i=1; i<fftSize/2; i++) 
  { 
testOutput[i]=testOutput[i]/(fftSize/2);
//    sprintf(buf,"%f\r\n", testOutput[i]); 
// USART1_send_string(buf);
  }
// while(1);
}

发表评论 评论 (1 个评论)
回复 leitianyu 2020-12-2 13:44
想问一下ADAU7002时钟端口是怎么连的,需要电阻分压吗

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章