学前班
最后登录1970-1-1
在线时间 小时
注册时间2016-5-12
|
大家有没有STM32H743的SAI4的例子啊
/**********************SAI4配置信息******************************/
//SAI Block A初始化,I2S,飞利浦标准
//mode:工作模式,可以设置:SAI_MODEMASTER_TX/SAI_MODEMASTER_RX/SAI_MODESLAVE_TX/SAI_MODESLAVE_RX
//cpol:数据在时钟的上升/下降沿选通,可以设置:SAI_CLOCKSTROBING_FALLINGEDGE/SAI_CLOCKSTROBING_RISINGEDGE
//datalen:数据大小,可以设置:SAI_DATASIZE_8/10/16/20/24/32
void SAI4A_Init(u32 mode,u32 cpol,u32 datalen)
{
HAL_SAI_DeInit(&SAI4A_Handler); //清除以前的配置
SAI4A_Handler.Instance=SAI4_Block_A; //SAI4 Bock A
SAI4A_Handler.Init.AudioMode=SAI_MODESLAVE_RX; //设置SAI4工作模式
SAI4A_Handler.Init.Synchro=SAI_SYNCHRONOUS_EXT_SAI1; //音频模块异步
SAI4A_Handler.Init.OutputDrive=SAI_OUTPUTDRIVE_ENABLE; //立即驱动音频模块输出
SAI4A_Handler.Init.NoDivider=SAI_MASTERDIVIDER_ENABLE; //使能主时钟分频器(MCKDIV)
SAI4A_Handler.Init.FIFOThreshold=SAI_FIFOTHRESHOLD_1QF; //设置FIFO阈值,1/4 FIFO
SAI4A_Handler.Init.MonoStereoMode=SAI_STEREOMODE; //立体声模式
SAI4A_Handler.Init.Protocol=SAI_FREE_PROTOCOL; //设置SAI1协议为:自由协议(支持I2S/LSB/MSB/TDM/PCM/DSP等协议)
SAI4A_Handler.Init.DataSize=SAI_DATASIZE_16; //设置数据大小
SAI4A_Handler.Init.FirstBit=SAI_FIRSTBIT_MSB; //数据MSB位优先
SAI4A_Handler.Init.ClockStrobing=SAI_CLOCKSTROBING_RISINGEDGE; //数据在时钟的上升/下降沿选通
//帧设置
SAI4A_Handler.FrameInit.FrameLength=32; //设置帧长度为32,左通道16个SCK,右通道16个SCK.
SAI4A_Handler.FrameInit.ActiveFrameLength=16; //设置帧同步有效电平长度,在I2S模式下=1/2帧长.
SAI4A_Handler.FrameInit.FSDefinition=SAI_FS_CHANNEL_IDENTIFICATION;//FS信号为SOF信号+通道识别信号
SAI4A_Handler.FrameInit.FSPolarity=SAI_FS_ACTIVE_LOW; //FS低电平有效(下降沿)
SAI4A_Handler.FrameInit.FSOffset=SAI_FS_BEFOREFIRSTBIT; //在slot0的第一位的前一位使能FS,以匹配飞利浦标准
//SLOT设置
SAI4A_Handler.SlotInit.FirstBitOffset=0; //slot偏移(FBOFF)为0
SAI4A_Handler.SlotInit.SlotSize=SAI_SLOTSIZE_16B; //slot大小为16位
SAI4A_Handler.SlotInit.SlotNumber=2; //slot数为2个
SAI4A_Handler.SlotInit.SlotActive=SAI_SLOTACTIVE_0|SAI_SLOTACTIVE_1;//使能slot0和slot1
HAL_SAI_Init(&SAI4A_Handler); //初始化SAI
SAI4A_DMA_Enable(); //使能SAI的DMA功能
__HAL_SAI_ENABLE(&SAI4A_Handler); //使能SAI
}
//SAI Block B初始化,I2S,飞利浦标准
//mode:工作模式,可以设置:SAI_MODEMASTER_TX/SAI_MODEMASTER_RX/SAI_MODESLAVE_TX/SAI_MODESLAVE_RX
//cpol:数据在时钟的上升/下降沿选通,可以设置:SAI_CLOCKSTROBING_FALLINGEDGE/SAI_CLOCKSTROBING_RISINGEDGE
//datalen:数据大小,可以设置:SAI_DATASIZE_8/10/16/20/24/32
void SAI4B_Init(u32 mode,u32 cpol,u32 datalen)
{
HAL_SAI_DeInit(&SAI4B_Handler); //清除以前的配置
SAI4B_Handler.Instance=SAI4_Block_B; //SAI4 Bock B
SAI4B_Handler.Init.AudioMode=SAI_MODESLAVE_RX; //设置SAI4工作模式
SAI4B_Handler.Init.Synchro=SAI_SYNCHRONOUS_EXT_SAI1; //音频模块同步
SAI4B_Handler.Init.OutputDrive=SAI_OUTPUTDRIVE_ENABLE; //立即驱动音频模块输出
SAI4B_Handler.Init.NoDivider=SAI_MASTERDIVIDER_ENABLE; //使能主时钟分频器(MCKDIV)
SAI4B_Handler.Init.FIFOThreshold=SAI_FIFOTHRESHOLD_1QF; //设置FIFO阈值,1/4 FIFO
SAI4B_Handler.Init.MonoStereoMode=SAI_STEREOMODE; //立体声模式
SAI4B_Handler.Init.Protocol=SAI_FREE_PROTOCOL; //设置SAI1协议为:自由协议(支持I2S/LSB/MSB/TDM/PCM/DSP等协议)
SAI4B_Handler.Init.DataSize=SAI_DATASIZE_16; //设置数据大小
SAI4B_Handler.Init.FirstBit=SAI_FIRSTBIT_MSB; //数据MSB位优先
SAI4B_Handler.Init.ClockStrobing=SAI_CLOCKSTROBING_RISINGEDGE;//数据在时钟的上升/下降沿选通
//帧设置
SAI4B_Handler.FrameInit.FrameLength=32; //设置帧长度为32,左通道16个SCK,右通道16个SCK.
SAI4B_Handler.FrameInit.ActiveFrameLength=16; //设置帧同步有效电平长度,在I2S模式下=1/2帧长.
SAI4B_Handler.FrameInit.FSDefinition=SAI_FS_CHANNEL_IDENTIFICATION;//FS信号为SOF信号+通道识别信号
SAI4B_Handler.FrameInit.FSPolarity=SAI_FS_ACTIVE_LOW; //FS低电平有效(下降沿)
SAI4B_Handler.FrameInit.FSOffset=SAI_FS_BEFOREFIRSTBIT; //在slot0的第一位的前一位使能FS,以匹配飞利浦标准
//SLOT设置
SAI4B_Handler.SlotInit.FirstBitOffset=0; //slot偏移(FBOFF)为0
SAI4B_Handler.SlotInit.SlotSize=SAI_SLOTSIZE_16B; //slot大小为16位
SAI4B_Handler.SlotInit.SlotNumber=2; //slot数为2个
SAI4B_Handler.SlotInit.SlotActive=SAI_SLOTACTIVE_0|SAI_SLOTACTIVE_1;//使能slot0和slot1
HAL_SAI_Init(&SAI4B_Handler);
SAI4B_DMA_Enable(); //使能SAI的DMA功能
__HAL_SAI_ENABLE(&SAI4B_Handler); //使能SAI
}
//开启SAI的DMA功能,HAL库没有提供此函数
//因此我们需要自己操作寄存器编写一个
void SAI4A_DMA_Enable(void)
{
u32 tempreg=0;
tempreg=SAI4_Block_A->CR1; //先读出以前的设置
tempreg|=1<<17; //使能DMA
SAI4_Block_A->CR1=tempreg; //写入CR1寄存器中
}
//开启SAIB的DMA功能,HAL库没有提供此函数
//因此我们需要自己操作寄存器编写一个
void SAI4B_DMA_Enable(void)
{
u32 tempreg=0;
tempreg=SAI4_Block_B->CR1; //先读出以前的设置
tempreg|=1<<17; //使能DMA
SAI4_Block_B->CR1=tempreg; //写入CR1寄存器中
}
//SAIA TX DMA配置
//设置为双缓冲模式,并开启DMA传输完成中断
//buf0:M0AR地址.
//buf1:M1AR地址.
//num:每次传输数据量
//width:位宽(存储器和外设,同时设置),0,8位;1,16位;2,32位;
void SAI4A_RX_DMA_Init(u8* buf0,u8 *buf1,u16 num,u8 width)
{
u32 memwidth=0,perwidth=0; //外设和存储器位宽
switch(width)
{
case 0: //8位
memwidth=DMA_MDATAALIGN_BYTE;
perwidth=DMA_PDATAALIGN_BYTE;
break;
case 1: //16位
memwidth=DMA_MDATAALIGN_HALFWORD;
perwidth=DMA_PDATAALIGN_HALFWORD;
break;
case 2: //32位
memwidth=DMA_MDATAALIGN_WORD;
perwidth=DMA_PDATAALIGN_WORD;
break;
}
__HAL_RCC_BDMA_CLK_ENABLE(); //使能BDMA时钟
__HAL_LINKDMA(&SAI4A_Handler,hdmarx,SAI4A_RXDMA_Handler); //将DMA与SAI联系起来
SAI4A_RXDMA_Handler.Init.Request= BDMA_REQUEST_SAI4_A;
SAI4A_RXDMA_Handler.Instance=BDMA_Channel0; //DMA2数据流3
SAI4A_RXDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //存储器到外设模式
SAI4A_RXDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
SAI4A_RXDMA_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
SAI4A_RXDMA_Handler.Init.PeriphDataAlignment=perwidth; //外设数据长度:16/32位
SAI4A_RXDMA_Handler.Init.MemDataAlignment=memwidth; //存储器数据长度:16/32位
SAI4A_RXDMA_Handler.Init.Mode=DMA_CIRCULAR; //使用循环模式
SAI4A_RXDMA_Handler.Init.Priority=DMA_PRIORITY_HIGH; //高优先级
SAI4A_RXDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE; //不使用FIFO
SAI4A_RXDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器单次突发传输
SAI4A_RXDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
HAL_DMA_DeInit(&SAI4A_RXDMA_Handler); //先清除以前的设置
HAL_DMA_Init(&SAI4A_RXDMA_Handler); //初始化DMA
HAL_NVIC_SetPriority(BDMA_Channel0_IRQn,2,0); //DMA中断优先级
HAL_NVIC_EnableIRQ(BDMA_Channel0_IRQn);
HAL_DMA_Start_IT(&SAI4A_RXDMA_Handler,(u32)&SAI4_Block_A->DR,(u32)buf0,200);
}
//SA2A TX DMA配置
//设置为双缓冲模式,并开启DMA传输完成中断
//buf0:M0AR地址.
//buf1:M1AR地址.
//num:每次传输数据量
//width:位宽(存储器和外设,同时设置),0,8位;1,16位;2,32位;
void SAI4B_RX_DMA_Init(u8* buf0,u8 *buf1,u16 num,u8 width)
{
u32 memwidth=0,perwidth=0; //外设和存储器位宽
switch(width)
{
case 0: //8位
memwidth=DMA_MDATAALIGN_BYTE;
perwidth=DMA_PDATAALIGN_BYTE;
break;
case 1: //16位
memwidth=DMA_MDATAALIGN_HALFWORD;
perwidth=DMA_PDATAALIGN_HALFWORD;
break;
case 2: //32位
memwidth=DMA_MDATAALIGN_WORD;
perwidth=DMA_PDATAALIGN_WORD;
break;
}
__HAL_RCC_BDMA_CLK_ENABLE(); //使能DMA2时钟
__HAL_LINKDMA(&SAI4B_Handler,hdmarx,SAI4B_RXDMA_Handler); //将DMA与SAI联系起来
SAI4B_RXDMA_Handler.Init.Request= BDMA_REQUEST_SAI4_B;
SAI4B_RXDMA_Handler.Instance=BDMA_Channel1; //DMA2数据流6
SAI4B_RXDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到存储器模式
SAI4B_RXDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
SAI4B_RXDMA_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
SAI4B_RXDMA_Handler.Init.PeriphDataAlignment=memwidth; //外设数据长度:16/32位
SAI4B_RXDMA_Handler.Init.MemDataAlignment=perwidth; //存储器数据长度:16/32位
SAI4B_RXDMA_Handler.Init.Mode=DMA_CIRCULAR; //使用循环模式
SAI4B_RXDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM; //中等优先级
SAI4B_RXDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE; //不使用FIFO
SAI4B_RXDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器单次突发传输
SAI4B_RXDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
HAL_DMA_DeInit(&SAI4B_RXDMA_Handler); //先清除以前的设置
HAL_DMA_Init(&SAI4B_RXDMA_Handler); //初始化DMA
HAL_NVIC_SetPriority(BDMA_Channel1_IRQn,1,3); //DMA中断优先级
HAL_NVIC_EnableIRQ(BDMA_Channel1_IRQn);
HAL_DMA_Start_IT(&SAI4B_RXDMA_Handler,(u32)&SAI4_Block_B->DR,(u32)buf0,200);
}
|
|