PlayBack
该示例实现将频率为 1KHz 的正弦波信号经 CODEC 编码,输出音频的功能。
利用 GDMA 将 I2S 数据从内存搬运到 I2S 的发送 FIFO ,再通过 CODEC 编码为 PDM 信号。
外接 PDM 播放器,可以实现播放固定频率的正弦波语音。
环境需求
该示例的环境需求,可参考 环境需求。
硬件连线
EVB 外接 PDM 播放器,连接 P4_3 和 CLK,P4_2 和 DATA。
编译和下载
该示例的编译和下载流程,可参考 编译和下载。
测试验证
在 PDM 播放器中听到 1KHz 的正弦波声音。
代码介绍
该章节主要介绍示例中的初始化和相应功能实现的代码和流程说明。
源码路径
工程文件和源码路径如下:
工程路径:
sdk\samples\peripheral\codec\playback\proj
源码路径:
sdk\samples\peripheral\codec\playback\src
初始化
外设的初始化流程可参考 General Introduction 中的 初始化流程 部分。
初始化流程包括了 CODEC、UART、I2S、GDMA 模块的初始化,具体流程如下。
调用
Pad_Config()
与Pinmux_Config()
, 配置 PDM 相关引脚对应引脚的 PAD 和 PINMUX。void board_codec_init(void) { Pad_Config(PDM_CLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pad_Config(PDM_DAT_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pinmux_Config(PDM_CLK_PIN, PDM_CLK); Pinmux_Config(PDM_DAT_PIN, PDM_DATA); }
调用
Pad_Config()
与Pinmux_Config()
,配置 I2S 相关引脚对应引脚的 PAD 和 PINMUX。void board_i2s_init(void) { Pad_Config(CODEC_BCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pad_Config(CODEC_LRCLK_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE,PAD_OUT_LOW); Pad_Config(CODEC_TX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pad_Config(CODEC_RX_PIN, PAD_PINMUX_MODE, PAD_IS_PWRON, PAD_PULL_NONE, PAD_OUT_ENABLE, PAD_OUT_LOW); Pinmux_Config(CODEC_BCLK_PIN, BCLK_SPORT0); Pinmux_Config(CODEC_LRCLK_PIN, LRC_SPORT0); Pinmux_Config(CODEC_TX_PIN, DACDAT_SPORT0); }
执行
I2S_StructInit()
和I2S_Init()
, 初始化 I2S 外设。I2S0 的初始化参数配置如下:
I2S Hardware Parameters |
Setting in the |
I2S master RX |
---|---|---|
Sample Rate (Mi) |
0x271 |
|
Sample Rate (Ni) |
0x10 |
|
Device Mode |
||
Channel Type |
||
Data Format |
||
Data Width |
执行
GDMA_StructInit()
和GDMA_Init()
, 初始化 GDMA 外设。GDMA 的初始化参数配置如下:
GDMA Hardware Parameters |
Setting in the |
GDMA Channel |
---|---|---|
Channel Num |
0 |
|
Transfer Direction |
||
Source Address Increment or Decrement |
||
Destination Address Increment or Decrement |
||
Source Data Size |
||
Destination Data Size |
||
Source Burst Transaction Length |
||
Destination Burst Transaction Length |
||
Source Address |
|
|
Destination Address |
|
|
Destination Handshake |
配置 GDMA 总传输完成中断
GDMA_INT_Transfer
和 NVIC, NVIC 相关配置可参考 中断配置。对 CODEC 外设的初始化。
调用
CODEC_AnalogCircuitInit()
初始化模拟电路。调用
RCC_PeriphClockCmd()
,开启 CODEC 时钟。执行
CODEC_StructInit()
和CODEC_Init()
, 初始化 CODEC 外设。CODEC 的初始化参数配置如下:
CODEC Hardware Parameters |
Setting in the |
CODEC |
---|---|---|
Da Mute |
||
Da Gain Mode |
0xAF |
|
DaC Dither |
||
I2S Data Format |
||
I2S Channel Len |
||
I2S Data Width |
||
I2S Channel Sequence |
执行
preload_cos_table
,准备需要发送的正弦波数据。调用
I2S_Cmd()
,使能 I2S 发送模式。调用GDMA_Cmd()
,使能 GDMA 传输。
功能实现
正弦波数据由 GDMA 从内存搬运到 I2S TX FIFO 中,经过 CODEC 的 DA 模块转换,外接 PDM 放大器后可听到音频。 数据在各个模块的传输顺序如下图所示。

音频数据传输模块
当 GDMA 传输数据量达到设定的 BlockSize 时,会触发
GDMA_INT_Transfer
中断。在中断处理函数内重新设置源端地址,目的端地址和 BlockSize,并重新使能 GDMA 传输,以确保能够连续传输数据。GDMA_SetSourceAddress(CODEC_GDMA_Channel, (uint32_t)codec_drv_cos_table); GDMA_SetDestinationAddress(CODEC_GDMA_Channel, (uint32_t)(&(I2S0->I2S_TX_FIFO_WR_ADDR))); GDMA_SetBufferSize(CODEC_GDMA_Channel, CODEC_DRV_COS_TABLE_SAMPLE); GDMA_ClearINTPendingBit(CODEC_GDMA_Channel_NUM, GDMA_INT_Transfer); GDMA_Cmd(CODEC_GDMA_Channel_NUM, ENABLE);