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

将STM32F746G-Disco开发板做助听器  

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

5 V1 J# ]( y, L+ m# V. n下面程序演示了助听器的功能,它来自Mbed例程。首先它通过数字麦克风(U21、U22)获取环境声音,将数据保存到接收缓冲区,然后将数字音频发送到音频输出(U11)。如果我们在CN10(音频输出)上接一个耳机或者扬声器,就可以清楚的听到放大后的环境声音,效果非常不错。在连接耳机时,需要注意保护耳朵,因为开发板上没有音量控制的旋钮,不能调节音量。4 `/ N- `1 m: ]6 ?8 S
' f, ]  N1 g; a0 ?
  1. . A/ G$ E% R, w: A! ]7 d& g8 S# S

  2. ) b& K- N) A5 j' J; o
  3. #include "mbed.h" 8 R9 h2 V& X  Z/ g5 x7 ?. a% z
  4. #include "AUDIO_DISCO_F746NG.h" 2 g5 q6 w  I: _; {. s; D  j
  5. #include "SDRAM_DISCO_F746NG.h"
    . H$ K; _& o7 T/ I+ X% U+ \' ^

  6. 5 E- F$ B( y) C3 Y
  7. AUDIO_DISCO_F746NG audio;
    ; q1 z- y& P" R; {
  8. // audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized
    , `! g# l, |( g. g' T% W! P/ ?
  9. // and FMC enabled
    ( }& ~7 N' t3 ]$ b9 L9 Z
  10. SDRAM_DISCO_F746NG sdram;
    $ m! \) K3 I- |6 |& U
  11. * x+ \' d( W$ R8 y, ~9 c
  12. DigitalOut led_green(LED1);   @/ X6 V7 T: C9 v1 `) N1 }- B9 E( S
  13. DigitalOut led_red(LED2); 3 S, R3 h) {+ i6 C- C/ o
  14. Serial pc(USBTX, USBRX);
    7 L& V1 O) O8 U$ i
  15. 2 p& t6 @( c  O+ u( q# c  G
  16. typedef enum 8 Q+ E& a, R7 I. a0 f
  17. { 3 }& L& r8 t$ I0 c; D
  18.     BUFFER_OFFSET_NONE = 0, 9 @4 m2 N6 @5 c: t
  19.     BUFFER_OFFSET_HALF = 1, $ `9 W3 T8 _' h8 |( U
  20.     BUFFER_OFFSET_FULL = 2, 1 r: |0 I. t/ o
  21. }BUFFER_StateTypeDef; % f5 n* w- K1 J1 m" ?- |8 n

  22. 5 N& Z# j9 @5 B9 R
  23. #define AUDIO_BLOCK_SIZE   ((uint32_t)512) : j9 }6 G3 w9 t" h( M' d
  24. #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    : Q" v8 D8 K$ n: m& k( q# N
  25. #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */ 3 O2 K- y  \- _2 {- L: l3 o
  26. __IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE; 9 Y7 U" o. a* }# S* u: A7 e5 v
  27. static uint8_t SetSysClock_PLL_HSE_200MHz();
    " V( `( r; j3 x5 _6 s2 [
  28. int main() ' y6 A$ p5 e3 h  `( `, B+ u
  29. {
    ) V7 _6 ]/ d/ H
  30.     SetSysClock_PLL_HSE_200MHz();
    ( u9 t5 Q+ I, {4 T" C5 p% @3 `
  31.     pc.baud(9600); 7 U8 ~2 D7 ]5 K$ x7 E# P$ ~9 E

  32. % o- r! j8 e$ z5 r
  33.     pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n"); $ @  Q8 Z+ P9 u; M: [( N
  34.     led_red = 0;
    2 F# M6 |4 d2 n8 u; ^
  35.    # L3 g( v, A8 v
  36.     pc.printf("\nAUDIO RECORD INIT OK\n"); " p# g9 O  a) h7 _1 [& h) e
  37.     pc.printf("Microphones sound streamed to headphones\n");
    . \: G( g, |& K# \# f4 |% ?
  38.      
    / S7 e/ D4 _# J: U5 o
  39.     /* Initialize SDRAM buffers */
    - M) g& H: j. k6 H2 {& k
  40.     memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2); 3 r2 n. H, c9 |# g
  41.     memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2); 7 y5 }. v, f; [6 |) Q/ N
  42.     audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    3 G2 v% k$ q0 Z: F2 T/ E- R
  43. ' d! j! t/ s( ]: h
  44.     /* Start Recording */ / F! q3 {) v: c: Y
  45.     audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE); , [! r& N& w* a+ x$ B6 Y+ b6 z
  46. 2 E. m6 c4 X7 L# R# [
  47.     /* Start Playback */ 7 ~" |" K; |" u% _; _2 ^- A% g
  48.     audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);
    3 a% w) L; X6 H! k$ R. J) e, s
  49.     audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
    5 e( q' [  G; T9 z8 [$ Z- I
  50. 1 C+ t" D8 C/ K" M+ L4 Z# `3 U  J
  51.     while (1) {
    + z0 A; `& h6 ?% `. C8 d
  52.         /* Wait end of half block recording */ / C6 Z7 z( Z  x5 E( b& S  S/ S2 b
  53.         while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) { % Q5 o; Y' x/ g% l9 S3 \$ N! Q
  54.         } 2 v. g4 K1 c! S/ N
  55.         audio_rec_buffer_state = BUFFER_OFFSET_NONE; 8 Q* Q/ `% m# Q2 ~- Q( S
  56.         /* Copy recorded 1st half block */ / [% l0 l1 g+ |* H
  57.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE); / g, B5 m! y6 T2 k$ D
  58.         /* Wait end of one block recording */ # L8 G5 e: O9 N. `2 N9 b+ @4 `
  59.         while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) { ; Q. ^9 K: S/ U( M# v0 L) y
  60.         }
    : L' T2 v; G' K( |$ W
  61.         audio_rec_buffer_state = BUFFER_OFFSET_NONE; 6 E8 W3 r% j- V, D. Z2 `1 r
  62.         /* Copy recorded 2nd half block */
    $ |% t; g1 O1 e$ L, M
  63.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  % h2 W8 E+ G$ d3 U
  64. + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    $ n9 e( r5 t+ G# f, e, C1 ]! F
  65.     }
    4 u8 R& i! F1 _$ [# M- j- E! z
  66. }
    . a2 b7 Z" `: d$ S- A2 f$ r
  67. /*------------------------------------------------------------------------------------- - @: m  l) }: W/ L6 W4 b- j. s% h
  68.        Callbacks implementation:
    / D% W5 Z2 S  ~( |1 c8 L6 [/ n
  69.            the callbacks API are defined __weak in the stm32746g_discovery_audio.c file + n7 S+ x1 L4 D; R! b5 l2 t( }
  70.            and their implementation should be done in the user code if they are needed. ' t: |7 M9 j) f+ A8 v- Z
  71.            Below some examples of callback implementations. 5 O5 h6 Z% S% C
  72.   -------------------------------------------------------------------------------------*/ 7 v/ b1 f/ y) ^" B
  73. /** ) Q/ B$ m7 E5 h4 \7 e
  74.   * @brief Manages the DMA Transfer complete interrupt. 4 Z/ f5 g6 V  Z
  75.   * @param None ) b: Y2 Q2 j. S. W' b$ S5 I
  76.   * @retval None ! W3 k* J2 b' \& d
  77.   */ * H2 @- H  N( V! P  F$ u
  78. void BSP_AUDIO_IN_TransferComplete_CallBack(void)
    . I/ k- e4 H1 S# }  ^8 j
  79. {
    , z7 k' G0 @8 K9 m4 b' F
  80.   audio_rec_buffer_state = BUFFER_OFFSET_FULL;
    # @. x+ f6 u) g  J
  81.   return; ! J  R% D! W; E! t0 K
  82. }
    / B/ J1 m3 a1 I: `1 ~4 y
  83. : d# U& ?7 j7 s5 s
  84. /** $ f' f" l1 z& D/ t1 A# h
  85.   * @brief  Manages the DMA Half Transfer complete interrupt.
    , B* w1 @; E. @
  86.   * @param  None ' M; N2 w: R- {1 h7 t
  87.   * @retval None 1 c5 k+ T$ Y* M( F; q  ~- W
  88.   */
    0 I- O5 r2 W% I/ [
  89. void BSP_AUDIO_IN_HalfTransfer_CallBack(void)   R' j3 B! n" _7 t$ v1 Q4 G
  90. {
    9 o6 I! D! l: f$ g' `* Z- ~* U
  91.   audio_rec_buffer_state = BUFFER_OFFSET_HALF; - d; V+ Q2 v# v5 Z( C
  92.   return; " t& [; g0 |* t# h( j
  93. }- H8 p3 q; Q& K; G0 |2 [6 C$ ]7 }
复制代码

9 b) f8 b, |  ^( G程序分析:
    6 a3 v) C1 Y; X9 f1 C7 Q" Y8 @& x
  • 首先定义缓冲区大小和音频输入输出缓冲区8 P, c% e1 i" z# h- V) v5 P
    ' y# i" S( {: c2 G# O' V4 ^) N
    #define AUDIO_BLOCK_SIZE   ((uint32_t)512)
    4 |% q* }: D( L0 {" S( M" ?6 u#define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    0 M& a$ R8 c. u) K$ p. B#define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  • 然后进行初始化,初始化部分完成下面几个功能:
    6 z7 p$ j! A: j) T: X! L# s% g
    • 分配缓冲区& _+ P5 ~, V3 o% ~2 Q* W  v
          /* Initialize SDRAM buffers */8 Y# K0 B  v5 \/ v7 \4 q" j
          memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);' w" s6 L% U8 Q8 H
          memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    • 启用录音功能,将音频输入保存到输入缓冲区0 S7 e$ y# s& }, p+ D+ d
          /* Start Recording */
      3 m1 u+ c, N" Z: g" T" [    audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    • 设置音频回放
      ' Q5 d$ Q' U* r* f) H; y    audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);6 c" y1 M0 s5 U+ y8 z3 n
          audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);
      2 f4 y+ q  X1 N0 G
  • 在主循环中,等待音频输入完成,然后将输入缓冲区(AUDIO_BUFFER_IN)的数据复制到输出(AUDIO_BUFFER_OUT)缓冲区。音频输入的录音和回放,都是使用DMA方式自动完成的,所以无需CPU处理。
    % N' g4 ~; Y0 @) }$ k. l. C5 s

