用radio 录音,保存成wav 是否可行
用radio硬件录音,保存成wav 是否可行 STM32的IIS只支持半双工.因此无法同时放音和录音.且RADIO板上面用的WM8978的数据输出不支持设置为三态,因此RADIO的配件并不支持录音.
不过V3的CODEC模块可以单独拆卸.CODEC模块是可以支持线路/MIC输入的.可以接全双工的IIS主机以实现录音. 请教楼上wm8978 录音电路看看是否可行
http://cache.amobbs.com/bbs_upload782111/files_40/ourdev_643648WR9AMH.jpg
想实现的录音部分电路 (原文件名:是否能实现录音.jpg) 又看看资料,上图只能是放音状态,不能录音,因为stm32的i2s是不支持双工的,如果要输入,要把第9脚引出来用模拟开关和第十脚切换,放音时切到10脚,录音切到9脚,这样实现半双工。
还有疑问:用收音机里面的程序初始化后,通过spi3 往wm8978写随机数据,想听听杂音,就是写不进去数据,。
我的初始化函数:
static void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Disable the JTAG interface and enable the SWJ interface */
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
/* PC5 CODEC CS */
GPIO_InitStructure.GPIO_Pin = CODEC_CSB_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(CODEC_CSB_PORT, &GPIO_InitStructure);
// WS
GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
#if CODEC_MASTER_MODE
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
#else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
#endif
GPIO_Init(CODEC_I2S_WS_PORT, &GPIO_InitStructure);
// CK
GPIO_InitStructure.GPIO_Pin = CODEC_I2S_CK_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
#if CODEC_MASTER_MODE
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
#else
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
#endif
GPIO_Init(CODEC_I2S_CK_PORT, &GPIO_InitStructure);
// SD
GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SD_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(CODEC_I2S_SD_PORT, &GPIO_InitStructure);
#ifdef CODEC_USE_MCO
/* MCO configure */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
RCC_MCOConfig(RCC_MCO_HSE);
#endif
}
static void I2S_Configuration(uint32_t I2S_AudioFreq)
{
I2S_InitTypeDef I2S_InitStructure;
/* I2S peripheral configuration */
I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq;
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
/* I2S2 configuration */
#if CODEC_MASTER_MODE
I2S_InitStructure.I2S_Mode = I2S_Mode_SlaveTx;
#else
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
#endif
I2S_Init(CODEC_I2S_PORT, &I2S_InitStructure);
}
uint8_t SPI3_WriteByte(unsigned char data)
{
//Wait until the transmit buffer is empty
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET);
// Send the byte
SPI_I2S_SendData(SPI3, data);
//Wait until a data is received
// while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET);
// // Get the received data
// data = SPI_I2S_ReceiveData(SPI3);
// Return the shifted data
return data;
}
void spi1_configration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
/* Enable SPI1 Periph clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
| RCC_APB2Periph_AFIO | RCC_APB2Periph_SPI1,
ENABLE);
/* Configure SPI1 pins: PA5-SCK, PA6-MISO and PA7-MOSI */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/*------------------------ SPI1 configuration ------------------------*/
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS= SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;/* 72M/64=1.125M */
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_I2S_DeInit(SPI1);
SPI_Init(SPI1, &SPI_InitStructure);
/* Enable SPI_MASTER */
SPI_Cmd(SPI1, ENABLE);
SPI_CalculateCRC(SPI1, DISABLE);
}
uint8_t SPI1_WriteByte(unsigned char data)
{
//Wait until the transmit buffer is empty
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
// Send the byte
SPI_I2S_SendData(SPI1, data);
//Wait until a data is received
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
// Get the received data
data = SPI_I2S_ReceiveData(SPI1);
// Return the shifted data
return data;
}
static void codec_send(rt_uint16_t s_data)
{
// rt_sem_take(&spi1_lock, RT_WAITING_FOREVER);
/* SPI1 configure */
// rt_hw_spi2_baud_rate(SPI_BaudRatePrescaler_64);/* 72M/64=1.125M */
SPI1->CR1 &= ~SPI_BaudRatePrescaler_256;
SPI1->CR1 |= SPI_BaudRatePrescaler_64;
codec_reset_csb();
SPI1_WriteByte((s_data >> 8) & 0xFF);
SPI1_WriteByte(s_data & 0xFF);
codec_set_csb();
// rt_sem_release(&spi1_lock);
}
static rt_err_t codec_init(rt_device_t dev)
{
spi1_configration();
codec_send(REG_SOFTWARE_RESET);
// 1.5x boost power up sequence.
// Mute all outputs.
// codec_send(REG_LOUT1_VOL | LOUT1MUTE);
// codec_send(REG_ROUT1_VOL | ROUT1MUTE);
// codec_send(REG_LOUT2_VOL | LOUT2MUTE);
// codec_send(REG_ROUT2_VOL | ROUT2MUTE);
// Enable unused output chosen from L/ROUT2, OUT3 or OUT4.
codec_send(REG_POWER_MANAGEMENT3 | OUT4EN);
// Set BUFDCOPEN=1 and BUFIOEN=1 in register R1
codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN);
// Set SPKBOOST=1 in register R49.
codec_send(REG_OUTPUT | SPKBOOST);
// Set VMIDSEL to required value in register R1.
codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
// Set L/RMIXEN=1 and DACENL/R=1 in register R3.
codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR);
// Set BIASEN=1 in register R1.
codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN);
// Set L/ROUT2EN=1 in register R3.
codec_send(REG_POWER_MANAGEMENT3 | LMIXEN | RMIXEN | DACENL | DACENR | LOUT2EN | ROUT2EN);
// Enable other mixers as required.
// Enable other outputs as required.
codec_send(REG_POWER_MANAGEMENT2 | LOUT1EN | ROUT1EN | BOOSTENL | BOOSTENR | INPPGAENL | INPPGAENR);
// Digital inferface setup.
codec_send(REG_AUDIO_INTERFACE | BCP_NORMAL | LRP_NORMAL | WL_16BITS | FMT_I2S);
// PLL setup.
// fs = 44.1KHz * 256fs = 11.2896MHz
// F_PLL = 11.2896MHz * 4 * 2 = 90.3168MHz
// R = 90.3168MHz / 12.288MHz = 7.35
// PLL_N = 7
// PLL_K = 0x59999A (0x5A5A5A for STM32's 44.117KHz fs generated from 72MHz clock)
codec_send(REG_PLL_N | 7);
#if CODEC_MASTER_MODE
codec_send(REG_PLL_K1 | 0x16);
codec_send(REG_PLL_K2 | 0xCC);
codec_send(REG_PLL_K3 | 0x19A);
#else
codec_send(REG_PLL_K1 | 0x16);
codec_send(REG_PLL_K2 | 0x12D);
codec_send(REG_PLL_K3 | 0x5A);
#endif
codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K | BIASEN | PLLEN);
codec_send(r06);
// Enable DAC 128x oversampling.
codec_send(REG_DAC | DACOSR128);
// Set LOUT2/ROUT2 in BTL operation.
codec_send(REG_BEEP | INVROUT2);
// Set output volume.
vol(25);
return RT_EOK;
}
void spi3_test(void)
{
u32 i;
vol(80);
I2S_Cmd(CODEC_I2S_PORT, ENABLE);
for(i=0;i<1000;i++)
{
SPI3_WriteByte(i);
}
}
最后是调用
while(1)
{
spi3_test();
rt_thread_delay(10);
} 思路是用spi1 配置wm8978 ,用i2s3来送数据,现在是pb3 和pa15 没有波形,pb3一直是高电平,pa15一直低电平,
参考 这个网站 http://bbs.21ic.com/icview-111525-1-1.html,上面说有波形输出的,不知道是我的设置有问题还是硬件问题,我的两个硬件都是一样,哪位能帮我判断下是哪里问题 1.给SPI上面挂个逻辑分析仪,确认命令是有正确发送出去.
2.冷上电后.VMID,VMIC都是没电的.正常接收
codec_send(REG_POWER_MANAGEMENT1 | BUFDCOPEN | BUFIOEN | VMIDSEL_75K);
这个命令后,VMID会输出电压 1/2vcc.
(不确认是这条,大概是这条,最好单步测反应)
页:
[1]