STM32F103的DMA双缓冲问题

2019-07-20 04:56发布

原子哥这是我第一次发帖子,希望被翻
我现在在做一个运用STM32F103的V3.5库函数来实现对WM8978音频播放,但是不知道如何配置DMA如何实现双缓冲,我看到STM32F4直接就有相关的库函数DMA_DoubleBufferModeConfig,但是
103在没有相关的库函数下如何编写呢?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
4条回答
weilexuexi12
2019-07-20 05:17
正点原子 发表于 2018-11-22 02:00
103没有双缓冲!
所以,只能单缓冲操作了。

你好原子哥,咱们有相关的关于这个 单缓冲操作,但是有双缓冲的那种效果的例程代码吗?我再网上看了看一些代码,但是写进去效果都不好。
下面是一部分代码:
DMA_Double_Buf_Init((uint32_t)databuf2,(uint32_t)databuf,2048);        (这是自己编写的双缓冲代码);
void DMA_Double_Buf_Init(u32 addr1,u32 addr2, u32 size)
{
        buf_addr1=addr1;
        buf_addr2=addr2;
        buf_size=size;
        buf_n=1;
        I2S_Configuration();
        DMA_Configuration(addr1,size);
}

//这是IIS配置函数       
void I2S_Configuration(void)
{
I2S_InitTypeDef I2S_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
  /* Configure SPI2 pins: CK, WS and SD ---------------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 ;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  /* Configure SPI2 pins: CK, WS and SD ---------------------------------*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  /* Configure SPI2 pins: MCK ---------------------------------*/
#ifdef         OPEN_MCK
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
#endif
   /*打开I2S时钟*/
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
  SPI_I2S_DeInit(SPI2);
  /* I2S peripheral configuration */
  I2S_InitStructure.I2S_Standard = I2S_Standard_Phillips;
  I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
#ifdef         OPEN_MCK       
  I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;
#else
        I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
#endif       
  I2S_InitStructure.I2S_AudioFreq = I2S_AudioFreq_44k;
  I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;
  I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx;//Rx 是在录音模式下使用,Tx 是在播放模式下使用
  I2S_Init(SPI2, &I2S_InitStructure);
  I2S_Cmd(SPI2, ENABLE);
//        SPI_I2S_SendData(SPI2,0xffff);
//        SPI_I2S_SendData(SPI2,0x0000);
//        SPI_I2S_SendData(SPI2,0xffff);
}   


//DMA配置函数

void DMA_Configuration(u32 addr, u32 size)
{
        NVIC_InitTypeDef NVIC_InitStructure;
  /*open DMA clock*/
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
       

  DMA_Cmd(DMA1_Channel5, DISABLE);
  I2S_Cmd(SPI2, DISABLE);
  DMA_DeInit(DMA1_Channel5);
  /* DMA Channel configuration ----------------------------------------------*/
  DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)(0x4000380c);//SPI发送寄存器地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32) addr;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  DMA_InitStructure.DMA_BufferSize = size;
  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_Priority = DMA_Priority_VeryHigh;
  //DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
        DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel5, &DMA_InitStructure);
  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
  /* Enable SPI DMA Tx request */
       
        NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
  I2S_Cmd(SPI2, ENABLE);
  DMA_Cmd(DMA1_Channel5, ENABLE);
}

这是一个IIS通过DMA双缓冲直接发送数据,下面是DMA中断:
void DMA1_Channel5_IRQHandler(void)
{
       
        if(DMA_GetITStatus(DMA1_IT_TC5) != RESET)
        {
               
                DMA_ClearITPendingBit(DMA1_IT_TC5);
               
                DMA_Double_Buf_Change();
               
        }
       
}

void DMA_Double_Buf_Change(void)
{
        DMA1_Channel5->CCR &= (uint16_t)(~DMA_CCR1_EN);       
        DMA1_Channel5->CNDTR = buf_size;
        if(buf_n==1)
        {
                DMA1_Channel5->CMAR  = buf_addr2;
                buf_n=2;
        }
        else
        {
                DMA1_Channel5->CMAR  = buf_addr1;
                buf_n=1;
        }       
        DMA1_Channel5->CCR |= DMA_CCR1_EN;
        buf_fin=1;
        LED1=!LED1;
}

一周热门 更多>