1nnocent 发表于 2021-4-16 14:18

【HC32F460开发板测评】05 wm8731通过耳机播放音乐

本帖最后由 1nnocent 于 2021-4-21 14:55 编辑

<p>HC32F460开发板的AUDIO是比较感兴趣的一个功能,这次来大概看一看。</p>

<p>AUDIO<br />
EVB 配置 1 个 Audio Codec 芯片 WM8731SEDS 和 Audio PA 芯片 BL6281,并提供一个板载<br />
MIC、 3.5mm 耳机接口和 Line in 接口以及一个喇叭接口,以实现录音以及音频输入和输出功<br />
能。<br />
MCU I2S 接口时钟可以通过更改电阻来切换,如下所示:</p>

<table>
        <tbody>
                <tr>
                        <td width="200">I2S_CLK</td>
                        <td width="200">R141</td>
                        <td width="200">R54</td>
                        <td width="200">R143</td>
                        <td width="200">R55</td>
                        <td width="200">R30</td>
                </tr>
                <tr>
                        <td width="200">I2S_EXCK(default)</td>
                        <td width="200">33</td>
                        <td width="200">100</td>
                        <td width="200">DNP</td>
                        <td width="200">DNP</td>
                        <td width="200">0</td>
                </tr>
                <tr>
                        <td width="200">I2S_MCK</td>
                        <td width="200">DNP</td>
                        <td width="200">DNP</td>
                        <td width="200">33</td>
                        <td width="200">100</td>
                        <td width="200">DNP</td>
                </tr>
        </tbody>
</table>

<p>&nbsp;</p>

<p>WM8731是一款Codec芯片,&nbsp;WM 8731带有集成耳机驱动器的低功率立体声编解码器,提供了立体声线和单麦克风电平音频输入,以及静音功能、可编程线型音量控制和适合驻极体型麦克风的偏压输出。</p>

<p>BL6281是一款&nbsp;AB类<a href="https://datasheet.eeworld.com.cn/cat/Audio_power_amplifier.html">音频功率放大器</a>用于驱动1.1W8&Omega;喇叭。</p>

<p>一开始看的是配套的历程,在I2C的例程里面可以找到,例程i2s_record_wm8731_exck_dma的功能是,录取音乐或麦克风的音频信号,将其存储,再通过DMA和I2S使用耳机或者喇叭播放出来,比较麻烦,所以先只单独试一下wm8731这个芯片,单独使用wm8731的话程序就比较简单,配置一下相关寄存器就好了。</p>

<p>一下是使用i2s_record_wm8731_exck_dma历程改的程序(程序就只剩下wm8731的配置,配置完就可以播放音频信号(J12输入音频信号),通过耳机J11可以听到音乐):</p>

<p>audio.c</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">/******************************************************************************/
/** \file audio.c
**
** \brief Audio functions
**
**   - 2021-04-151.0First version for Audio
**
******************************************************************************/

/*******************************************************************************
* Include files
******************************************************************************/
#include &quot;hc32_ddl.h&quot;
#include &quot;wm8731.h&quot;
#include &quot;audio.h&quot;
#include &quot;i2c.h&quot;

/*******************************************************************************
* Local type definitions (&#39;typedef&#39;)
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros (&#39;#define&#39;)
******************************************************************************/
#define RECORDER_WAVFILELEN         (15u*1024u)

/*******************************************************************************
* Global variable definitions (declared in header file with &#39;extern&#39;)
******************************************************************************/
extern uint16_t *pu16SoundData;
extern uint16_t au16RecorderSoundI2s;

/*******************************************************************************
* Local function prototypes (&#39;static&#39;)
******************************************************************************/

