[其他ST产品] STM32CubeIDE Audio播放音频,DAC + TIM + DMA

[复制链接]
1104|27
 楼主| 慢动作 发表于 2023-1-12 10:53 | 显示全部楼层 |阅读模式
AC, DAC, DM, DMA, IDE
官方参考 文档 和 例程:

文档编号 AN3126   网址:意法半导体STM | STM32/STM8微控制器 | MCU单片机

例程编号 UM0891   网址:意法半导体STM | STM32/STM8微控制器 | MCU单片机


3531163bf7624858ea.png


评论

———————————————— 版权声明:本文为CSDN博主「sudaroot」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/sudaroot/article/details/106337717  发表于 2023-1-12 11:02
 楼主| 慢动作 发表于 2023-1-12 10:54 | 显示全部楼层
官方硬件连接:
文档编号(UM0841)
5919063bf76747c3f9.png
 楼主| 慢动作 发表于 2023-1-12 10:55 | 显示全部楼层
官方例程实现流程图:
1412063bf769906f9b.png
 楼主| 慢动作 发表于 2023-1-12 10:59 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:00 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:00 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:01 | 显示全部楼层
官方例程播放音频代码:
  1. /**
  2.   * [url=home.php?mod=space&uid=247401]@brief[/url]  Start wave playing
  3.   * @param  None
  4.   * @retval None
  5.   */
  6. uint8_t WavePlayerMenu_Start(uint8_t *DirName, uint8_t *FileName, uint32_t *FileLen)
  7. {
  8.   DAC_InitTypeDef            DAC_InitStructure;
  9.   DMA_InitTypeDef            DMA_InitStructure;
  10.   uint32_t var;
  11.   uint8_t tmp, KeyState = NOKEY;
  12.   RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  13.   WaveFileStatus = Unvalid_RIFF_ID;

  14.   /* TIM6 Configuration */
  15.   TIM_DeInit(TIM6);

  16.   /* DMA1 channel3 configuration */
  17.   DMA_DeInit(DMA1_Channel3);
  18.   DMA_InitStructure.DMA_PeripheralBaseAddr = DAC_DHLCD_REG_8LCD_REG_1_ADDRESS;
  19.   DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) & Wavebuffer;
  20.   DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
  21.   DMA_InitStructure.DMA_BufferSize = 512;
  22.   DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  23.   DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  24.   DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
  25.   DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
  26.   DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
  27.   DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  28.   DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  29.   DMA_Init(DMA1_Channel3, &DMA_InitStructure);

  30.   /* Enable DMA1 Channel3 */
  31.   DMA_Cmd(DMA1_Channel3, ENABLE);

  32.   /* DAC deinitialize */
  33.   DAC_DeInit();
  34.   DAC_StructInit(&DAC_InitStructure);

  35.   /* Fill DAC InitStructure */
  36.   DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;
  37.   DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;
  38.   DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

  39. /* DAC Channel1: 8bit right---------------------------------------------------*/
  40.   /* DAC Channel1 Init */
  41.   DAC_Init(DAC_Channel_1, &DAC_InitStructure);
  42.   /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is
  43.      automatically connected to the DAC converter. */
  44.   DAC_Cmd(DAC_Channel_1, ENABLE);
  45.   /* Enable DMA for DAC Channel1 */
  46.   DAC_DMACmd(DAC_Channel_1, ENABLE);

  47.   /* Read the Speech wave file status */
  48.   WaveFileStatus = WavePlayer_WaveParsing(DirName, FileName, &wavelen);

  49.   /* TIM6 TRGO selection */
  50.   TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);
  51.   TIM_SetAutoreload(TIM6, TIM6ARRValue);

  52.   if (WaveFileStatus == Valid_WAVE_File)  /* the .WAV file is valid */
  53.   {
  54.     /* Set WaveDataLenght to the Speech wave length */
  55.     WaveDataLength = WAVE_Format.DataSize;
  56.   }
  57.   else
  58.   {
  59.     return NOKEY;
  60.   }
  61.   
  62.   /* Start TIM6 */
  63.   TIM_Cmd(TIM6, ENABLE);

  64.   LCD_SetTextColor(LCD_COLOR_MAGENTA);
  65.   /* Set the Back Color */
  66.   LCD_SetBackColor(LCD_COLOR_BLUE);
  67.   LCD_DrawRect(LCD_LINE_7, 310, 16, 300);

  68.   while (WaveDataLength)
  69.   {
  70.     DFS_ReadFile(&fiwave, sector, Wavebuffer2, &var, SECTOR_SIZE);
  71.     if (WaveDataLength) WaveDataLength -= 512;
  72.     if (WaveDataLength < 512) WaveDataLength = 0;
  73.     while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET)
  74.     {
  75.     }
  76.     DMA1->IFCR = DMA1_FLAG_TC3;
  77.     DMA1_Channel3->CCR = 0x0;

  78.     DMA1_Channel3->CNDTR = 0x200;
  79.     DMA1_Channel3->CPAR = 0x40007410;
  80.     DMA1_Channel3->CMAR = (uint32_t) & Wavebuffer2;
  81.     DMA1_Channel3->CCR = 0x2091;

  82.     DFS_ReadFile(&fiwave, sector, Wavebuffer, &var, SECTOR_SIZE);
  83.     if (WaveDataLength) WaveDataLength -= 512;
  84.     if (WaveDataLength < 512) WaveDataLength = 0;
  85.    
  86.     while (DMA_GetFlagStatus(DMA1_FLAG_TC3) == RESET)
  87.     {
  88.     }
  89.     DMA1->IFCR = DMA1_FLAG_TC3;
  90.     DMA1_Channel3->CCR = 0x0;

  91.     DMA1_Channel3->CNDTR = 0x200;
  92.     DMA1_Channel3->CPAR = 0x40007410;
  93.     DMA1_Channel3->CMAR = (uint32_t) & Wavebuffer;
  94.     DMA1_Channel3->CCR = 0x2091;
  95.   }
  96.   DMA1_Channel3->CCR = 0x0;
  97.   
  98.   /* Disable TIM6 */
  99.   TIM_Cmd(TIM6, DISABLE);
  100.   WaveDataLength = 0;
  101.   
  102.   return NOKEY;
  103. }

 楼主| 慢动作 发表于 2023-1-12 11:02 | 显示全部楼层
