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

将STM32F746G-Disco开发板做助听器  

[复制链接]
shaoziyang 发布时间:2016-3-28 15:27
STM32F746G-Disco开发板上带有数字麦克风和音频输出,它们组合起来就可以实现助听器的功能。只要把麦克风的输入信号进行放大,然后在通过音频接口输出。; J" g8 ~' W  U% Q$ y% o
6 {: @: J) z, A& h. \
下面程序演示了助听器的功能,它来自Mbed例程。首先它通过数字麦克风(U21、U22)获取环境声音,将数据保存到接收缓冲区,然后将数字音频发送到音频输出(U11)。如果我们在CN10(音频输出)上接一个耳机或者扬声器,就可以清楚的听到放大后的环境声音,效果非常不错。在连接耳机时,需要注意保护耳朵,因为开发板上没有音量控制的旋钮,不能调节音量。$ E1 \6 t+ e2 J- ~# q* ?6 q

2 q- v# c  }9 a1 R( y, D& D& y( m
  1. 0 G; q3 y) h  f, m9 {4 l. ~

  2. ' c) g& n. n+ H" \9 k: q
  3. #include "mbed.h"
    % S. ^- \+ v$ S$ T. E. z
  4. #include "AUDIO_DISCO_F746NG.h"
    , e! b$ ], r1 ^7 K2 ?8 {/ r5 j6 L
  5. #include "SDRAM_DISCO_F746NG.h" : e3 S# I$ O5 H$ R( W- D$ U/ O  k
  6. $ O" {( n5 G1 o
  7. AUDIO_DISCO_F746NG audio;
    . ]+ y9 r4 w% f% T+ |; Z
  8. // audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized + k' r3 [, {2 h. e0 y/ `
  9. // and FMC enabled ! i8 b- u- m, o9 ?  v2 {8 K
  10. SDRAM_DISCO_F746NG sdram;
    9 f+ J4 H, U% `3 w, E% p2 C! Y! ]

  11. ' p$ d6 A  m( E- `, Z% T- q6 l. u
  12. DigitalOut led_green(LED1);
    5 \  N" B0 ]' U0 u
  13. DigitalOut led_red(LED2);
    $ c5 f4 u& O1 V
  14. Serial pc(USBTX, USBRX);
    % C2 Z. w! P( ?5 R4 V. v$ V

  15. 5 d2 }( |& q. V  \8 i3 i0 E' T
  16. typedef enum 7 e1 N' C% }4 \8 v* f
  17. { 5 C4 o0 A8 B5 D" t! w, |
  18.     BUFFER_OFFSET_NONE = 0,
    " S2 ~; A' |2 S, t
  19.     BUFFER_OFFSET_HALF = 1, 7 f7 j6 O& W8 w0 _
  20.     BUFFER_OFFSET_FULL = 2, 9 _0 \% l: g: K9 q! M
  21. }BUFFER_StateTypeDef;
    6 H: g( @! Y6 f! u9 k

  22.   L/ F/ a7 c* e0 w( D
  23. #define AUDIO_BLOCK_SIZE   ((uint32_t)512)
    , `+ ]$ v6 Z* K- P5 \2 C
  24. #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    4 h# e) k3 n% h( R% L
  25. #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */ $ d/ g& a7 L- H/ r
  26. __IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    ) z3 G- D( h5 l& |; f
  27. static uint8_t SetSysClock_PLL_HSE_200MHz(); " }# o0 ]5 A/ c- b; L" [$ Q4 P
  28. int main() 8 P8 f- c% f8 p  q
  29. {
    & F6 r, Z8 ?7 K4 f
  30.     SetSysClock_PLL_HSE_200MHz(); ! d6 U1 T! a  R! ?; m
  31.     pc.baud(9600);
    & ]+ D! p* Z; z6 u! N7 T

  32. $ y7 ?2 K! X# _. u0 H: K
  33.     pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
    : k( i/ x. b  `# {- g8 s
  34.     led_red = 0; 9 |6 e- P6 C7 M  s
  35.    ' z, |; H6 M% `" u( f
  36.     pc.printf("\nAUDIO RECORD INIT OK\n");
    7 m9 N! k. L7 P3 C) f* c
  37.     pc.printf("Microphones sound streamed to headphones\n");
    ; t  Y6 a$ I+ n
  38.      - G2 u& c6 u1 M9 l- [: C6 ~! E
  39.     /* Initialize SDRAM buffers */
    2 q; P- l; X1 w8 m# h. N
  40.     memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2); ) S" h# i( ~$ m# E
  41.     memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2); 4 X) p3 n$ m" M9 B7 ^6 V
  42.     audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    & z- [3 n6 F9 P3 a, p

  43. $ A' h; x* H- D# D- o3 ~) ~
  44.     /* Start Recording */ ' ~( I5 L$ U. J9 w# C. A+ J  N4 L
  45.     audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE); 2 s, D& q: I9 {' o0 n. r

  46. 0 R$ q) H9 e% x! Q
  47.     /* Start Playback */ 8 U" K, P( t& @2 k
  48.     audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
    ( ~% @! b1 A9 v, E1 g
  49.     audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
    5 {2 M5 w  o# m

  50. 6 Q8 {4 _$ R1 O
  51.     while (1) { 4 f2 f5 h- e. A5 s4 h5 Q
  52.         /* Wait end of half block recording */ - e7 J$ \3 _; a& O4 r
  53.         while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
    1 a: E" c+ Q9 E! J# c% X. k& `
  54.         } ! `! n  J. h  P. N; l
  55.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    3 t; H2 y: m  P; L" W
  56.         /* Copy recorded 1st half block */
    3 Y3 V. F  f/ s% \. c8 L
  57.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE); & O# _8 Y/ h9 Y  d6 F+ g/ B
  58.         /* Wait end of one block recording */ , F% C: v& q) n4 Q
  59.         while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
      {' n/ P# @# z# V/ ]
  60.         }   j4 Y6 y$ H( f6 B8 ?: w) b
  61.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    + _$ v& [, f0 J# a8 W+ n. E
  62.         /* Copy recorded 2nd half block */
    9 C- D8 d/ I9 d" I% ~0 N# p7 J
  63.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  4 o) @! e3 s' l) f6 s/ H
  64. + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    9 E+ J2 _3 z4 C
  65.     }
    ; g# |& Z1 F3 N' d# y3 ^
  66. }
      o, H* n  m4 q$ u4 P0 r; O. D
  67. /*------------------------------------------------------------------------------------- , w0 a# A8 w3 @" U3 `3 l7 f4 r
  68.        Callbacks implementation: - d: M+ q5 L6 l# b
  69.            the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
    ; c- Y$ T- Y  D, A2 F7 J
  70.            and their implementation should be done in the user code if they are needed. / K. ^! z% U6 S# L
  71.            Below some examples of callback implementations.
    # A4 E$ L8 }, y# e
  72.   -------------------------------------------------------------------------------------*/
    2 C" e' s0 f9 X" p# A
  73. /** ' W9 x& [+ }! C" c7 t) D; C
  74.   * @brief Manages the DMA Transfer complete interrupt.
    ; M$ b+ G' L+ @. ?7 W# E5 d3 ?
  75.   * @param None 8 u7 @6 @2 W1 Y1 S
  76.   * @retval None
    3 e# A7 v+ `/ ^4 \  E
  77.   */
    - |( ~4 Q0 p6 P9 G& A( q
  78. void BSP_AUDIO_IN_TransferComplete_CallBack(void) ; d) d0 R) B* e1 a& K' _5 f
  79. { - `0 Q' C" U: f/ c! h
  80.   audio_rec_buffer_state = BUFFER_OFFSET_FULL;
    ; s2 ^: v9 s; q3 i  a
  81.   return;
    % Q$ Y* a! L; g4 n0 f7 _' M5 n! z/ I
  82. }
    4 ?% a* I% S6 S: Q$ ^
  83. % D* v7 t& ?. u% ]( L; c; k6 r2 Y0 ~
  84. /** 2 n# T0 s2 Z# l" r2 c1 S0 k
  85.   * @brief  Manages the DMA Half Transfer complete interrupt. 1 l; {* v/ D! I
  86.   * @param  None 7 h. Q) |; z! F2 _( h
  87.   * @retval None ' S; w) J- w% `
  88.   */
    # D- r$ ^, z& H% b1 T
  89. void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
      u" F* R: x5 z  E" o8 e, e2 m5 l
  90. {
    ! W0 w6 f2 p9 w0 o. M
  91.   audio_rec_buffer_state = BUFFER_OFFSET_HALF; , o+ P3 i% {+ k! m, E* s
  92.   return; ) s; N1 ]& Q# x& c
  93. }
    , C1 e9 @5 I, L3 m
复制代码
; J  _/ h" o8 P/ ~0 L$ i# O0 I
程序分析:
    4 ?0 u2 ]9 W' [! N3 R) r8 d& T/ r% q
  • 首先定义缓冲区大小和音频输入输出缓冲区
    ; g6 l" n1 d5 A( D  K3 x
    , m# i9 C+ u& L& _" F# s3 e! Y#define AUDIO_BLOCK_SIZE   ((uint32_t)512)
    , _* W$ U2 x  V( S: d3 _& u. K#define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    7 s/ e' b3 `( _9 @+ W#define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  • 然后进行初始化,初始化部分完成下面几个功能:
    # Y% \, |  Y! m1 d0 m  h: d5 B
    • 分配缓冲区
      1 |9 v$ c6 p/ m) c- P; e    /* Initialize SDRAM buffers */7 x0 B4 P# P8 v4 e; y& t2 c
          memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);/ k! t: Z* ]5 y6 x
          memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    • 启用录音功能,将音频输入保存到输入缓冲区- m" i# d& b3 F; d. e) S+ o9 h; S6 G7 k
          /* Start Recording */6 _- i- H' T4 K. F; y, q
          audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    • 设置音频回放6 y/ c* R+ ]0 @( e" l7 X
          audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
      6 w4 K" O0 ~/ s( {. A3 Y* B: e/ t    audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
      5 d- x: T  @+ G0 L5 d$ T1 ?
  • 在主循环中,等待音频输入完成,然后将输入缓冲区(AUDIO_BUFFER_IN)的数据复制到输出(AUDIO_BUFFER_OUT)缓冲区。音频输入的录音和回放,都是使用DMA方式自动完成的,所以无需CPU处理。
    " }0 Z& A6 O5 {* l' O6 l. q$ o
9 j0 n. d$ ]7 l+ Q) D/ i7 D9 _( X
完整参考程序:9 v4 y* b- h# v1 N$ k6 e
DISCO-F746NG_AUDIO_demo_uvision_disco_f746ng.zip (1.47 MB, 下载次数: 73)

评分

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

查看全部评分

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

举报

27个回答
shaoziyang 回答时间:2016-3-28 15:51:39
沐紫 发表于 2016-3-28 15:33
" |1 W/ m2 ^7 f( _谢谢楼主,有实物图或者视频演示就更好啦
( i$ G# w. T0 Q  N3 J5 O( L; S
这个例子主要是通过音频进行测试,不方便视频。有板子的网友试试就知道了,效果很棒。
liangwei 回答时间:2016-6-30 09:06:23
shaoziyang 发表于 2016-6-23 09:44
2 N) N! \2 r8 a8 s8 X9 \5 Z需要有源音箱吧,不然带不动

2 z6 r% e# P. I" c+ d4 r不是的,那个芯片支持2w的喇叭,是软件里面设置了静音
shaoziyang 回答时间:2016-6-23 09:44:08
weiyuliang 发表于 2016-6-22 16:54
0 D5 }( U; u' K. }8 W4 t7 z牛,我外接喇叭为啥木声音那
! a' Y3 O3 ?0 _
需要有源音箱吧,不然带不动
沐紫 回答时间: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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版