你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

将STM32F746G-Disco开发板做助听器  

[复制链接]
shaoziyang 发布时间:2016-3-28 15:27
STM32F746G-Disco开发板上带有数字麦克风和音频输出,它们组合起来就可以实现助听器的功能。只要把麦克风的输入信号进行放大,然后在通过音频接口输出。

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



  1. #include "mbed.h"
  2. #include "AUDIO_DISCO_F746NG.h"
  3. #include "SDRAM_DISCO_F746NG.h"

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

  8. DigitalOut led_green(LED1);
  9. DigitalOut led_red(LED2);
  10. Serial pc(USBTX, USBRX);

  11. typedef enum
  12. {
  13.     BUFFER_OFFSET_NONE = 0,
  14.     BUFFER_OFFSET_HALF = 1,
  15.     BUFFER_OFFSET_FULL = 2,
  16. }BUFFER_StateTypeDef;

  17. #define AUDIO_BLOCK_SIZE   ((uint32_t)512)
  18. #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
  19. #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  20. __IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
  21. static uint8_t SetSysClock_PLL_HSE_200MHz();
  22. int main()
  23. {
  24.     SetSysClock_PLL_HSE_200MHz();
  25.     pc.baud(9600);

  26.     pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
  27.     led_red = 0;
  28.    
  29.     pc.printf("\nAUDIO RECORD INIT OK\n");
  30.     pc.printf("Microphones sound streamed to headphones\n");
  31.      
  32.     /* Initialize SDRAM buffers */
  33.     memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
  34.     memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
  35.     audio_rec_buffer_state = BUFFER_OFFSET_NONE;

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

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

  41.     while (1) {
  42.         /* Wait end of half block recording */
  43.         while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
  44.         }
  45.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
  46.         /* Copy recorded 1st half block */
  47.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
  48.         /* Wait end of one block recording */
  49.         while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
  50.         }
  51.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
  52.         /* Copy recorded 2nd half block */
  53.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  
  54. + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
  55.     }
  56. }
  57. /*-------------------------------------------------------------------------------------
  58.        Callbacks implementation:
  59.            the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
  60.            and their implementation should be done in the user code if they are needed.
  61.            Below some examples of callback implementations.
  62.   -------------------------------------------------------------------------------------*/
  63. /**
  64.   * @brief Manages the DMA Transfer complete interrupt.
  65.   * @param None
  66.   * @retval None
  67.   */
  68. void BSP_AUDIO_IN_TransferComplete_CallBack(void)
  69. {
  70.   audio_rec_buffer_state = BUFFER_OFFSET_FULL;
  71.   return;
  72. }

  73. /**
  74.   * @brief  Manages the DMA Half Transfer complete interrupt.
  75.   * @param  None
  76.   * @retval None
  77.   */
  78. void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
  79. {
  80.   audio_rec_buffer_state = BUFFER_OFFSET_HALF;
  81.   return;
  82. }
复制代码

程序分析:

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

    #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处理。

完整参考程序:
DISCO-F746NG_AUDIO_demo_uvision_disco_f746ng.zip (1.47 MB, 下载次数: 72)

评分

参与人数 1 ST金币 +30 收起 理由
沐紫 + 30 赞一个!

查看全部评分

收藏 3 评论27 发布时间:2016-3-28 15:27

举报

27个回答
shaoziyang 回答时间:2016-3-28 15:51:39
沐紫 发表于 2016-3-28 15:33
谢谢楼主,有实物图或者视频演示就更好啦

这个例子主要是通过音频进行测试,不方便视频。有板子的网友试试就知道了,效果很棒。
liangwei 回答时间:2016-6-30 09:06:23
shaoziyang 发表于 2016-6-23 09:44
需要有源音箱吧,不然带不动

不是的,那个芯片支持2w的喇叭,是软件里面设置了静音
shaoziyang 回答时间:2016-6-23 09:44:08
weiyuliang 发表于 2016-6-22 16:54
牛,我外接喇叭为啥木声音那

需要有源音箱吧,不然带不动
沐紫 回答时间:2016-3-28 15:33:47
谢谢楼主,有实物图或者视频演示就更好啦
风子 回答时间:2016-3-28 17:50:05
看看     
DLGG-308046 回答时间:2016-3-28 21:28:03
看看学习下
macosx 回答时间:2016-3-28 23:27:29
能在 F4 上實現嗎?來學習一下!
liangwei 回答时间:2016-6-22 16:54:43
牛,我外接喇叭为啥木声音那
vitence 回答时间:2016-6-30 13:37:27
学习一下
babyfeng 回答时间:2016-7-10 22:24:33
谢谢分享 学习下
DLGG-308046 回答时间:2016-8-29 14:07:36
请教一下,程序中音频输入的录音和回放的DMA配置是怎么实现的?
zhangxu56726 回答时间:2016-8-29 15:07:40
dddddddddddddddddddddddd
涛哥2035 回答时间:2016-8-29 15:55:57
实用的是不是都是模拟的啊?
xyx365 回答时间:2016-8-30 08:46:47
学习一下
12下一页
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版