void I2S_Init(void)
{ uint32_t u32RxValue1, u32RxValue2;
/* SPI1选择PCLK1作为时钟源,默认PCLK1的时钟等于HCLK的时钟 */
CLK_SetModuleClock(SPI1_MODULE, CLK_CLKSEL2_SPI1SEL_PCLK1, MODULE_NoMsk);
/* 使能SPI1的时钟 */
CLK_EnableModuleClock(SPI1_MODULE);
/* 配置 SPI1 相关引脚 */
/* GPA[7:4] : SPI1_CLK (I2S1_BCLK), SPI1_MISO (I2S1_DI), SPI1_MOSI (I2S1_DO), SPI1_SS (I2S1_LRCLK) */
SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA4MFP_Msk | SYS_GPA_MFPL_PA5MFP_Msk |
SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
SYS->GPA_MFPL |= (SYS_GPA_MFPL_PA4MFP_SPI1_SS | SYS_GPA_MFPL_PA5MFP_SPI1_MOSI | SYS_GPA_MFPL_PA6MFP_SPI1_MISO | SYS_GPA_MFPL_PA7MFP_SPI1_CLK);
/* I2S1使用SPI1接口,配置为16bit, Stereo,I2S format,使能TX和RX FIFO threshold中断,连续发送数据0xAA00AA01, 0xAA02AA03, ..., 0xAAFEAAFF 每个发送5000次,然后改变TX的值*/
/* I2S 外设时钟频率等于 PCLK1 的时钟频率 */
I2S_Open(SPI1, I2S_MODE_SLAVE, 0, I2S_DATABIT_16, I2S_STEREO, I2S_FORMAT_I2S);
/* 初始化发送数据计数 */
g_u32DataCount = 0;
/* 初始化发送/接收数据 */
g_u32TxValue = 0xAA00AA01; u32RxValue1 = 0; u32RxValue2 = 0;
/* 使能TX/RX threshold 中断 */
I2S_EnableInt(SPI1, I2S_FIFO_TXTH_INT_MASK| I2S_FIFO_RXTH_INT_MASK);
NVIC_EnableIRQ(SPI1_IRQn);
while(1)
{
/* 改变要发送的数据 */
if(g_u32DataCount >= 50000)
{
g_u32TxValue = 0xAA00AA00 | ((g_u32TxValue + 0x00020002) & 0x00FF00FF); /* g_u32TxValue: 0xAA00AA01, 0xAA02AA03, ..., 0xAAFEAAFF */ printf("TX value: 0x%X\n", g_u32TxValue); g_u32DataCount = 0;
}
}
} uint32_t g_au32PcmRecBuf[96];
/*I2S1 中断处理函数*/
void SPI1_IRQHandler()
{ uint32_t u32I2SIntFlag; uint32_t i, u32Idx;
u32I2SIntFlag = SPI1->I2SSTS; /*发生Tx Threshold中断*/ if(u32I2SIntFlag & SPI_I2SSTS_TXTHIF_Msk)
{
/* 写2 笔TX 值到 TX FIFO */
I2S_WRITE_TX_FIFO(SPI1, g_u32TxValue); I2S_WRITE_TX_FIFO(SPI1, g_u32TxValue); g_u32DataCount += 2;
}
/*发生Rx Threshold中断*/ if(u32I2SIntFlag & SPI_I2SSTS_RXTHIF_Msk)
{ g_au32PcmRecBuf[g_u32RecPos++] = I2S_READ_RX_FIFO(SPI1); g_au32PcmRecBuf[g_u32RecPos++] = I2S_READ_RX_FIFO(SPI1); if(g_u32RecPos >= 96) g_u32RecPos = 0;
}
}
上面的代码在M451SeriesBSP_CMSIS_v3.00.005里面,SampleCode\StdDriver\I2S_Slave目录下。 上面的demo,通过I2S发送一些数据出去,就是说I2S不一定非得传输音频数据,也可以拿来单纯的传输数据用。通过RX收到的数据我们也没有做进一步的处理,只是放在变量g_au32PcmRecBuf中。如果做USB声卡应用,g_au32PcmRecBuf里面的数据可以通过USB发送到PC上。
|