stm32的timer-trgo + DMA + DAC 播放WAV格式音乐

1、考虑到stm32F103的flash大小有限,所以音频数据存在spi-flash中,WAV文件有6段语音。合成在一起大概有1.3M(客户给的文件)。所以用Audition软件把WAV文件转换成8k采样频率和8位数据格式(PS:音质效果还可以),文件大小变为126k,spi-flash有4M字节, 完全可以存下。

2、考虑到CPU的效率问题,采用TIMER+DMA的方式输送音频数据,下面贴出DAC的配置,采用的是DAC的通道1,即对应的PA4引脚,下面贴出DAC配置代码。

    GPIO_InitTypeDef GPIO_InitStructure;
    DAC_InitTypeDef            DAC_InitStructure;
    uint8_t i;
    
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
    
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4; //| GPIO_PIN_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    DAC_InitStructure.DAC_Trigger                      = DAC_Trigger_T5_TRGO;
    // 不生成波形
    DAC_InitStructure.DAC_WaveGeneration               = DAC_WaveGeneration_None;
    DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_LFSRUnmask_Bit0;   
    // 输出缓存开启
    DAC_InitStructure.DAC_OutputBuffer                 = DAC_OutputBuffer_Enable;
    DAC_Init(DAC_Channel_1, &DAC_InitStructure);
    // PA4
    DAC_DMACmd(DAC_Channel_1, ENABLE);
    DAC_SetChannel1Data(DAC_Align_8b_R, 0);  //8位右对齐数据格式设置DAC

值

说明: DAC触发信号配置为定时器5的TRGO触发, 开启DAC输出缓存功能,使DAC驱动增大。

3、下面是播放音乐的详细代码

/***************************************************************************************
函数名称: void play_music(uint8_t data)
函数功能: 播放音乐函数
输入参数: 第几段音乐
返 回 值: 无
***************************************************************************************/
void play_music(uint8_t data)
{
    uint32_t play_addr, play_len, len;
    uint32_t file_addr, file_len;

    //==================================================================================
    //==================================================================================
    file_addr = music_file_offset(data, &file_len, &play_len);
    if (file_len == 0)
        return;
   
    play_addr = file_addr + sizeof(wav_typedef);
    //==================================================================================
    // dma-dac输出音乐数据
    //==================================================================================
    while (play_len != 0)
    {
        //==================================================================================
        // 播放当前缓存,
        //==================================================================================
        if (play_len > DAC_DMA_NUM)
            len = DAC_DMA_NUM;
        else if (play_len > 0)
            len = play_len;
        else
            break;
        
        music_flash_read(play_addr, dac_buf1, len);
        dac_dma_send(dac_buf1, len);
        play_len -= len;
        play_addr += len;
        //==================================================================================
        //  初始化下一缓存数据
        //==================================================================================
        if (play_len > DAC_DMA_NUM)
            len = DAC_DMA_NUM;
        else if (play_len > 0)
            len = play_len;
        else
            break;
        
        music_flash_read(play_addr, dac_buf2, len);
        dac_dma_send(dac_buf2, len);
        play_len -= len;
        play_addr += len;
    }
}

具体细节, 比如每播放一段语音后开始或者结束时都有一点杂音,这些问题已经解决,需要完整源代码的可以私聊我哦,微信电话:18666267395

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现任意波形发生器,可以使用STM32F407微控制器的DACDMATimer功能。 首先,DAC(数字模拟转换器)是用来将数字信号转换为模拟电压输出的设备。STM32F407具有多个DAC通道,每个通道都可以输出一个模拟电压。我们可以使用DAC通道输出的电压值来生成波形。 接下来,我们可以使用DMA(直接内存访问)功能,将要输出的波形数据传输到DAC的数据寄存器中。通过使用DMA,我们可以实现高效的数据传输而无需CPU的干预。可以将波形数据存储在内存数组中,并使用DMA将这些数据发送给DAC通道。 最后,我们可以使用Timer(定时器)功能来控制波形的输出频率。定时器可以产生特定的定时脉冲,用于触发DAC输出的更新。通过配置定时器的预分频器和计数器,在每个定时器更新事件后触发DAC通道输出的更新。这样,我们可以控制波形的输出频率。 具体实现的步骤如下: 1. 配置DAC通道及其输出引脚,并设置DAC工作模式。 2. 配置DMA控制器,设置传输方向为内存到外设,选择波形数据的内存地址和DAC数据寄存器的外设地址。 3. 准备波形数据,可以是正弦波、方波或其他自定义波形,将波形数据存储在内存数组中。 4. 配置定时器,设置预分频器和计数器的值,以控制波形的输出频率。 5. 启动DMA和定时器,开始产生波形。 通过使用STM32F407的DACDMA和定时器功能,可以实现一个任意波形发生器。能够灵活生成各种形状的波形,并且输出频率可以自由调节。这样的实现可以应用于音频信号发生器、信号调试等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CJ773208906

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值