/**
*******************************************************************************
** \briefConfiguration Codec to record wav file
**
** \paramNone
**
** \retval None
**
******************************************************************************/
void WM8731_CodecConfigRecord(void)
{
    stc_wm8731_reg_t stcWm8731Reg;
    MEM_ZERO_STRUCT(stcWm8731Reg);
    /* Config codec */
    /* Reset register */
    stcWm8731Reg.RESET            = 0x00u;    // Reset WM8731
    /* Left &amp; right line input */
    stcWm8731Reg.LLIN_f.LINVOL      = 0x17;    // Left channel line input volume: 0dB--0x17u
    stcWm8731Reg.LLIN_f.LINMUTE   = 0u;       // Enable left channel line input mute
    stcWm8731Reg.LLIN_f.LRINBOTH    = 0u;       // Disable simultaneous input volume and mute load from left to right
    stcWm8731Reg.RLIN_f.RINVOL      = 0x17;    // Right channel line input volume 0dB
    stcWm8731Reg.RLIN_f.RINMUTE   = 0u;       // Enable right channel line input mute
    stcWm8731Reg.RLIN_f.RINBOTH   = 0u;       // Disable simultaneous input volume and mute load from right to left
    /* Left &amp; right headphone output */
    stcWm8731Reg.LHOUT_f.LHPVOL   = 0x5Fu;    // Set volume of left headphone to 0dB. 0x30(-73dB) ~ 0x7F(+6dB), 0 ~ 0x2F: mute
    stcWm8731Reg.LHOUT_f.LZCEN      = 0u;       // Disable left channel zero cross detect
    stcWm8731Reg.LHOUT_f.LRHPBOTH   = 0u;       // Disable simultaneous output volume and mute load from left to right
    stcWm8731Reg.RHOUT_f.RHPVOL   = 0x5Fu;    // Set volume of right headphone to 0dB. 0x30(-73dB) ~ 0x7F(+6dB), 0 ~ 0x2F: mute
    stcWm8731Reg.RHOUT_f.RZCEN      = 0u;       // Enable right channel zero cross detect
    stcWm8731Reg.RHOUT_f.RLHPBOTH   = 0u;       // Disable simultaneous output volume and mute load from right to left
    /* Analog audio path control */
#if(RECORD_MIC)
    stcWm8731Reg.AAPC_f.MICBOOST    = 1u;       // Disable boost, 0: disable 1: enable
    stcWm8731Reg.AAPC_f.MUTEMIC   = 0u;       // Enable mute to ADC
    stcWm8731Reg.AAPC_f.INSEL       = 1u;       // Line input select to ADC, 0: linein1: mic
    stcWm8731Reg.AAPC_f.BYPASS      = 1u;       // Enbale bypass 0: disable 1:enable
    stcWm8731Reg.AAPC_f.DACSEL      = 0u;       // Select DAC
    stcWm8731Reg.AAPC_f.SIDETONE    = 0u;       // Disable side tone 0: disable 1:enable
    stcWm8731Reg.AAPC_f.SIDEATT   = 0u;       // 0: -6dB, 1: -12dB, 2: -9dB, 3: -15dB.
#else
    stcWm8731Reg.AAPC_f.MICBOOST    = 0u;       // Disable boost, 0: disable 1: enable
    stcWm8731Reg.AAPC_f.MUTEMIC   = 1u;       // Enable mute to ADC
    stcWm8731Reg.AAPC_f.INSEL       = 0u;       // Line input select to ADC, 0: linein1: mic
    stcWm8731Reg.AAPC_f.BYPASS      = 1u;       // Enbale bypass 0: disable 1:enable
    stcWm8731Reg.AAPC_f.DACSEL      = 0u;       // Select DAC
    stcWm8731Reg.AAPC_f.SIDETONE    = 0u;       // Disable side tone 0: disable 1:enable
    stcWm8731Reg.AAPC_f.SIDEATT   = 0u;       // 0: -6dB, 1: -12dB, 2: -9dB, 3: -15dB.
#endif
    /* Digital audio path control */
    stcWm8731Reg.DAPC_f.ADCHPD      = 0u;       // Enable high pass filter
    stcWm8731Reg.DAPC_f.DEEMP       = 0u;       // De-emphasis contrl. 0: disable, 1: 32kHz, 2: 44.1kHz, 3: 48kHz
    stcWm8731Reg.DAPC_f.DACMU       = 0u;       // 0:Disable soft mute   1: Enable soft mute
    stcWm8731Reg.DAPC_f.HPOR      = 0u;       // Clear offset when high pass
    /* Power down control */
    stcWm8731Reg.PDC_f.LINEINPD   = 0u;       // Disable line input power down
    stcWm8731Reg.PDC_f.MICPD      = 0u;       // Disable microphone input power down
    stcWm8731Reg.PDC_f.ADCPD      = 0u;       // Disable ADC power down
    stcWm8731Reg.PDC_f.DACPD      = 0u;       // Disable DAC power down
    stcWm8731Reg.PDC_f.OUTPD      = 0u;       // Disable output power down
    stcWm8731Reg.PDC_f.OSCPD      = 0u;       // Disable oscillator power down
    stcWm8731Reg.PDC_f.CLKOUTPD   = 0u;       // Disable CLKOUT power down
    stcWm8731Reg.PDC_f.POWEROFF   = 0u;       // Disable power off mode
    /* Digital audio interface format */
    stcWm8731Reg.DAIF_f.FORMAT      = 2u;       // 0: MSB-First, right justified, 1: MSB-first, left justified, 2: I2S-format, 3: DSP mode
    stcWm8731Reg.DAIF_f.IWL         = 0u;       // 0: 16 bits, 1: 20 bits, 2: 24 bits, 3: 32 bits
    stcWm8731Reg.DAIF_f.LRP         = 0u;       // 1: right channel DAC data when DACLRC (WS) is high,0: right channel DAC data when DACLRC (WS) is low
    stcWm8731Reg.DAIF_f.LRSWAP      = 0u;       // 1: swap left channel and right channel, 0: don&#39;t swap
    stcWm8731Reg.DAIF_f.MS          = 0u;       // 1: Enable master mode, 0: Enable slave mode
    stcWm8731Reg.DAIF_f.BCLKINV   = 0u;       // Don&#39;t invert BCLK
    /* Sampling control */
    stcWm8731Reg.SC_f.NORMAL_USB    = 0u;       // 0: normal mode, 1: USB mode
    stcWm8731Reg.SC_f.BOSR          = 0u;       // Nomrmal mode: 0: 256fs, 1: 384fs
                                                // USB mode: 0: 250fs, 1:272fs
    stcWm8731Reg.SC_f.SR            = 2u;       // Sample rate setting
    stcWm8731Reg.SC_f.CLKDIV2       = 0u;       // 0: core clock is MCLK, 1: core clock is MCLK divided by 2
    stcWm8731Reg.SC_f.CLKODIV2      = 0u;       // 0: output clock is core clock, 1: core clock is core clock/2
    // Active control
    stcWm8731Reg.AC_f.ACTIVE      = 1u;       // 0: inactive, 1: active

    WM8731_Init(I2C_CH, &amp;stcWm8731Reg);

    WM8731_SetHpVolume(I2C_CH, 0x7Fu,0x7Fu);    //0x2F-MUTE ~ 0x7F Maximum
}

