4341|5

1228

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

请教mbed里DISCO-F746NG_AUDIO_demo例程DMA实现方式 [复制链接]

下边这段转自其他论坛,貌似不让发连接,我斗胆直接粘过来了,请作者见谅@dcexpert
{


STM32F746G-Disco开发板上带有数字麦克风和音频输出,它们组合起来就可以实现助听器的功能。只要把麦克风的输入信号进行放大,然后在通过音频接口输出。

下面程序演示了助听器的功能,它来自Mbed例程。首先它通过数字麦克风(U21、U22)获取环境声音,将数据保存到接收缓冲区,然后将数字音频发送到音频输出(U11)。如果我们在CN10(音频输出)上接一个耳机或者扬声器,就可以清楚的听到放大后的环境声音,效果非常不错。在连接耳机时,需要注意保护耳朵,因为开发板上没有音量控制的旋钮,不能调节音量。





#include "mbed.h"
#include "AUDIO_DISCO_F746NG.h"
#include "SDRAM_DISCO_F746NG.h"

AUDIO_DISCO_F746NG audio;
// audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized
// and FMC enabled
SDRAM_DISCO_F746NG sdram;

DigitalOut led_green(LED1);
DigitalOut led_red(LED2);
Serial pc(USBTX, USBRX);

typedef enum
{
    BUFFER_OFFSET_NONE = 0,
    BUFFER_OFFSET_HALF = 1,
    BUFFER_OFFSET_FULL = 2,
}BUFFER_StateTypeDef;

#define AUDIO_BLOCK_SIZE   ((uint32_t)512)
#define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
#define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
__IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
static uint8_t SetSysClock_PLL_HSE_200MHz();
int main()
{
    SetSysClock_PLL_HSE_200MHz();
    pc.baud(9600);

    pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
    led_red = 0;

    pc.printf("\nAUDIO RECORD INIT OK\n");
    pc.printf("Microphones sound streamed to headphones\n");

    /* Initialize SDRAM buffers */
    memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
    memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    audio_rec_buffer_state = BUFFER_OFFSET_NONE;

    /* Start Recording */
    audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);

    /* Start Playback */
    audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
    audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);

    while (1) {
        /* Wait end of half block recording */
        while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
        }
        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        /* Copy recorded 1st half block */
        memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
        /* Wait end of one block recording */
        while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
        }
        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        /* Copy recorded 2nd half block */
        memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  
+ (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    }
}
/*-------------------------------------------------------------------------------------
       Callbacks implementation:
           the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
           and their implementation should be done in the user code if they are needed.
           Below some examples of callback implementations.
  -------------------------------------------------------------------------------------*/
/**
  * @brief Manages the DMA Transfer complete interrupt.
  * @param None
  * @retval None
  */
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_FULL;
  return;
}

/**
  * @brief  Manages the DMA Half Transfer complete interrupt.
  * @param  None
  * @retval None
  */
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_HALF;
  return;
}

程序分析:

  • 首先定义缓冲区大小和音频输入输出缓冲区

    #define AUDIO_BLOCK_SIZE   ((uint32_t)512)
    #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  • 然后进行初始化,初始化部分完成下面几个功能:
    • 分配缓冲区
          /* Initialize SDRAM buffers */
          memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
          memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    • 启用录音功能,将音频输入保存到输入缓冲区
          /* Start Recording */
          audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    • 设置音频回放
          audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
          audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
  • 在主循环中,等待音频输入完成,然后将输入缓冲区(AUDIO_BUFFER_IN)的数据复制到输出(AUDIO_BUFFER_OUT)缓冲区。音频输入的录音和回放,都是使用DMA方式自动完成的,所以无需CPU处理。



}


请教一下,程序中音频输入的录音和回放的DMA配置是怎么实现的?


此帖出自stm32/stm8论坛

最新回复

nmg
你不懒给我们讲解你理解的DMA,100字以内  详情 回复 发表于 2016-8-29 17:38
点赞 关注
个人签名

喝最烈的酒,..DIY最实用的东西

 

回复
举报

1万

帖子

24

TA的资源

版主

沙发
 
这就是Mbed官方的一个例程。具体实现是先设置好缓冲区,在设置外设,最后在主程序中查询标志位,然后复制数据。

它并不是完全自动化,只是录音和回放部分是DMA方式,有数据就自动播放。
此帖出自stm32/stm8论坛

点评

哦 谢谢。 刚才在群里人民币的幻想为我耐心的讲解了DMA,受益匪浅,结合这个例子我再学习学习,非常感谢  详情 回复 发表于 2016-8-29 16:11
 
 

回复

1228

帖子

0

TA的资源

纯净的硅(高级)

板凳
 
dcexpert 发表于 2016-8-29 15:49
这就是Mbed官方的一个例程。具体实现是先设置好缓冲区,在设置外设,最后在主程序中查询标志位,然后复制数 ...

哦 谢谢。
刚才在群里人民币的幻想为我耐心的讲解了DMA,受益匪浅,结合这个例子我再学习学习,非常感谢
此帖出自stm32/stm8论坛

点评

nmg
你不懒给我们讲解你理解的DMA,100字以内  详情 回复 发表于 2016-8-29 17:38
这个例子比较有趣,可以试试,就是要注意音量控制,开发板上没有音量控制。  详情 回复 发表于 2016-8-29 16:14
 
个人签名

喝最烈的酒,..DIY最实用的东西

 

回复

1万

帖子

24

TA的资源

版主

4
 
lidonglei1 发表于 2016-8-29 16:11
哦 谢谢。
刚才在群里人民币的幻想为我耐心的讲解了DMA,受益匪浅,结合这个例子我再学习学习,非常感谢

这个例子比较有趣,可以试试,就是要注意音量控制,开发板上没有音量控制。
此帖出自stm32/stm8论坛
 
 
 

回复

5263

帖子

236

TA的资源

管理员

5
 
lidonglei1 发表于 2016-8-29 16:11
哦 谢谢。
刚才在群里人民币的幻想为我耐心的讲解了DMA,受益匪浅,结合这个例子我再学习学习,非常感谢

你不懒给我们讲解你理解的DMA,100字以内
此帖出自stm32/stm8论坛
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

这个图就是我理解的这个程序。 [attachimg]256304[/attachimg] 还没找到DMA的具体资料,目前我认为(不一定对)F7里有2个DMA,每个DMA有8个数据流,也就是可以同时(并行)执行16个数据搬移(我开始以为是每个DM  详情 回复 发表于 2016-8-30 08:26
 
 
 

回复

1228

帖子

0

TA的资源

纯净的硅(高级)

6
 
nmg 发表于 2016-8-29 17:38
你不懒给我们讲解你理解的DMA,100字以内

这个图就是我理解的这个程序。


还没找到DMA的具体资料,目前我认为(不一定对)F7里有2个DMA,每个DMA有8个数据流,也就是可以同时(并行)执行16个数据搬移(我开始以为是每个DMA只能执行1个搬运,所以这个程序内部是用memcpy搬运的)。
此帖出自stm32/stm8论坛
 
个人签名

喝最烈的酒,..DIY最实用的东西

 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表