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

将STM32F746G-Disco开发板做助听器  

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

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

# Y7 d+ A+ H& {

  1. % `* m! L) S( s. `& Z1 L. `' b6 M0 }9 j
  2. / A$ m( Z+ B: ~- ]
  3. #include "mbed.h" : a4 p9 l% H8 O$ I6 c
  4. #include "AUDIO_DISCO_F746NG.h" 7 R) Y+ Y1 R/ K$ v- K
  5. #include "SDRAM_DISCO_F746NG.h"
    & ?) l* _! P+ M( ^$ m% m( T% l

  6. $ a1 k3 T' n8 }/ g" h. I
  7. AUDIO_DISCO_F746NG audio; $ b) |  _$ ]+ I" I/ u
  8. // audio IN_OUT buffer is stored in the SDRAM, SDRAM needs to be initialized
    / M6 C7 a& B7 F7 i; q6 d  c6 U
  9. // and FMC enabled
    - ]2 {3 k& B  i; G0 W. x! t
  10. SDRAM_DISCO_F746NG sdram;
    * Z* y- l, r9 R; e- f0 N! ]

  11. 5 q0 V8 E8 v! k/ Y" t. N
  12. DigitalOut led_green(LED1);
    ' M3 E2 y( e0 u( P; N
  13. DigitalOut led_red(LED2);
    2 L3 _4 r* B" o2 D" f3 e- ]' v' @# K
  14. Serial pc(USBTX, USBRX);
    # A. C& t4 l* ]1 g) d& t- O
  15. 5 C  I0 b- B( X0 u/ Y* L
  16. typedef enum % w" f$ w  i! C: M* T7 K5 M' [
  17. {
    ) I' ^2 ?6 Q, x  p" M
  18.     BUFFER_OFFSET_NONE = 0,
    : l) T: i" Q: L) K: ?" x) Y  \! p
  19.     BUFFER_OFFSET_HALF = 1, 1 B1 ~( D# B/ U+ J; b
  20.     BUFFER_OFFSET_FULL = 2,
    ! _7 y% r" z* D" K) b2 o
  21. }BUFFER_StateTypeDef;
    6 [3 Z9 }3 [& f( x/ }1 \
  22. $ b9 h6 S% A! C+ e
  23. #define AUDIO_BLOCK_SIZE   ((uint32_t)512)   i. U8 j, u9 r& m  a+ v
  24. #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */
    , g8 S& C4 U2 r5 j# E7 k1 {- K
  25. #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */ % I1 w8 k3 f' y6 ]! B, B( z& y/ h6 `4 C
  26. __IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    - |' |( k* H0 A1 O, B* l4 |. f
  27. static uint8_t SetSysClock_PLL_HSE_200MHz();
    3 {" X7 F3 k6 J
  28. int main()
    $ C1 _7 T+ r) m8 X  }2 r1 y
  29. { # a$ i/ y: H: o% E
  30.     SetSysClock_PLL_HSE_200MHz();
    ! a0 \- r- ?; z. u# h% o
  31.     pc.baud(9600);
    2 w6 s2 P& Y# a' i6 L

  32. / P4 H. D1 K/ `) Z/ N, G/ q1 \" W  \
  33.     pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n"); 7 C0 G$ X! Z5 I
  34.     led_red = 0; 5 ~+ a: g! `' E. k9 `
  35.    - _8 ]- Y! l) D% Q
  36.     pc.printf("\nAUDIO RECORD INIT OK\n");
    : v$ A; p1 Z0 c' {
  37.     pc.printf("Microphones sound streamed to headphones\n"); " e+ P* z7 m' F1 U, s6 L- L
  38.      
    % n9 p0 t- d, q5 D* o
  39.     /* Initialize SDRAM buffers */
    9 C5 l# ~5 h1 P& C- N3 V& ^4 a
  40.     memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
    " G; ~  o1 ~3 }# p' y% W, h
  41.     memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    & _. T0 b3 e' ?" V2 F
  42.     audio_rec_buffer_state = BUFFER_OFFSET_NONE; 0 @1 T+ I7 k5 M8 X( a$ W

  43. , g/ l. `- I' q+ G6 U
  44.     /* Start Recording */ ; V0 t7 A2 I8 U' _7 B
  45.     audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    ! M8 N* Z9 a# j( f1 ~* m% ?# _' ]- z

  46. ( y; J0 k. m$ M7 A# ^: R
  47.     /* Start Playback */
    4 n& V1 S1 p$ |7 @  I& g7 n. F
  48.     audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02); 0 L# O8 v1 r% J+ l! g& O
  49.     audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2); 8 c; V2 C+ p: I. b2 [( d7 `* x( A

  50. / b0 ^1 k% D7 k/ l+ F9 ?  G# H
  51.     while (1) { 3 _% N4 B8 _$ `9 f4 @" H
  52.         /* Wait end of half block recording */
    # z' Q/ ~4 @  l# O) O
  53.         while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) { ' E# {3 C: _, D+ C; z
  54.         } 6 u  H. t/ \  P; n4 y3 f  R! @
  55.         audio_rec_buffer_state = BUFFER_OFFSET_NONE; + X3 {1 k* v3 `* F% I+ S: K
  56.         /* Copy recorded 1st half block */ - A7 K% i/ n2 ~/ W+ A8 P- J( a
  57.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
    ! J$ ^" l( r2 r0 M1 t0 p" H
  58.         /* Wait end of one block recording */ / W/ W8 ~2 u2 k+ W2 F  [9 m
  59.         while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) { ! e  h) [# l) r9 Q0 @
  60.         }
    ' ^& H: K4 T+ \" m
  61.         audio_rec_buffer_state = BUFFER_OFFSET_NONE;
    ! G4 N7 W: h9 l+ Z. }
  62.         /* Copy recorded 2nd half block */
    ; q' h; A  s% R- l" Z& |
  63.         memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  ; P0 G( C! M7 x# G1 J" G
  64. + (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    6 i9 F* p, L  ?% x3 v
  65.     }
    ' E1 p, `( T# `9 {; P4 K
  66. }
      D2 [$ w. O- H, z% \2 H  p
  67. /*-------------------------------------------------------------------------------------
    % J$ {6 n1 m" f6 y' e3 U, q' p
  68.        Callbacks implementation: , G$ v7 S  A6 k/ D! k3 \
  69.            the callbacks API are defined __weak in the stm32746g_discovery_audio.c file 0 M! \; ?: p" {5 Y  Z' \
  70.            and their implementation should be done in the user code if they are needed.
    . K! n  p( w3 X! R
  71.            Below some examples of callback implementations. % d. l8 ^- n" c' e. w# N% T
  72.   -------------------------------------------------------------------------------------*/ 0 k: j  i& A3 l: v
  73. /**
    " C4 V1 U  H; J: n
  74.   * @brief Manages the DMA Transfer complete interrupt.
    / H4 H! ~; f, d
  75.   * @param None
    * W0 p: ^9 J5 [0 l
  76.   * @retval None 2 H1 Z- E; Z$ h$ x; B, n' e
  77.   */ ) X9 ^- G1 j/ s# f4 Z
  78. void BSP_AUDIO_IN_TransferComplete_CallBack(void)
    6 B. {1 |: M. h3 G
  79. {
    $ d2 }; A2 m: y) A. t/ [
  80.   audio_rec_buffer_state = BUFFER_OFFSET_FULL;
    ; e1 _4 v9 p, P" n9 }( `! E
  81.   return;
    3 ^( F; M! r8 j& E" K# ]' f( Y' M
  82. }
    , C4 c% N3 Z) t- l$ ~

  83. 4 N' ?4 t, j2 E6 f( q$ E
  84. /** 2 P; L: ]& r, V8 h( |/ p, R% P
  85.   * @brief  Manages the DMA Half Transfer complete interrupt. ) _+ X3 q/ l1 v
  86.   * @param  None
    2 w/ z6 E$ `& i7 j3 _" w7 p6 T% @$ A8 Z
  87.   * @retval None 3 T7 E- L! Y; c! J# U* r& A. J
  88.   */ ; r9 X% f9 `% \. T, n* d
  89. void BSP_AUDIO_IN_HalfTransfer_CallBack(void) ) y! g/ u8 q# i! h% ?2 q& c- S
  90. { 1 W8 r' _' O1 _( y  E- z
  91.   audio_rec_buffer_state = BUFFER_OFFSET_HALF; 2 O# d7 e& a% u2 f8 `; p# _3 L1 b4 Y
  92.   return; . w% l) G. P/ M$ E
  93. }( A) ^4 a4 P* k$ x1 n
复制代码

7 N: f, @/ k) B9 ^! @' u程序分析:
    % I, K* o% ], B0 E" H% b: \
  • 首先定义缓冲区大小和音频输入输出缓冲区( J2 o4 Z) D0 a# f' |
    : P$ g: j2 c; i. M
    #define AUDIO_BLOCK_SIZE   ((uint32_t)512)( L* B( g) Z, ?3 `
    #define AUDIO_BUFFER_IN     SDRAM_DEVICE_ADDR     /* In SDRAM */1 a4 `! ~/ Y  m0 ?3 N
    #define AUDIO_BUFFER_OUT   (SDRAM_DEVICE_ADDR + (AUDIO_BLOCK_SIZE * 2)) /* In SDRAM */
  • 然后进行初始化,初始化部分完成下面几个功能:4 G0 w  P; T( q; u! l8 I
    • 分配缓冲区! P! B. P' Y6 S7 O6 n: E$ V
          /* Initialize SDRAM buffers */* N+ _/ F, h+ G3 N1 h( N
          memset((uint16_t*)AUDIO_BUFFER_IN, 0, AUDIO_BLOCK_SIZE*2);
      : h8 s9 I3 D" I0 W& w- G3 Y3 E    memset((uint16_t*)AUDIO_BUFFER_OUT, 0, AUDIO_BLOCK_SIZE*2);
    • 启用录音功能,将音频输入保存到输入缓冲区
      2 Q+ R+ A2 E! w3 |- r5 p+ |3 ], h    /* Start Recording */1 B. C: T7 d9 x: Z; ?- N- K- e" X
          audio.IN_Record((uint16_t*)AUDIO_BUFFER_IN, AUDIO_BLOCK_SIZE);
    • 设置音频回放, p. a5 U1 e! |
          audio.OUT_SetAudioFrameSlot(CODEC_AUDIOFRAME_SLOT_02);) M, j. B- ?3 e1 g2 U
          audio.OUT_Play((uint16_t*)AUDIO_BUFFER_OUT, AUDIO_BLOCK_SIZE * 2);5 P  r& {2 \6 y: o
  • 在主循环中,等待音频输入完成,然后将输入缓冲区(AUDIO_BUFFER_IN)的数据复制到输出(AUDIO_BUFFER_OUT)缓冲区。音频输入的录音和回放,都是使用DMA方式自动完成的,所以无需CPU处理。* M8 O- d1 V8 L" W, z
2 B! I/ m0 F$ t  t
完整参考程序:! N6 T$ d8 f0 }: Q
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# F+ [' |6 q0 _& M" A8 V8 F0 ^9 ~' E
谢谢楼主,有实物图或者视频演示就更好啦
' \9 S) F, k/ X: W- r
这个例子主要是通过音频进行测试,不方便视频。有板子的网友试试就知道了,效果很棒。
liangwei 回答时间:2016-6-30 09:06:23
shaoziyang 发表于 2016-6-23 09:44
) h$ a2 f7 F* E, c4 q需要有源音箱吧,不然带不动
& H  c  \4 x1 b/ n7 E2 M. L- r
不是的,那个芯片支持2w的喇叭,是软件里面设置了静音
shaoziyang 回答时间:2016-6-23 09:44:08
weiyuliang 发表于 2016-6-22 16:54
- \2 P* k  R0 h) r) [5 n牛,我外接喇叭为啥木声音那
+ J. P. r- e( W. q+ E1 A% b! ]/ ~7 I
需要有源音箱吧,不然带不动
沐紫 回答时间: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 手机版