/**
*******************************************************************************
** \briefConfiguration Codec to play wav file
**
** \paramNone
**
** \retval None
**
******************************************************************************/
void WM8731_CodecConfigPlay(void)
{
    stc_wm8731_reg_t stcWm8731Reg;
    MEM_ZERO_STRUCT(stcWm8731Reg);
    /* Config codec */
    /* Reset register */
    stcWm8731Reg.RESET            = 0x00u;    // Reset WM8731
    /* Left &amp; right line input */
    stcWm8731Reg.LLIN_f.LINVOL      = 0x00u;    // Left channel line input volume: 0dB--0x17u
    stcWm8731Reg.LLIN_f.LINMUTE   = 1u;       // Enable left channel line input mute
    stcWm8731Reg.LLIN_f.LRINBOTH    = 0u;       // Disable simultaneous input volume and mute load from left to right
    stcWm8731Reg.RLIN_f.RINVOL      = 0x00u;    // Right channel line input volume 0dB
    stcWm8731Reg.RLIN_f.RINMUTE   = 1u;       // Enable right channel line input mute
    stcWm8731Reg.RLIN_f.RINBOTH   = 0u;       // Disable simultaneous input volume and mute load from right to left
    /* Left &amp; right headphone output */
    stcWm8731Reg.LHOUT_f.LHPVOL   = 0x5Fu;    // Set volume of left headphone to 0dB. 0x30(-73dB) ~ 0x7F(+6dB), 0 ~ 0x2F: mute
    stcWm8731Reg.LHOUT_f.LZCEN      = 0u;       // Disable left channel zero cross detect
    stcWm8731Reg.LHOUT_f.LRHPBOTH   = 0u;       // Disable simultaneous output volume and mute load from left to right
    stcWm8731Reg.RHOUT_f.RHPVOL   = 0x5Fu;    // Set volume of right headphone to 0dB. 0x30(-73dB) ~ 0x7F(+6dB), 0 ~ 0x2F: mute
    stcWm8731Reg.RHOUT_f.RZCEN      = 0u;       // Enable right channel zero cross detect
    stcWm8731Reg.RHOUT_f.RLHPBOTH   = 0u;       // Disable simultaneous output volume and mute load from right to left
    /* Analog audio path control */
    stcWm8731Reg.AAPC_f.MICBOOST    = 0u;       // Disable boost
    stcWm8731Reg.AAPC_f.MUTEMIC   = 1u;       // Enable mute to ADC
    stcWm8731Reg.AAPC_f.INSEL       = 0u;       // Line input select to ADC
    stcWm8731Reg.AAPC_f.BYPASS      = 0u;       // Enbale bypass
    stcWm8731Reg.AAPC_f.DACSEL      = 1u;       // Select DAC
    stcWm8731Reg.AAPC_f.SIDETONE    = 0u;       // Disable side tone
    stcWm8731Reg.AAPC_f.SIDEATT   = 0u;       // 0: -6dB, 1: -12dB, 2: -9dB, 3: -15dB.
    /* Digital audio path control */
    stcWm8731Reg.DAPC_f.ADCHPD      = 0u;       // Enable high pass filter
    stcWm8731Reg.DAPC_f.DEEMP       = 3u;       // De-emphasis contrl. 0: disable, 1: 32kHz, 2: 44.1kHz, 3: 48kHz
    stcWm8731Reg.DAPC_f.DACMU       = 0u;       // 0:Disable soft mute   1: Enable soft mute
    stcWm8731Reg.DAPC_f.HPOR      = 0u;       // Clear offset when high pass
    /* Power down control */
    stcWm8731Reg.PDC_f.LINEINPD   = 0u;       // Disable line input power down
    stcWm8731Reg.PDC_f.MICPD      = 0u;       // Disable microphone input power down
    stcWm8731Reg.PDC_f.ADCPD      = 0u;       // Disable ADC power down
    stcWm8731Reg.PDC_f.DACPD      = 0u;       // Disable DAC power down
    stcWm8731Reg.PDC_f.OUTPD      = 0u;       // Disable output power down
    stcWm8731Reg.PDC_f.OSCPD      = 0u;       // Disable oscillator power down
    stcWm8731Reg.PDC_f.CLKOUTPD   = 0u;       // Disable CLKOUT power down
    stcWm8731Reg.PDC_f.POWEROFF   = 0u;       // Disable power off mode
    /* Digital audio interface format */
    stcWm8731Reg.DAIF_f.FORMAT      = 2u;       // 0: MSB-First, right justified, 1: MSB-first, left justified, 2: I2S-format, 3: DSP mode
    stcWm8731Reg.DAIF_f.IWL         = 0u;       // 0: 16 bits, 1: 20 bits, 2: 24 bits, 3: 32 bits
    stcWm8731Reg.DAIF_f.LRP         = 0u;       // 1: right channel DAC data when DACLRC (WS) is high,0: right channel DAC data when DACLRC (WS) is low
    stcWm8731Reg.DAIF_f.LRSWAP      = 0u;       // 1: swap left channel and right channel, 0: don&#39;t swap
    stcWm8731Reg.DAIF_f.MS          = 0u;       // 1: Enable master mode, 0: Enable slave mode
    stcWm8731Reg.DAIF_f.BCLKINV   = 0u;       // Don&#39;t invert BCLK
    /* Sampling control */
    stcWm8731Reg.SC_f.NORMAL_USB    = 0u;       // 0: normal mode, 1: USB mode
    stcWm8731Reg.SC_f.BOSR          = 0u;       // Nomrmal mode: 0: 256fs, 1: 384fs
                                                // USB mode: 0: 250fs, 1:272fs
    stcWm8731Reg.SC_f.SR            = 1u;       // Sample rate setting
    stcWm8731Reg.SC_f.CLKDIV2       = 0u;       // 0: core clock is MCLK, 1: core clock is MCLK divided by 2
    stcWm8731Reg.SC_f.CLKODIV2      = 0u;       // 0: output clock is core clock, 1: core clock is core clock/2
    // Active control
    stcWm8731Reg.AC_f.ACTIVE      = 1u;       // 0: inactive, 1: active

    WM8731_Init(I2C_CH, &amp;stcWm8731Reg);

    WM8731_SetHpVolume(I2C_CH, 0x7Fu,0x7Fu);    //0x2F-MUTE ~ 0x7F Maximum
}

