你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于stm32f407 I2s DMA的主发送问题

[复制链接]
YLee 提问时间:2013-6-28 15:24 /
 最近用stm32f407做一个sd卡mp3解码后,音频传输的项目,声卡芯片用的VM8978,采取的是SPI3的i2s,用的DMA是DMA1的stream5通道0.用的是主发送模式
在dma中断中我用一个led反转看是否进入中断,结果是,中断进入,但i2s 引脚为何没有输出,按道理说应该是有波形输出的啊 BCLk脚怎么一直是低电平了?
新手,求各位大侠赐教!!
程序如下:
DMA_InitTypeDef DMA_InitStructure;
u32 AudioTotalSize = 0xffff; 
u32 AudioRemSize = 0; 
u16 *CurrentPos;           

extern void AUDIO_TransferComplete(u32 pBuffer, uint32_t Size);
void AUDIO_Init(u32 AudioFreq)
{
        Audio_I2S_Init(AudioFreq);
        I2S_GPIO_Init();
        Audio_DMA_Init();
}
void I2s_GPIO_DEinit(void)
{
          GPIO_InitTypeDef GPIO_InitStructure;
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;


    /* I2S3S_WS */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* I2S3_CK, I2S3_SD, I2S3ext_SD */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}
void I2S_GPIO_Init(void)
{
          GPIO_InitTypeDef GPIO_InitStructure;
                I2s_GPIO_DEinit();
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    /* Connect pins to I2S peripheral  */
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_SPI3);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI3);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_I2S3ext);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI3);

    /* I2S3S_WS */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    /* I2S3_CK, I2S3_SD, I2S3ext_SD */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

}

void Audio_I2S_Init(uint32_t AudioFreq)
{
          I2S_InitTypeDef I2S_InitStructure;
                SPI_I2S_DeInit(SPI3);
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
          SPI_I2S_DeInit(SPI3);
          I2S_InitStructure.I2S_AudioFreq = AudioFreq;
          I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
          I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
          I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
          I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;
          I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable; 
          I2S_Init(SPI3, &I2S_InitStructure);
}

//DMA传送配置
void Audio_DMA_Init(void)  

          NVIC_InitTypeDef NVIC_InitStructure;
          RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE); 
          DMA_Cmd(DMA1_Stream5, DISABLE);
          DMA_DeInit(DMA1_Stream5);
          DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
          DMA_InitStructure.DMA_PeripheralBaseAddr = 0x4000380C;
          DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0;//该项将在播放函数中进行配置
          DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
          DMA_InitStructure.DMA_BufferSize = (uint32_t)0xFFFE;//该项将在播放函数中进行配置      
          DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
          DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
          DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
          DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 
          DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; 
          DMA_InitStructure.DMA_Priority = DMA_Priority_High;
          DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
          DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
          DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
          DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;  
          DMA_Init(DMA1_Stream5, &DMA_InitStructure);  
          DMA_ITConfig(DMA1_Stream5, DMA_IT_TC, ENABLE);//使能所选DMA的中断
          //I2S DMA中断通道配置
          NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream5_IRQn;
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级(0 最高)
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//子优先级(0 最高)
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
          NVIC_Init(&NVIC_InitStructure);   
          SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE);//中断请求使能  
}


//开始从特定大小(Size)的缓冲区(pBuffer)中播放音频流
uint32_t AUDIO_Play(u16* pBuffer, u32 Size)
{
          AudioTotalSize=Size; 
          Audio_MAL_Play((u32)pBuffer,(u32)(DMA_MAX(Size/4)));//更新媒体层数据并播放
          AudioRemSize=(Size/2)-DMA_MAX(AudioTotalSize);//更新剩余数据量
          CurrentPos=pBuffer+DMA_MAX(AudioTotalSize);//更新当新数据指针 
          return 0;
}

//开始播放媒体中的音频流
void Audio_MAL_Play(u32 Addr, u32 Size)
{         
          DMA_InitStructure.DMA_Memory0BaseAddr=(uint32_t)Addr;//配置缓冲区地址和大小
          DMA_InitStructure.DMA_BufferSize=(uint32_t)Size/2;
          DMA_Init(DMA1_Stream5,&DMA_InitStructure);
          DMA_Cmd(DMA1_Stream5,ENABLE);//I2S DMA使能   
          if ((SPI3->I2SCFGR & I2S_ENABLE_MASK)==0)I2S_Cmd(SPI3,ENABLE);//若I2S接口未使能,则使能
}

//I2S中断处理
void SPI3_IRQHandler(void)
{
          if (SPI_I2S_GetFlagStatus(SPI3,SPI_I2S_FLAG_TXE)!=RESET)
          {             
            SPI_I2S_SendData(SPI3, 0);//发送空字节到I2S 
                        SPI_I2S_ClearFlag(SPI3,SPI_I2S_FLAG_TXE);
          }
}

//DMA中断处理函数
void DMA1_Stream5_IRQHandler(void)
{    
          //传送完成中断
          if (DMA_GetFlagStatus(DMA1_Stream5, DMA_FLAG_TCIF5)!=RESET)
          {  
                        if (AudioRemSize>0)//查看是否到达文件尾
            {   
                        printf("DMA1\r\n");
                      while (DMA_GetCmdStatus(DMA1_Stream5) != DISABLE) IWDG_ReloadCounter();//等待DMA disabled     
                      DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5);//清传送完成中断标志           
                      DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) CurrentPos;//重新配置缓冲区地址和大小
                      DMA_InitStructure.DMA_BufferSize = (uint32_t) (DMA_MAX(AudioRemSize));            
                      DMA_Init(DMA1_Stream5, &DMA_InitStructure);
                      DMA_Cmd(DMA1_Stream5, ENABLE);    
                      CurrentPos += DMA_MAX(AudioRemSize);//更新数据指针        
                      AudioRemSize -= DMA_MAX(AudioRemSize);//更新剩余数据   
                      DMA_Cmd(DMA1_Stream5, ENABLE); 
            }
            else//已到达文件尾
            {
                     DMA_Cmd(DMA1_Stream5, DISABLE);   
                      DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5);       
                      AUDIO_TransferComplete((uint32_t)CurrentPos, 0);       
                        STM_EVAL_LEDToggle(2);                                    //led反转 ,显示状态
//                         printf("DMA2\r\n");
            }
        //                                        printf("DMA3\r\n");

          }
}
收藏 评论1 发布时间:2013-6-28 15:24

举报

1个回答
shiyang1212 回答时间:2014-3-26 14:58:58

回复:关于stm32f407 I2s DMA的主发送问题

你的程序调试出来了吧??????  我看你的外设地址用的是SPI2的地址啊

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版