3 {# ]  K9 G7 M  d1 p: t  Z完整参考程序:
: `0 H2 M$ D" p+ D, g DISCO-F746NG_AUDIO_demo_uvision_disco_f746ng.zip (1.47 MB, 下载次数: 69)

评分

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

查看全部评分

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

举报

27个回答
shaoziyang 回答时间:2016-3-28 15:51:39
沐紫 发表于 2016-3-28 15:33* g& K* A  k2 E" L0 n
谢谢楼主,有实物图或者视频演示就更好啦

1 A4 `+ T; X. u: i3 E4 n. m这个例子主要是通过音频进行测试,不方便视频。有板子的网友试试就知道了,效果很棒。
liangwei 回答时间:2016-6-30 09:06:23
shaoziyang 发表于 2016-6-23 09:44
3 ]& y* z8 R8 ?3 V. Q' L需要有源音箱吧,不然带不动

" ~( A* M4 G- n% G! r. [不是的,那个芯片支持2w的喇叭,是软件里面设置了静音
shaoziyang 回答时间:2016-6-23 09:44:08
weiyuliang 发表于 2016-6-22 16:546 H$ v: U1 K/ x" s- x
牛,我外接喇叭为啥木声音那
2 G, p4 n" r! t' V
需要有源音箱吧,不然带不动
沐紫 回答时间: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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版