/**
*******************************************************************************
** \briefConfiguration Codec to play wav file
**
** \paramNone
**
** \retval None
**
******************************************************************************/
void SpeakerInit(void)
{
        stc_port_init_t stcPortIni;
#if(SPEAKER_ON)
        /* Initialize SPK_EN port for speaker */
        MEM_ZERO_STRUCT(stcPortIni);
        stcPortIni.enPinMode = Pin_Mode_Out;
        PORT_Init(SPK_EN_PORT, SPK_EN_PIN, &amp;stcPortIni);
        SPEAKER_EN();
#endif
//        /* Prepare buffer for store recoder data */
//        pu16SoundData = &amp;au16RecorderSoundI2s;
}

/*******************************************************************************
* Local variable definitions (&#39;static&#39;)
******************************************************************************/

/*******************************************************************************
* Function implementation - global (&#39;extern&#39;) and local (&#39;static&#39;)
******************************************************************************/

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/
</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>audio.h</p>

<div aria-label="代码段 小部件" contenteditable="false" role="region" tabindex="-1">
<pre data-widget="codesnippet">
<code class="hljs">/******************************************************************************/
/** \file audio.h
**
** A detailed description is available at
** @link audio Series description @endlink
**
**   - 2021-4-151.0First version for Audio Series Functions description
**   Library.
**
******************************************************************************/
#ifndef __AUDIO_H__
#define __AUDIO_H__

