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

将STM32F746G-Disco开发板做助听器  

[复制链接]
shaoziyang 发布时间:2016-3-28 15:27
STM32F746G-Disco开发板上带有数字麦克风和音频输出,它们组合起来就可以实现助听器的功能。只要把麦克风的输入信号进行放大,然后在通过音频接口输出。# {& t5 x+ q2 \7 V" o+ {
+ d! h+ w$ }$ U3 S4 @
下面程序演示了助听器的功能,它来自Mbed例程。首先它通过数字麦克风(U21、U22)获取环境声音,将数据保存到接收缓冲区,然后将数字音频发送到音频输出(U11)。如果我们在CN10(音频输出)上接一个耳机或者扬声器,就可以清楚的听到放大后的环境声音,效果非常不错。在连接耳机时,需要注意保护耳朵,因为开发板上没有音量控制的旋钮,不能调节音量。
5 h" x& r7 J) L. k% Q% a% r) \5 E
7 ?. W0 b+ k8 `2 l) i

  1. + h5 g9 P1 n4 H$ ~2 N3 [3 q, Q

  2. % w, _; c5 z8 Y7 n3 F' I# h: s
  3. #include "mbed.h"
    ) P+ r" L, I- t4 Y: {/ n( B
  4. #include "AUDIO_DISCO_F746NG.h"
    $ s3 U/ _# B. a' h$ C5 v% i" g" f
  5. #include "SDRAM_DISCO_F746NG.h"
    # n7 O9 t+ n  ~

  6. 4 ~( u6 q5 a: q/ c9 l' o
  7. AUDIO_DISCO_F746NG audio; : I- k# Z* D! f, w7 {
  8. // audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized 3 W" K9 o$ t) T0 O% l
  9. // and FMC enabled + I3 W& H3 O+ l/ g) r& ^
  10. SDRAM_DISCO_F746NG sdram;
    5 _6 O  K0 l0 T# i3 _( V! O

  11. $ i5 W0 P$ T6 B" o6 F
  12. DigitalOut led_green(LED1); , a0 T) ~  P' R. d$ w
  13. DigitalOut led_red(LED2); + Q. X7 M! h  P  Z- t
  14. Serial pc(USBTX, USBRX);
    3 M& p) F. [$ c0 F

  15. % r, a) {+ N" \7 S. V
  16. typedef enum 9 C" K6 k6 @1 n& \. {
  17. { " P% {. Q6 `. t6 m3 L) w
  18.     BUFFER_OFFSET_NONE = 0,
    ; L$ t" k  R! \! B
  19.     BUFFER_OFFSET_HALF = 1,
    " I5 e5 N9 q- E( h% F0 E  A9 V
  20.     BUFFER_OFFSET_FULL = 2,
    6 ^. Z5 s( @* h/ {) s3 l: \
  21. }BUFFER_StateTypeDef;
    9 i2 V/ q4 B# Z3 \4 w% ~6 E

  22. 8 S  J( C6 D/ W! H) n: s
  23. #define AUDIO_BLOCK_SIZE   ((uint32_t)512)
    , @% p1 ?2 l. a
  24. #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    0 [' i6 E. S: L) n; w( ^2 E
  25. #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */ ! ^& ?& Y& m2 b1 S: g: M2 q
  26. __IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    : A6 r" g" }3 S% \6 v  Z& M
  27. static uint8_t SetSysClock_PLL_HSE_200MHz();
      ?3 }* l: F. G7 v2 J3 X
  28. int main() ( f# I2 Y2 ]+ w' O
  29. {
    - v& p# N1 W& H) u4 m
  30.     SetSysClock_PLL_HSE_200MHz();
    ' T& |6 g4 W9 Q+ ~3 N9 z* h2 ]
  31.     pc.baud(9600);
    2 ^6 F: P) f  o
  32. # \& g( \! V* z! ~6 `- W
  33.     pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
    5 F' p( o  K! a: h
  34.     led_red = 0; ' J' F7 M1 F& F' I
  35.    % R$ l4 k  C8 g. ?
  36.     pc.printf("\nAUDIO RECORD INIT OK\n"); ) M9 Q' o6 d4 L  {
  37.     pc.printf("Microphones sound streamed to headphones\n");
    7 t. a' \6 Z; v7 f9 a
  38.      
    ; p7 _; G3 X9 y* L8 }2 J
  39.     /* Initialize SDRAM buffers */ 1 F4 x) ~. A) G# Z" o% ~0 `$ |
  40.     memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
    & w7 B; i- r  j8 o
  41.     memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    . b8 c' Q% Y; Q' P3 R* f' c% y
  42.     audio_rec_buffer_state = BUFFER_OFFSET_NONE; 5 y2 r* g, e0 i7 {4 E2 b, j& Z
  43. # J% U1 s2 u- @5 G! n. T
  44.     /* Start Recording */ 9 ~: I. |! L6 m3 d
  45.     audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE); 0 T3 ]2 @, h0 ~

  46. 3 b& g6 M1 G# r
  47.     /* Start Playback */
    $ a" e4 `$ M) s
  48.     audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); ( R1 O/ G# Q' u0 a. `8 [" n" u; n
  49.     audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2); - Z6 \0 E* L7 ~9 h3 K; P

  50. / k$ j1 V0 H. y
  51.     while (1) { 0 K$ l+ T" m3 q* J3 z, |, E
  52.         /* Wait end of half block recording */ / }/ n$ e$ S! d+ q
  53.         while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) { # X& Y# h& o5 s: _' Q0 j" j9 G9 P
  54.         }
    : v4 P: p% e4 e- b; O+ g& h
  55.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    - R% t& M* Y! d6 _; p5 s0 T
  56.         /* Copy recorded 1st half block */ 0 K1 f. `. q+ Z+ Z  p
  57.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
    + M, k' V, e' V" y
  58.         /* Wait end of one block recording */
    9 {: K3 Y0 S% X" o! R( o
  59.         while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) { . O% V4 c7 N/ Q9 |0 s
  60.         } 3 b2 n, ^5 C4 g3 t0 O6 L1 ?
  61.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    1 z, l0 J0 V5 {+ ?4 ?
  62.         /* Copy recorded 2nd half block */ 2 q, l$ N2 Y) i5 H+ t) b6 a
  63.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  ; E+ e) N& q& S# \3 U
  64. + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    3 P# Z, f) G* w& h9 a
  65.     } ) u2 R1 S3 e# {3 L$ U0 O) Z
  66. }
    : Q- w$ v; h' P+ X/ ?$ p+ B; }
  67. /*-------------------------------------------------------------------------------------
    - m5 R, c( r; m) E7 N* A: o% q
  68.        Callbacks implementation: , J! p0 y( _" |0 O
  69.            the callbacks API are defined __weak in the stm32746g_discovery_audio.c file : \1 _9 B8 m0 S# P0 Z
  70.            and their implementation should be done in the user code if they are needed.
    5 u0 W& W2 y4 h" t/ F5 G% A
  71.            Below some examples of callback implementations. % z% f! q, H& @. P# |, @
  72.   -------------------------------------------------------------------------------------*/ ; T4 V' m' K3 `$ u4 H
  73. /** 4 O# O) v& f/ [; K' z, \' g
  74.   * @brief Manages the DMA Transfer complete interrupt. . a7 \' j% K* v/ r# Q
  75.   * @param None , e; \& O4 ^0 H; u
  76.   * @retval None
      h* o; O4 [4 Q& V; E$ L
  77.   */ 2 W9 W& L4 ?0 ?1 E2 R: Y
  78. void BSP_AUDIO_IN_TransferComplete_CallBack(void)
    ; T  ]3 t% l( o. ^5 @
  79. {
    2 a; {# e+ l7 q, {* Z  \- M
  80.   audio_rec_buffer_state = BUFFER_OFFSET_FULL; 0 B% S/ m" ~2 P. [5 }
  81.   return; / v5 t) e0 }4 m
  82. } / |, d: ]" u. W1 Q8 X1 V6 }! Q
  83. * n4 n# G" X7 V, l4 C1 t9 w
  84. /**
    / U( Q0 q; }& ]' e' A
  85.   * @brief  Manages the DMA Half Transfer complete interrupt. 6 g& r- V: n; n7 ?' P- P  {8 u) E9 ^
  86.   * @param  None
    # S2 ?+ A: Y8 P0 ^& i
  87.   * @retval None
    0 }0 ?; t; ?* a5 ?! R  h4 E& }, G
  88.   */ 2 M9 o' D4 w- P+ O: M
  89. void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
    ( Z3 C; E) s2 C6 Z2 D
  90. {
    / e( H& J0 w- x) w
  91.   audio_rec_buffer_state = BUFFER_OFFSET_HALF;
      C/ H! ^/ ], e5 r( P
  92.   return;
    1 s/ P3 f  g3 ^' }; ?
  93. }9 C, @  S( @  p: P% A5 I  t+ v
复制代码

. a7 V( Y  F$ p# x+ W程序分析:
    % n2 _' ^  \3 E& B
  • 首先定义缓冲区大小和音频输入输出缓冲区
    ! a1 ]) h+ G+ N7 ^' F" i" y' A% x% L
    #define AUDIO_BLOCK_SIZE   ((uint32_t)512)# U# A' n$ E* t# d' _
    #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */4 D0 v6 |- u5 h  h5 c, c
    #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  • 然后进行初始化,初始化部分完成下面几个功能:
    ! z8 X# T4 n1 @& f; T2 z2 j6 r" I  _2 W7 p
    • 分配缓冲区
      1 g/ _4 w& T# C% g! l4 Q    /* Initialize SDRAM buffers */+ G( w4 R. y4 g& _, \
          memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
      - d1 l/ |/ C! w4 d7 O+ \% d    memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    • 启用录音功能,将音频输入保存到输入缓冲区8 F! [. t: D& Q- Y; h# q4 A# P
          /* Start Recording */$ a/ x  p2 ?. u: N* X; F
          audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    • 设置音频回放) }3 }( v& M: `% S7 F% Z
          audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);) E4 [/ K- ?  @$ v. A) W* q& f
          audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
      5 u% D- f: j! b6 M" i8 i/ `
  • 在主循环中,等待音频输入完成,然后将输入缓冲区(AUDIO_BUFFER_IN)的数据复制到输出(AUDIO_BUFFER_OUT)缓冲区。音频输入的录音和回放,都是使用DMA方式自动完成的,所以无需CPU处理。7 E6 Q+ U8 n. j. P7 R' F' b$ Q; d

, c6 D; a3 h) ^. p8 R完整参考程序:6 W5 Z; m# w3 n9 |# a4 a
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& O3 o: u/ u# d+ b
谢谢楼主,有实物图或者视频演示就更好啦
- s2 j+ [! ^* N! ]0 X2 S8 e
这个例子主要是通过音频进行测试,不方便视频。有板子的网友试试就知道了,效果很棒。
liangwei 回答时间:2016-6-30 09:06:23
shaoziyang 发表于 2016-6-23 09:44
) _% w. G, e, O需要有源音箱吧,不然带不动

& {& p- c9 `, d' R) q不是的,那个芯片支持2w的喇叭,是软件里面设置了静音
shaoziyang 回答时间:2016-6-23 09:44:08
weiyuliang 发表于 2016-6-22 16:54
+ L% ?5 [& }- h6 f0 \7 g牛,我外接喇叭为啥木声音那
0 C9 K) f4 M- _6 w: A
需要有源音箱吧,不然带不动
沐紫 回答时间: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 手机版