随言:
建议下载该例程看看源码,但是由于官方使用的是外部TF卡存储音频,有一个读取外部数据拷贝到SRAM的延时问题,故官方使用了双缓存区方式。

而我只想简单播放音频,故我找了一段15秒的16KHz_8bit_wav格式音频,直接转成C语言数组存在芯片内部flash。由于是放在内部flash,故不用担心数据拷贝的速度问题,所以我使用单缓冲区就可以了。甚至可以不需要把内部flash数据拷贝到缓存区,直接让DMA指向flash数据的地址。

音频的采样位数为8bit 16bit 24bit 32bit,采样位数越高当然音质越好,但是相对的存储也急剧增加。
 楼主| 慢动作 发表于 2023-1-12 11:03 | 显示全部楼层
注意:STM32F4的DAC最大分辨率为12bit,故我们只能使用8bit的音频。还有就是一般高采样位数音频转低采样位数音频的一定要适当加入抖动(噪声)。
 楼主| 慢动作 发表于 2023-1-12 11:06 | 显示全部楼层
硬件要求:一定要带功放模块。
开发板:STM32F407ZG,功放PAM8403,一个喇叭4Ω 3W。
 楼主| 慢动作 发表于 2023-1-12 11:16 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:27 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:28 | 显示全部楼层
STM32CubeIDE配置:
首先配置TIM6。使用TIM6触发DAC的将音频数字数据转换为模拟波形。由于我使用的音频为16KHz,

计算  1s / 16K = 0.0000625s = 62.5us。即每62.5us触发一次DAC转换。
 楼主| 慢动作 发表于 2023-1-12 11:28 | 显示全部楼层
TIM6的时钟是84MHz,分频系数42,故当前时钟为2MHz,向上计数一次为0.5us,计数值设为125,即可满足62.5us触发一次DAC转换。
 楼主| 慢动作 发表于 2023-1-12 11:29 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:36 | 显示全部楼层
DAC设置,PA4引脚,TIM6触发,打开DMA.
9790263bf7eb090966.png
 楼主| 慢动作 发表于 2023-1-12 11:37 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:41 | 显示全部楼层
 楼主| 慢动作 发表于 2023-1-12 11:43 | 显示全部楼层
准备工作:

1、下载一首十几秒的歌曲。

2、准备一下音频编辑工具,我自己用Adobe Audition CS6。
 楼主| 慢动作 发表于 2023-1-12 11:45 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

1071

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部