/*******************************************************************************
* Include files
******************************************************************************/
#include &quot;hc32_common.h&quot;

/*******************************************************************************
* Local pre-processor symbols/macros (&#39;#define&#39;)
******************************************************************************/
/* Define if need play by speaker*/
#define SPEAKER_ON                  (true)
       
/* Select Record source */
//#define RECORD_MIC                  (true)

#define SPK_EN_PORT               (PortB)
#define SPK_EN_PIN                  (Pin00)

#define SPEAKER_EN()                (PORT_SetBits(SPK_EN_PORT, SPK_EN_PIN))
#define SPEAKER_DISEN()             (PORT_ResetBits(SPK_EN_PORT, SPK_EN_PIN))
       
//#define RECORDER_WAVFILELEN         (15u*1024u)

///*******************************************************************************
// * Local variable definitions (&#39;static&#39;)
// ******************************************************************************/
//uint16_t *pu16SoundData=NULL;
//uint16_t au16RecorderSoundI2s;
//uint8_t u8RecordEndFlag = 0u;
//uint32_t u32Count = 0ul;


void WM8731_CodecConfigRecord(void);
void WM8731_CodecConfigPlay(void);
void SpeakerInit(void);

#endif /* __AUDIO_H__ */

/*******************************************************************************
* End of file
******************************************************************************/

</code></pre>
<img src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" /><span style="background: url(&quot;https://bbs.eeworld.com.cn/static/editor/plugins/widget/images/handle.png&quot;) rgba(220, 220, 220, 0.5); top: -15px; left: 0px; display: block;"><img height="15" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" /></span></div>

<p>i2c.c</p>

<pre>
<code>/******************************************************************************/
/** \file I2C.c
**
** \brief I2C functions
**
**   - 2021-04-151.0First version for I2C
**
******************************************************************************/

/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
#include "i2c.h"

/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/

/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/

/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
void i2cInit()
{
        /* Initialize i2c port for codec wm8731 */
        PORT_SetFunc(I2C2_SCL_PORT, I2C2_SCL_PIN, Func_I2c2_Scl, Disable);
        PORT_SetFunc(I2C2_SDA_PORT, I2C2_SDA_PIN, Func_I2c2_Sda, Disable);
        /* Enable I2C Peripheral*/
        PWC_Fcg1PeriphClockCmd(PWC_FCG1_PERIPH_I2C2, Enable);
}

/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/

/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/

/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

</code></pre>

<p>i2c.h</p>

<pre>
<code>/******************************************************************************/
/** \file i2c.h
**
** A detailed description is available at
** @link i2c Series description @endlink
**
**   - 2021-4-151.0First version for i2c Series Functions description
**   Library.
**
******************************************************************************/
#ifndef __I2C_H__
#define __I2C_H__

/*******************************************************************************
* Include files
******************************************************************************/

/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* Define I2C unit used for the example */
#define I2C_CH                      (M4_I2C2)
/* Define port and pin for SDA and SCL */
#define I2C2_SCL_PORT               (PortD)
#define I2C2_SCL_PIN                (Pin00)
#define I2C2_SDA_PORT               (PortD)
#define I2C2_SDA_PIN                (Pin01)

void i2cInit(void);


#endif /* __I2C_H__ */

/*******************************************************************************
* End of file
******************************************************************************/

</code></pre>

<p>wm8731.c以及相应的头文件这里不再给出,这两个文件和例程里的是一样的。</p>

<p>单独wm8731代码:</p>

<p></p>

<p>下面这个代码和例程i2s_record_wm8731_exck_dma功能一样,但是使用空历程文件改的,看起来会比历程的简洁一些:</p>

<p></p>
页: [1]
查看完整版本: 【HC32F460开发板测评】05 wm8731通过耳机播放音乐