[3]<<0; //设置I2SDIV
tempreg|=I2S_PSC_TBL[4]<<8; //设置ODD位
tempreg|=1<<9; //使能MCKOE位,输出MCK
SPI2->I2SPR=tempreg; //设置I2SPR寄存器
return 0;
}
//I2S2 TX DMA配置
//设置为双缓冲模式,并开启DMA传输完成中断
//buf0:M0AR地址.
//buf1:M1AR地址.
//num:每次传输数据量
void I2S2_TX_DMA_Init(u8* buf0,u8 *buf1,u16 num)
{
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_LINKDMA(&I2S_Handle,hdmatx,I2S_TxDMA_Handle);
I2S_TxDMA_Handle.Instance=DMA1_Stream4;
I2S_TxDMA_Handle.Init.Channel=DMA_CHANNEL_0;
I2S_TxDMA_Handle.Init.Direction=DMA_MEMORY_TO_PERIPH;
I2S_TxDMA_Handle.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
I2S_TxDMA_Handle.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_1QUARTERFULL;
I2S_TxDMA_Handle.Init.MemBurst=DMA_MBURST_SINGLE;
I2S_TxDMA_Handle.Init.MemDataAlignment=DMA_MDATAALIGN_HALFWORD;
I2S_TxDMA_Handle.Init.MemInc=DMA_MINC_ENABLE;
I2S_TxDMA_Handle.Init.Mode=DMA_CIRCULAR;
I2S_TxDMA_Handle.Init.PeriphBurst=DMA_PBURST_SINGLE;
I2S_TxDMA_Handle.Init.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD;
I2S_TxDMA_Handle.Init.PeriphInc=DMA_PINC_DISABLE;
I2S_TxDMA_Handle.Init.Priority=DMA_PRIORITY_HIGH;
HAL_DMA_DeInit(&I2S_TxDMA_Handle); //先清除以前的设置
HAL_DMA_Init(&I2S_TxDMA_Handle); //初始化DMA
HAL_DMAEx_MultiBufferStart(&I2S_TxDMA_Handle,(u32)buf0,(u32)&SPI2->DR,(u32)buf1,num);//开启双缓冲
__HAL_DMA_DISABLE(&I2S_TxDMA_Handle); //先关闭DMA
__HAL_DMA_ENABLE_IT(&I2S_TxDMA_Handle,DMA_IT_TC); //开启传输完成中断
__HAL_DMA_CLEAR_FLAG(&I2S_TxDMA_Handle,DMA_FLAG_TCIF0_4); //清除DMA传输完成中断标志位
HAL_NVIC_SetPriority(DMA1_Stream4_IRQn,0,0); //DMA中断优先级
HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn);
}
//I2S DMA回调函数指针
void (*i2s_tx_callback)(void); //TX回调函数
//DMA1_Stream4中断服务函数
void DMA1_Stream4_IRQHandler(void)
{
/* __HAL_DMA_GET_FLAG(xxx)!=RESET时可以正常工作
__HAL_DMA_GET_FLAG(xxx)==SET时无法正常工作
库文件stm32f4xx_hal_dma.h中说明了FLAG的状态是SET or RESET
The state of FLAG (SET or RESET)
很奇怪!!!
*/
if(__HAL_DMA_GET_FLAG(&I2S_TxDMA_Handle,DMA_FLAG_TCIF0_4)!=RESET)DMA1_Stream4,传输完成标志
{
__HAL_DMA_CLEAR_FLAG(&I2S_TxDMA_Handle,DMA_FLAG_TCIF0_4); //清除DMA传输完成中断标志位
i2s_tx_callback(); //执行回调函数,读取数据等操作在这里面处理
}
}
//I2S开始播放
void I2S_Play_Start(void)
{
__HAL_DMA_ENABLE(&I2S_TxDMA_Handle);//开启DMA TX传输,开始播放
}
//关闭I2S播放
void I2S_Play_Stop(void)
{
__HAL_DMA_DISABLE(&I2S_TxDMA_Handle);//关闭DMA,结束播放
}
[/mw_shl_code]