STM32 M4 Cortex WAV 播放器 SD 卡 DMA DAC

Posted

技术标签:

【中文标题】STM32 M4 Cortex WAV 播放器 SD 卡 DMA DAC【英文标题】:STM32 M4 Cortex WAV Player SD Card DMA DAC 【发布时间】:2020-04-11 09:41:19 【问题描述】:

几个月来,我尝试通过 DMA 将 16 位 48kHz 的波形文件从 SD 卡运行到我的 DAC 输出。

但我得到的只是可怕的声音。我阅读了很多 ST Electronics 的数据表,但都没有解决问题。

首先我尝试了 HAL 驱动程序,但只有来自阵列的正弦波形有效。不是波形文件。

所以我切换到 DMA、TIM6 和 DAC 的低层驱动程序。

这是我在 main 中的初始化源:

  LL_DAC_EnableDMAReq(DAC1, LL_DAC_CHANNEL_1); // enable DMA for Channel1
  LL_DAC_Enable(DAC1, LL_DAC_CHANNEL_1); //enable Channel on DAC
  LL_DMA_ConfigAddresses(DMA1, LL_DMA_STREAM_5,(uint32_t) &DAC_Buff, LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_12BITS_RIGHT_ALIGNED ), LL_DMA_DIRECTION_MEMORY_TO_PERIPH ); //Speicherbereich auf den die DMA Unit zugreift definieren
  LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, 2);     // die beschreibung in UM1725 ist heir etwas dürftig ich hab einfach mal 16 für 2byte genommen
  LL_DMA_EnableIT_HT(DMA1,LL_DMA_STREAM_5);     // Halb Transfer Interrupt für Sream5 aktivieren
  LL_DMA_EnableIT_TC(DMA1,LL_DMA_STREAM_5);      // Complet Transfer Interrupt für Sream5 aktivieren
  LL_DAC_EnableTrigger(DAC1, LL_DAC_CHANNEL_1);  // ohne geht garnix, aber wenn an muss man __disable_irq machen
  LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);    //Stream5 DAC1 Starten

我读取文件的来源有效:

char wave_playback(const char *FileName)

  FRESULT res;
  FIL file;
  UINT cnt;
uint32_t filesize;

  res = f_open( &file, FileName, FA_READ );   //file oeffne
  if(res) return 1;
filesize= f_size(&file);
  res = f_lseek(&file,0x2c);                  // WAV head  überspringen
//  filesize=filesize-0x2c;
  if(res) return 2;
 f_read (&file,&DAC_Buff[0],512,&cnt);       //beider 256 Buffer befüllen
 //filesize=filesize-512;
  if(res) return 3;

 __disable_irq();

  //TIM6->CR1 |= TIM_CR1_CEN;
 LL_TIM_EnableCounter(TIM6);                // Timer 6 der DMA triggert starten

  while(1)
  
     volatile ITStatus it_st;
         it_st = RESET;
     while(it_st == RESET)    //auf Flag für halben Transfer warten
         it_st = LL_DMA_IsActiveFlag_HT5(DMA1);
         //it_st = READ_BIT(DMA1->HISR ,DMA_HISR_HTIF5);
     
     f_read (&file,&DAC_Buff[0],256,&cnt);      //unteren buffer befüllen
     LL_DMA_ClearFlag_HT5(DMA1);                // half transfer flag (stream5) löschen
    // DMA1->HISR |= DMA_HISR_HTIF5;
    // filesize=filesize-256;
     if(cnt<256)break;                        //wenn das ende des files erreicht while verlassen

     it_st = RESET;
     while(it_st == RESET)    ////auf Flag für kompletten Transfer warten
     it_st = LL_DMA_IsActiveFlag_TC5(DMA1);
     //it_st = READ_BIT(DMA1->HISR ,DMA_HISR_TCIF5);
     
     f_read (&file,&DAC_Buff[256],256,&cnt);  //oberen buffer befüllen
     LL_DMA_ClearFlag_TC5(DMA1);  //complet transfer flag (stream5) löschen
     //DMA1->HISR |= DMA_HISR_TCIF5;
    // filesize=filesize-256;
     if(cnt<256)break;                        //wenn das ende des files erreicht while verlassen
  

  //TIM6->CR1 &= ~TIM_CR1_CEN;                  // Roh Kommando Timer 6 der DMA triggert stoppen
  LL_TIM_DisableCounter(TIM6);                  // Timer 6 der DMA triggert stoppen

  f_close(&file);                             //file stream beenden

  return 0;                                   //bei wenn i.O. 0 zurueck geben

我检查了两次 SD 卡上的波形文件(16bit 48kHz),但声音很吓人,我不明白为什么。

然后我再次尝试使用 HAL 驱动程序,但没有任何效果,因此我切换回 LL 驱动程序。

我做错了什么?有人知道吗?

【问题讨论】:

您没有准确说明您使用的是哪种硬件(评估板)。我假设某处有扬声器?哪一个以及它如何与STM32连接?通常您可以找到示例源代码来演示评估板的不同功能。 STM32 Nucleo 和 EVAL 板就是这种情况。你检查了吗? 这是一个带有 STM32F407 VGT6 ARM 微控制器的 STM32F4xx_M DevEBox Board V3。它不是 ST 的官方开发板。来自 ST 的官方示例源代码根本没有帮助我。 PA4 上的 2DAC DAC1 和 PA5 引脚上的 DAC2。 喜欢这个。 [链接] (item.taobao.com/…) 【参考方案1】:

您正在播放的数据中可能存在位或字节字节序问题。尝试切换到 8 位模式:

LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_5, LL_DAC_DMA_GetRegAddr(DAC1, LL_DAC_CHANNEL_1, LL_DAC_DMA_REG_DATA_8BITS_RIGHT_ALIGNED));
LL_DMA_SetPeriphSize(DMA1, LL_DMA_STREAM_5, LL_DMA_MDATAALIGN_BYTE);
LL_DMA_SetMemorySize(DMA1, LL_DMA_STREAM_5, LL_DMA_MDATAALIGN_BYTE);

【讨论】:

什么是位字节序?

以上是关于STM32 M4 Cortex WAV 播放器 SD 卡 DMA DAC的主要内容,如果未能解决你的问题,请参考以下文章

stm32mp1 Cortex M4开发篇7:窗口看门狗

如何在 STM32F4、Cortex M4 上写入/读取 FLASH

STM32MP157开发板Linux+Qt项目实战:音乐播放器

STM32MP157开发笔记 | 02 - 开发环境搭建(A7核M4核)

STM32MP157开发笔记 | 02 - 开发环境搭建(A7核M4核)

stm32库函数算hal层吗