OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5239|回复: 4

STM32F1 使用 DAC播放WAV音频文件使用DMA有音爆问题

[复制链接]

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2019-10-23
在线时间
72 小时
发表于 2021-2-26 15:16:04 | 显示全部楼层 |阅读模式
30金钱
问题:使用STM32F103的DAC播放WAV音频文件时,会出现音爆现象,也就是播放前会咚的响一下,有没有各位能解决的,在此3感激不尽

这里使用的DAC引脚为PA4脚 也就是DAC1脚


下面贴出我的代码:
设置C配置文件


#include "soundplay.h"
#include "sound2.h"


//参考:https://blog.csdn.net/m0_46145395/article/details/112341219
//参考:http://blog.chinaunix.net/uid-22670933-id-5792785.html
//参考:http://news.eeworld.com.cn/mcu/2018/ic-news072340545.html
//参考:https://blog.csdn.net/liqiang420795936/article/details/108216511
//参考:https://blog.csdn.net/sudaroot/article/details/106337717

/**-***********************************************************************
音频文件需要的信息:
create table fileinfo(
    ID       int, #文件编号
    name     varchar(20),#文件名称
    Length   int,    #文件长度
    Smapling int,    #文件频率
    BaseAddress  int,    #保存地址
    primary  key(ID,BaseAddress)
);

insert into fileinfo values(1,'正常行驶',18636,16000,1024);
*****************************************************************************/
void DAC_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
   
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );      //使能PORTA通道时钟
   
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;   
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_SetBits(GPIOA,GPIO_Pin_4)    ;//PA.4 输出高
}

u8 buff[sizeof(dataspeed)];

void WAVE_Play_config(void)
{
    u32 i=0;
   
    DMA_InitTypeDef            DMA_InitStructure;
    TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
    DAC_InitTypeDef            DAC_InitStructure;
   
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);//开启DMA2时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);//开时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);//开DAC时钟


    TIM_DeInit(TIM6);

//    TIM_TimeBaseStructure.TIM_Period = 72000000/FmtBlock.wavFormat.dwSamplesPerSec;   

    TIM_TimeBaseStructure.TIM_Period = (72000000/WAVE_Sampling);    //=72000000/采样率
    TIM_TimeBaseStructure.TIM_Prescaler = 0;                  
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;         
    TIM_TimeBaseInit(TIM6, &TIM_TimeBaseStructure);
    TIM_ClearFlag(TIM6, TIM_FLAG_Update);                                
    TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update);//设置TIME输出触发为更新模式  


    DAC_StructInit(&DAC_InitStructure);   
    DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None;//不产生波形
    DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable; //不使能输出缓存 驱动增大
    DAC_InitStructure.DAC_Trigger = DAC_Trigger_T6_TRGO;//DAC触发为定时器6触发
    DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude=DAC_LFSRUnmask_Bit0;//屏蔽、幅值设置
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);//初始化


    DMA_StructInit( &DMA_InitStructure);                                                //DMA结构体初始化
    DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&(DAC->DHR8R1);//外设地址为DAC通道1的地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buff;  //波形数据表内存地址
    DMA_InitStructure.DMA_BufferSize = 18636;//;//47857;//66056;//47857;//2484;//寄存器大小
        
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;                            //从内存到外设
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 //内存地址递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//宽度为字节
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_Byte;                 //宽度为字节
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;                                 //优先级非常高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                        //关闭内存到内存模式
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;                                    //循环发送模式
    DMA_Init(DMA2_Channel3, &DMA_InitStructure);//初始化
   
    DMA_Cmd(DMA2_Channel3, ENABLE); //使能DMA通道3
    TIM_Cmd(TIM6, ENABLE);
   
    for(i=0;i<sizeof(dataspeed);i++)
    {
        buff=dataspeed/9;//音量调节最高除以10
    }   
   
    DAC_Cmd(DAC_Channel_1, ENABLE);    //使能DAC的通道1
    DAC_DMACmd(DAC_Channel_1, ENABLE); //使能DAC通道1的DMA
}

这是h文件
#ifndef __SOUNDPLAY_H
#define __SOUNDPLAY_H

#include "system.h"

//DAC DHR12RD寄存器,12位、右对齐、双通道
//#define DAC_DHR12RD_ADDRESS      (DAC_BASE+0x20)

#define DAC_DHR12RD_ADDRESS      (DAC_BASE+0x20)

#define WAVE_Sampling   16000  //采样率


typedef struct
{
    unsigned char ID;
    unsigned char name[20];
    unsigned int  length;  //文件长度
    unsigned int  Smapling;//采样率
    unsigned int  BaseAddress;//保存基地址
}FileInfo;




void DAC_GPIO_Init(void);
void WAVE_Play_config(void);


/*
void SoundPlay_Init(void);

void DAC_Mode_Init(void);
*/
void Test_DAC_Init(void);
void Test_TimeConfig(void);



#endif

这是PA4脚输出的波形
1.

DAC波形.jpg
2.
DAC.png

如何才能解决那个快速下降的低电平问题?



正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2019-10-23
在线时间
72 小时
 楼主| 发表于 2021-2-26 15:17:53 | 显示全部楼层
但是不使用DMA,直接使用DAC播放就没有问题,不知道如何解决音爆问题
回复

使用道具 举报

12

主题

3402

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8691
金钱
8691
注册时间
2020-5-11
在线时间
4183 小时
发表于 2021-2-26 16:05:41 | 显示全部楼层
buff=dataspeed/9; 这写的啥
专治疑难杂症
回复

使用道具 举报

4

主题

16

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
236
金钱
236
注册时间
2019-10-23
在线时间
72 小时
 楼主| 发表于 2021-2-27 10:09:03 | 显示全部楼层
LcwSwust 发表于 2021-2-26 16:05
buff=dataspeed/9; 这写的啥

这是用来调节音量的将每个数据减去或除去一定数字,实现音量大小的调节
回复

使用道具 举报

12

主题

3402

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8691
金钱
8691
注册时间
2020-5-11
在线时间
4183 小时
发表于 2021-2-27 10:38:53 | 显示全部楼层
本帖最后由 LcwSwust 于 2021-2-27 10:40 编辑
ESP32 发表于 2021-2-27 10:09
这是用来调节音量的将每个数据减去或除去一定数字,实现音量大小的调节

哦,看来是网页的问题,元素序号 [ i ] 没显示出来,打扰了。
傲游截图20210227104025.jpg
专治疑难杂症
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-29 02:54

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表