之前我公司的产品I2S用的是 PB13,PB14,PB15,但是PB13引脚是I2S2_CK 与ULPI_D6分时复用的,这样做不能满足要求。
于是我们公司又选用了176引脚的STM32F407IG,这时I2S2_CK 与ULPI_D6就可以分配开了,I2S2_CK 引脚用的是PI1,PI2为I2S_EXT_SD PI3为I2S_SD,
但在实时调试当中,I2S不能接收数据,SPI_I2S_FLAG_RXNE状态位置不了位,
如果把I2S2_CK 配置成PB13 或者PB10就可以接收,SPI_I2S_FLAG_RXNE也可以置位。
这是什么原因?求大神解答。
下面为管脚配置,及I2S配置函数。
******************************************************************************************************
* 函 数 名: I2S_GPIO_Config
* 功能说明: 配置GPIO引脚用于codec应用
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void I2S_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 录音笔WM8978管脚配置
PB9/I2S2_WS
PI1/I2S2_CK
PI2/I2S2ext_SD
PI3/I2S2_SD
PC6/I2S2_MCK
*/
/* 使能SPI2时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* Enable GPIOI, GPIOB, GPIOC clock */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOI, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ; //WS
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 ;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ; //CLK EXT_SD SD
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 ;
GPIO_Init(GPIOI, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ; //MCLK
GPIO_Init(GPIOC, &GPIO_InitStructure);
/* Connect pins to I2S peripheral */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_SPI2); //WS
GPIO_PinAFConfig(GPIOI, GPIO_PinSource1, GPIO_AF_SPI2); //CLK
GPIO_PinAFConfig(GPIOI, GPIO_PinSource2, GPIO_AF_SPI3); /* 注意: PI2连接设置需要是 SPI3 */
GPIO_PinAFConfig(GPIOI, GPIO_PinSource3, GPIO_AF_SPI2); //SD
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2);
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI3); /* 注意: PB14连接设置需要是 SPI3 */
//GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_SPI2); //MCLK
}
/*
*********************************************************************************************************
* 函 数 名: I2S_Config
* 功能说明: 配置STM32的I2S外设工作模式
* 形 参: _usStandard : 接口标准,I2S_Standard_Phillips, I2S_Standard_MSB 或 I2S_Standard_LSB
* _usMCLKOutput : 主时钟输出,I2S_MCLKOutput_Enable or I2S_MCLKOutput_Disable
* _usAudioFreq : 采样频率,I2S_AudioFreq_8K、I2S_AudioFreq_16K、I2S_AudioFreq_22K、
* I2S_AudioFreq_44K、I2S_AudioFreq_48
* _usMode : CPU I2S的工作模式,I2S_Mode_MasterTx、I2S_Mode_MasterRx、
*
* 返 回 值: 无
*********************************************************************************************************
*/
static void I2S_Mode_Config(uint16_t _usStandard, uint16_t _usWordLen, uint32_t _uiAudioFreq, uint16_t _usMode)
{
I2S_InitTypeDef I2S_InitStructure;
if ((_usMode == I2S_Mode_SlaveTx) && (_usMode == I2S_Mode_SlaveRx))
{
/*不支持这2种模式 */
return;
}
/*
For I2S mode, make sure that either:
- I2S PLL is configured using the functions RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S),
RCC_PLLI2SCmd(ENABLE) and RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY).
*/
{
uint32_t n = 0;
FlagStatus status = RESET;
RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);
RCC_PLLI2SCmd(ENABLE);
for (n = 0; n < 500; n++)
{
status = RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY);
if (status == 1)
{
break;
}
}
}
/* 打开 I2S2 APB1 时钟 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
/* 复位 SPI2 外设到缺省状态 */
SPI_I2S_DeInit(SPI2);
//RCC_PLLI2SConfig(213,2); //willow add 20160118 for 录音时钟。
/* I2S2 外设配置 */
//if (_usMode == I2S_Mode_MasterTx)
{
I2S_StructInit(&I2S_InitStructure);
I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; /* 配置I2S工作模式 */
I2S_InitStructure.I2S_Standard = _usStandard; /* 接口标准 */
I2S_InitStructure.I2S_DataFormat = _usWordLen; /* 数据格式,16bit */
I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; /* 主时钟模式 */
I2S_InitStructure.I2S_AudioFreq = _uiAudioFreq; /* 音频采样频率 */
I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
I2S_Init(SPI2, &I2S_InitStructure);
/* Configure the I2Sx_ext (the second instance) in Slave Receiver Mode */
I2S_FullDuplexConfig(I2S2ext, &I2S_InitStructure);
/* 使能 SPI2/I2S2 外设 */
I2S_Cmd(SPI2, ENABLE);
/* Enable the I2Sx_ext peripheral for Full Duplex mode */
I2S_Cmd(I2S2ext, ENABLE);
}
/* 禁止I2S2 TXE中断(发送缓冲区空),需要时再打开 */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_TXE, DISABLE);
/* 禁止I2S2 RXNE中断(接收不空),需要时再打开 */
SPI_I2S_ITConfig(I2S2ext, SPI_I2S_IT_RXNE, DISABLE);
#if 0 /* 这一段代码用于测试I2S双向传输功能 */
while (1)
{
static uint16_t usData;
if (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == SET)
{
SPI_I2S_SendData(SPI2, 0x55);
}
if (SPI_I2S_GetFlagStatus(I2S2ext, SPI_I2S_FLAG_RXNE) == SET)
{
usData = SPI_I2S_ReceiveData(I2S2ext);
printf("%02X ", usData);
}
}
#endif
}
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
1.png (77.17 KB, 下载次数: 0)
下载附件
2016-6-27 15:24 上传
一周热门 更多>