打印
[STM32F7]

将STM32F746G-Disco开发板做助听器

[复制链接]
1736|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Messi1999|  楼主 | 2016-7-11 12:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
STM32F746G-Disco开发板上带有数字麦克风和音频输出,它们组合起来就可以实现助听器的功能。只要把麦克风的输入信号进行放大,然后在通过音频接口输出。

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


#include "mbed.h"
#include "AUDIO_DISCO_F746NG.h"
#include "SDRAM_DISCO_F746NG.h"

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

DigitalOut led_green(LED1);
DigitalOut led_red(LED2);
Serial pc(USBTX, USBRX);

typedef enum
{
    BUFFER_OFFSET_NONE = 0,
    BUFFER_OFFSET_HALF = 1,
    BUFFER_OFFSET_FULL = 2,
}BUFFER_StateTypeDef;

#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 */
__IO uint32_t  audio_rec_buffer_state = BUFFER_OFFSET_NONE;
static uint8_t SetSysClock_PLL_HSE_200MHz();
int main()
{
    SetSysClock_PLL_HSE_200MHz();
    pc.baud(9600);

    pc.printf("\n\nAUDIO LOOPBACK EXAMPLE START:\n");
    led_red = 0;
   
    pc.printf("\nAUDIO RECORD INIT OK\n");
    pc.printf("Microphones sound streamed to headphones\n");
     
    /* 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);
    audio_rec_buffer_state = BUFFER_OFFSET_NONE;

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

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

    while (1) {
        /* Wait end of half block recording */
        while(audio_rec_buffer_state == BUFFER_OFFSET_HALF) {
        }
        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        /* Copy recorded 1st half block */
        memcpy((uint16_t *)(AUDIO_BUFFER_OUT), (uint16_t *)(AUDIO_BUFFER_IN), AUDIO_BLOCK_SIZE);
        /* Wait end of one block recording */
        while(audio_rec_buffer_state == BUFFER_OFFSET_FULL) {
        }
        audio_rec_buffer_state = BUFFER_OFFSET_NONE;
        /* Copy recorded 2nd half block */
        memcpy((uint16_t *)(AUDIO_BUFFER_OUT + (AUDIO_BLOCK_SIZE)), (uint16_t *)(AUDIO_BUFFER_IN  
+ (AUDIO_BLOCK_SIZE)), AUDIO_BLOCK_SIZE);
    }
}
/*-------------------------------------------------------------------------------------
       Callbacks implementation:
           the callbacks API are defined __weak in the stm32746g_discovery_audio.c file
           and their implementation should be done in the user code if they are needed.
           Below some examples of callback implementations.
  -------------------------------------------------------------------------------------*/
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url] Manages the DMA Transfer complete interrupt.
  * @param None
  * @retval None
  */
void BSP_AUDIO_IN_TransferComplete_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_FULL;
  return;
}

/**
  * @brief  Manages the DMA Half Transfer complete interrupt.
  * @param  None
  * @retval None
  */
void BSP_AUDIO_IN_HalfTransfer_CallBack(void)
{
  audio_rec_buffer_state = BUFFER_OFFSET_HALF;
  return;
}
程序分析:

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

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



沙发
mmuuss586| | 2016-7-11 19:45 | 只看该作者
谢谢分享

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

363

帖子

1

粉丝