初级会员

- 积分
- 91
- 金钱
- 91
- 注册时间
- 2019-8-31
- 在线时间
- 24 小时
|
3金钱
下面第一部分是F767的接口配置,参照的原子哥例程
void SAIA_Init(u32 mode,u32 cpol,u32 datalen)
{
HAL_SAI_DeInit(&SAI1A_Handler); /**< 清除以前的配置 */
SAI1A_Handler.Instance=SAI1_Block_A; /**< SAI1 Bock A */
SAI1A_Handler.Init.AudioMode=mode; /**< 设置SAI1工作模式 */
SAI1A_Handler.Init.Synchro=SAI_ASYNCHRONOUS; /**< 音频模块异步 */
SAI1A_Handler.Init.OutputDrive=SAI_OUTPUTDRIVE_ENABLE; /**< 立即驱动音频模块输出 */
SAI1A_Handler.Init.NoDivider=SAI_MASTERDIVIDER_ENABLE; /**< 使能主时钟分频器(MCKDIV).亦可选择disable,此处非重点,故均按默认处理 */
SAI1A_Handler.Init.FIFOThreshold=SAI_FIFOTHRESHOLD_1QF; /**< 设置FIFO阈值,1/4 FIFO */
SAI1A_Handler.Init.MonoStereoMode=SAI_STEREOMODE; /**< 立体声模式 */
SAI1A_Handler.Init.Protocol=SAI_FREE_PROTOCOL; /**< 设置SAI1协议为:自由协议(支持I2S/LSB/MSB/TDM/PCM/DSP等协议) */
SAI1A_Handler.Init.DataSize=datalen; /**< 设置数据大小 */
SAI1A_Handler.Init.FirstBit=SAI_FIRSTBIT_MSB; /**< 数据MSB位优先 */
SAI1A_Handler.Init.ClockStrobing=cpol; /**< 数据在时钟的上升/下降沿选通 */
/* 帧设置 */
SAI1A_Handler.FrameInit.FrameLength=64; /**< 设置帧长度为64,左通道32个SCK,右通道32个SCK. */
SAI1A_Handler.FrameInit.ActiveFrameLength=32; /**< 设置帧同步有效电平长度,在I2S模式下=1/2帧长. */
SAI1A_Handler.FrameInit.FSDefinition=SAI_FS_CHANNEL_IDENTIFICATION;/**< FS信号为SOF信号+通道识别信号 */
SAI1A_Handler.FrameInit.FSPolarity=SAI_FS_ACTIVE_LOW; /**< FS低电平有效(下降沿) */
SAI1A_Handler.FrameInit.FSOffset=SAI_FS_BEFOREFIRSTBIT; /**< 在slot0的第一位的前一位使能FS,以匹配飞利浦标准 */
/* SLOT设置 */
SAI1A_Handler.SlotInit.FirstBitOffset=0; /**< slot偏移(FBOFF)为0 */
SAI1A_Handler.SlotInit.SlotSize=SAI_SLOTSIZE_32B; /**< slot大小为32位 */
SAI1A_Handler.SlotInit.SlotNumber=2; /**< slot数为2个 */
SAI1A_Handler.SlotInit.SlotActive=SAI_SLOTACTIVE_0|SAI_SLOTACTIVE_1;/**< 使能slot0和slot1 */
HAL_SAI_Init(&SAI1A_Handler); /**< 初始化SAI */
__HAL_SAI_ENABLE(&SAI1A_Handler); /**< 使能SAI */
}
/* 开启SAIA的DMA功能 */
void SAIA_DMA_Enable(void)
{
u32 tempreg=0;
tempreg=SAI1_Block_A->CR1; /**< 先读出以前的设置 */
tempreg|=1<<17; /**< 使能DMA */
SAI1_Block_A->CR1=tempreg; /**< 写入CR1寄存器中 */
}
/* 开启SAIB的DMA功能 */
void SAIB_DMA_Enable(void)
{
u32 tempreg=0;
tempreg=SAI1_Block_B->CR1; /**< 先读出以前的设置 */
tempreg|=1<<17; /**< 使能DMA */
SAI1_Block_B->CR1=tempreg; /**< 写入CR1寄存器中 */
}
void SAIA_TX_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_DMA2_CLK_ENABLE(); /**< 使能DMA2时钟 */
__HAL_LINKDMA(&SAI1A_Handler,hdmatx,SAI1_TXDMA_Handler); /**< 将DMA与SAI联系起来 */
SAI1_TXDMA_Handler.Instance=DMA2_Stream3; /**< DMA2数据流3 */
SAI1_TXDMA_Handler.Init.Channel=DMA_CHANNEL_0; /**< 通道0 */
SAI1_TXDMA_Handler.Init.Direction=DMA_MEMORY_TO_PERIPH; /**< 存储器到外设模式 */
SAI1_TXDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE; /**< 外设非增量模式 */
SAI1_TXDMA_Handler.Init.MemInc=DMA_MINC_ENABLE; /**< 存储器增量模式 */
SAI1_TXDMA_Handler.Init.PeriphDataAlignment=perwidth; /**< 外设数据长度:16/32位 */
SAI1_TXDMA_Handler.Init.MemDataAlignment=memwidth; /**< 存储器数据长度:16/32位 */
SAI1_TXDMA_Handler.Init.Mode=DMA_CIRCULAR; /**< 使用循环模式 */
SAI1_TXDMA_Handler.Init.Priority=DMA_PRIORITY_HIGH; /**< 高优先级 */
SAI1_TXDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE; /**< 不使用FIFO */
SAI1_TXDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE; /**< 存储器单次突发传输 */
SAI1_TXDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; /**< 外设突发单次传输 */
HAL_DMA_DeInit(&SAI1_TXDMA_Handler); /**< 先清除以前的设置 */
HAL_DMA_Init(&SAI1_TXDMA_Handler); /**< 初始化DMA */
HAL_DMAEx_MultiBufferStart(&SAI1_TXDMA_Handler,(u32)buf0,(u32)&SAI1_Block_A->DR,(u32)buf1,num);/**< 开启双缓冲 */
__HAL_DMA_DISABLE(&SAI1_TXDMA_Handler); /**< 先关闭DMA */
delay_us(10); /**< 10us延时,防止-O2优化出问题 */
__HAL_DMA_ENABLE_IT(&SAI1_TXDMA_Handler,DMA_IT_TC); /**< 开启传输完成中断 */
__HAL_DMA_CLEAR_FLAG(&SAI1_TXDMA_Handler,DMA_FLAG_TCIF3_7); /**< 清除DMA传输完成中断标志位 */
HAL_NVIC_SetPriority(DMA2_Stream3_IRQn,0,0); /**< DMA中断优先级 */
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
* 拟进入发送。从接收模式转发送模式时需调用此函数 */
void Enter_Trs_mode(void)
{
SAI_Trs_Stop(); /**< 停止时钟发送 */
SAI_Rec_Stop(); /**< 停止接收 */
}
const u32 SAITrsbuff1[SAI_TX_DMA_BUF_SIZE]={0x888888,0x777777};/*<要发送的24位数据>这里是先随意给的两个数据用于测试,下同*/
const u32 SAITrsbuff2[SAI_TX_DMA_BUF_SIZE]={0x666666,0x555555};/*<要发送的24位数据>*/
/* 进入发送 */
void Trs_mode(void)
{
Enter_Trs_mode();
SAIA_Init(SAI_MODEMASTER_TX,SAI_CLOCKSTROBING_RISINGEDGE,SAI_DATASIZE_24);/**< SAI1_A主机发送此处因为AK4556是可以接受24位数据,所以设置为24*/
SAIA_SampleRate_Set(REC_SAMPLERATE); /**< 设置采样率 */
SAIA_TX_DMA_Init((u8*)&SAITrsbuff1,(u8*)&SAITrsbuff2,SAI_TX_DMA_BUF_SIZE/4,2); /**< 配置TX DMA,32位 */
__HAL_DMA_DISABLE_IT(&SAI1_TXDMA_Handler,DMA_IT_TC); /**< 关闭传输完成中断 */
SAI_Trs_Start(); /**< 开始SAI数据发送(主机) */
//printf("already send");
}
从示波器观察F767输出的数字数据,观察不到数据,可以看到虚影,谢谢各位大佬能够指点错误之处
|
|