这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » AT32I2S使用DMA半传输及传输完成中断来实现DMA双缓冲效果

共3条 1/1 1 跳转至

AT32I2S使用DMA半传输及传输完成中断来实现DMA双缓冲效果

菜鸟
2020-12-09 18:41:00     打赏

本文主要在AT32F403A芯片上演示

        使用DMA半传输及传输完成中断的组合使用来实现DMA双缓冲存储I2S接收到的数据

以下为主函数关键源码实现:

int main(void)

{

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  RCC_Configuration();

  GPIO_Configuration();

  AT32_Board_Init();

  SPI_I2S_Reset(SPI3);

  SPI_I2S_Reset(SPI2);

  I2S_DefaultInit(&I2S_InitStructure);

  I2S_InitStructure.I2s_AudioProtocol = I2S_AUDIOPROTOCOL_PHILLIPS;

  I2S_InitStructure.I2S_FrameFormat = I2S_FRAMEFORMAT_DL16BIT_CHL32BIT;

  I2S_InitStructure.I2S_MCLKOE = I2S_MCLKOE_DISABLE;

  I2S_InitStructure.I2S_AudioFreq = I2S_AUDIOFREQ_48K;

  I2S_InitStructure.I2S_CPOL = I2S_CPOL_LOW;


  I2S_InitStructure.I2S_Mode = I2S_MODE_MASTERTX;

  I2S_Init(SPI3, &I2S_InitStructure);

  I2S_InitStructure.I2S_Mode = I2S_MODE_SLAVERX;

  I2S_Init(SPI2, &I2S_InitStructure);


  DMA_Reset(DMA1_Channel4);

  DMA_Reset(DMA2_Channel2);  

  DMA_DefaultInitParaConfig(&DMA_InitStructure);

  DMA_InitStructure.DMA_BufferSize = 36;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;

  DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;

  DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_HALFWORD;

  DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_HALFWORD;

  DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;

  DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;

  DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;


  DMA_InitStructure.DMA_PeripheralBaseAddr = I2S3_DR_ADDRESS;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&I2S3_Buffer_Tx;

  DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST;

  DMA_Init(DMA2_Channel2, &DMA_InitStructure);

  DMA_InitStructure.DMA_PeripheralBaseAddr = I2S2_DR_ADDRESS;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&I2S2_Buffer_Rx;

  DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC;  

  DMA_Init(DMA1_Channel4, &DMA_InitStructure);  

  DMA_ChannelEnable(DMA2_Channel2, ENABLE); ///<使用DMA2_Channel2发送数据

  DMA_ChannelEnable(DMA1_Channel4, ENABLE);  ///<使用DMA1_Channel4接收数据


  SPI_I2S_DMAEnable(SPI2,SPI_I2S_DMA_RX,ENABLE);

  I2S_Enable(SPI2, ENABLE);

  I2S_Enable(SPI3, ENABLE);

  SPI_I2S_DMAEnable(SPI3,SPI_I2S_DMA_TX,ENABLE);  

  while(DMA_GetFlagStatus(DMA1_FLAG_HT4)==RESET);///<等待半传输完成后处理前半部分接收到的数据

  for(main_temp1 = 0; main_temp1 < 18 ;main_temp1++)

  {

    User_Buffer1[main_temp1] = I2S2_Buffer_Rx[main_temp1];

  }

  while(DMA_GetFlagStatus(DMA1_FLAG_TC4)==RESET);///<等待传输完成后处理后半部分接收到的数据

  for(main_temp1 = 0; main_temp1 < 18 ;main_temp1++)

  {

    User_Buffer2[main_temp1] = I2S2_Buffer_Rx[main_temp1 + 18];

  }


  TransferStatus1 = Buffercmp(User_Buffer1, (uint16_t*)I2S3_Buffer_Tx, 18);///<前半部分数据准确性检查

  TransferStatus2 = Buffercmp(User_Buffer2, (uint16_t*)(&I2S3_Buffer_Tx[18]), 18);///<后半部分数据准确性检查

  if((TransferStatus1==PASSED) && (TransferStatus2==PASSED))

  {

    AT32_LEDn_ON(LED2);

  }    

  else

  {

    AT32_LEDn_OFF(LED2);

  }

  while (1)

  {

  }

}


以下为中断函数关键源码实现:

void DMA1_Channel4_IRQHandler(void)

{

  if(DMA_GetITStatus(DMA1_INT_HT4))

  {

    Ht_Int_Flag = 1;

    DMA_ClearITPendingBit(DMA1_INT_HT4);

  }

  if(DMA_GetITStatus(DMA1_INT_TC4))

  {

    Tc_Int_Flag = 1;

    DMA_ClearITPendingBit(DMA1_INT_TC4);

  }

}

说明:本文只提供一种方法参考,可能切合某些实际应用的话(比如允许更改DMA目的地址等),还有更加合理的方法,所以需要具体问题具体讨论。




关键词: AT32     DMA双缓冲     I2S     403A    

工程师
2020-12-09 22:27:19     打赏
2楼

效果还是不错的


工程师
2020-12-09 22:37:55     打赏
3楼

确实是个不错的产品


共3条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]