OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3269|回复: 1

在使用F767的DMA双缓冲模式,给外部音频芯AK4556发送数字数据时,用示波器观察跟自己想要的不对

[复制链接]

1

主题

6

帖子

0

精华

初级会员

Rank: 2

积分
91
金钱
91
注册时间
2019-8-31
在线时间
24 小时
发表于 2020-6-20 09:57:53 | 显示全部楼层 |阅读模式
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输出的数字数据,观察不到数据,可以看到虚影,谢谢各位大佬能够指点错误之处

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165475
金钱
165475
注册时间
2010-12-1
在线时间
2115 小时
发表于 2020-6-21 01:30:38 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-1 08:04

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表