开发板
亚博K210开发板
实验目的
本次测试主要学习 K210 通过 I2S 播放 PCM 音频数据的功能。
实验准备
实验元件
扬声器
元件特性
- K210 开发板默认已经焊接好功放和扬声器,功放的作用是把音源的弱信号放大,然后推动扬声器发声。而功放是通过 I2S 协议与 K210芯片通讯的。
- I2S 总线英文简称 Inter-ICSound,是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专门用于音频设备之间的数据传输, 广泛应用于各种多媒体系统。I2S 也是同步串行通信接口。
- 集成电路内置音频总线共有 3 个(I²S0、I²S1、I²S2),都是 MASTER 模式。 其中 I²S0 支持可配置连接语音处理模块,实现语音增强和声源定向的功能。下 面是一些共有的特性:
• 总线宽度可配置为 8,16,和 32 位
• 每个接口最多支持 4 个立体声通道
• 由于发送器和接收器的独立性,所以支持全双工通讯
• APB 总线和 I²S SCLK 的异步时钟
• 音频数据分辨率为 12,16,20,24 和 32 位
• I²S0 发送 FIFO 深度为 64 字节, 接收为 8 字节,I²S1 和 I²S2 的发送和接收 FIFO 深度都为 8 字节
• 支持 DMA 传输
• 可编程 FIFO 阈值
硬件连接
K210 开发板出厂默认已经焊接扬声器及相关配件,其中 SPK_WS 连接到 IO30,SPK_DATA 连接到 IO31,SKP_BCK 连接到 IO32。
SDK 中对应 API 功能
以头文件 i2s.h为例
I2S 标准总线定义了三种信号:时钟信号 BCK、声道选择信号 WS 和串行数据信号 SD。一个基本的 I2S 数据总线有一个主机和一个从机。主机和从机的角色在通信过程中保持不变。I2S 模块包含独立的发送和接收声道,能够保证优良的通信性能。
• i2s_init:初始化 I2S 设备,设置接收或发送模式,通道掩码。
• i2s_send_data_dma:I2S 发送数据。
• i2s_recv_data_dma:I2S 接收数据。
• i2s_rx_channel_config:设置接收通道参数。
• i2s_tx_channel_config:设置发送通道参数。
• i2s_play:发送 PCM 数据, 比如播放音乐
• i2s_set_sample_rate:设置采样率。
• i2s_set_dma_divide_16:设置 dma_divide_16,16 位数据时设置 dma_divide_16,DMA 传输时自动将 32 比特 INT32 数据分成两个 16 比特的左右声道数据。
• i2s_get_dma_divide_16:获取 dma_divide_16 值。用于判断是否需要设置 dma_divide_16。
• i2s_handle_data_dma:I2S 通过 DMA 传输数据。
实验原理
I2S 有 3 个主要信号:
- 串行时钟 SCLK,也叫位时钟(BCLK),即对应数字音频的每一位数据,SCLK都有 1 个脉冲。SCLK 的频率=2×采样频率×采样位数
- 帧时钟 LRCK,用于切换左右声道的数据。LRCK 为“1”表示正在传输的是左声道的数据,为“0”则表示正在传输的是右声道的数据。LRCK 的频率等于采样频率。
- 串行数据 SDATA,就是用二进制补码表示的音频数据。
- I2S 格式的信号无论有多少位有效数据,数据的最高位总是出现在 LRCK 变化(也就是一帧开始)后的第 2 个 SCLK 脉冲处(如上)。这就使得接收端与发送端的有效位数可以不同。如果接收端能处理的有效位数少于发送端,可以放弃数据帧中多余的低位数据;如果接收端能处理的有效位数多于发送端,可以自行补足剩余的位。这种同步机制使得数字音频设备的互连更加方便,而且不会造成数据错位。对于
MCLK 是主时钟或系统时钟,能够保证两个芯片之间同步。 - DAC 芯片将 I2S 信号转化成 RCH 信号输送给功放,功放将 RCH 信号发大,然 后扬声器播放出对应的声音
实验过程
- 首先初始化 K210 的硬件引脚和软件功能使用的是 FPIOA 映射关系。
// 硬件IO口,与原理图对应
#define PIN_SPK_WS (30)
#define PIN_SPK_DATA (31)
#define PIN_SPK_BCK (32)
/*****************************SOFTWARE-GPIO********************************/
// 软件GPIO口,与程序对应
/*****************************FUNC-GPIO************************************/
// GPIO口的功能,绑定到硬件IO口
#define FUNC_SPK_WS FUNC_I2S2_WS
#define FUNC_SPK_DATA FUNC_I2S2_OUT_D0
#define FUNC_SPK_BCK FUNC_I2S2_SCLK
void hardware_init(void)
{
/*
** SPK_WS---IO30
** SPK_DATA-IO31
** SPK_BCK--IO32
*/
fpioa_set_function(PIN_SPK_WS, FUNC_SPK_WS);
fpioa_set_function(PIN_SPK_DATA, FUNC_SPK_DATA);
fpioa_set_function(PIN_SPK_BCK, FUNC_SPK_BCK);
}
- 设置系统时钟频率,由于 uarths 的时钟来自 PLL0,所以设置 PLL0 之后需要重新初始化以下 uarths,否则 printf 可能会打印乱码。
/* 设置系统时钟 */
sysctl_pll_set_freq(SYSCTL_PLL0, 320000000UL);
sysctl_pll_set_freq(SYSCTL_PLL1, 160000000UL);
sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL);
uarths_init();
- 初始化 I2S 设备 2 为发送模式,注意通道掩码对应通道 0:0x03,通道 1:0x0C,通道 2:0x30,通道 3:0xC0,。
/* 初始化I2S,第三个参数为设置通道掩码,通道0:0x03,通道1:0x0C,通道2:0x30,通道3:0xC0 */
i2s_init(I2S_DEVICE_2, I2S_TRANSMITTER, 0x03);
- 设置 I2S 发送数据通道 0 的参数,接收数据位 16bit,单个时钟数据位 32,DMA 触发 FIFO 深度为 4,工作模式为右声道。
i2s_tx_channel_config(
I2S_DEVICE_2, /* I2S设备号*/
I2S_CHANNEL_0, /* I2S通道 */
RESOLUTION_16_BIT, /* 接收数据位数 */
SCLK_CYCLES_32, /* 单个数据时钟数 */
TRIGGER_LEVEL_4, /* DMA触发时FIFO深度 */
RIGHT_JUSTIFYING_MODE); /* 工作模式 */
- I2S 播放音乐,播放音乐需要使用 DMA 通道,只要选择一个空闲的 DMA 通道即可,PCM 数据可以通过 wav 音乐文件转化。
i2s_play(
I2S_DEVICE_2, /* I2S设备号 */
DMAC_CHANNEL0, /* DMA通道号 */
(uint8_t *)test_pcm, /* 播放的PCM数据 */
sizeof(test_pcm), /* PCM数据的长度 */
1024, /* 单次发送数量 */
16, /* 单次采样位宽 */
2); /* 声道数 */
- 最后是一个 while(1)循环,不让系统退出。如果需要重新播放音乐,请按一下开发板的复位键。
while (1);
return 0;
- 编译调试,烧录运行
进入自己项目 build目录,运行以下命令编译。
cmake .. -DPROJ=watchdog -G "MinGW Makefiles"
make
实验现象
K210 开发板播放一次音乐,最后停止,当需要再次播放音乐时,请按一下K210 开发板的复位键。
实验总结
- 扬声器不是直接接收 K210 芯片数据的,而是经过 DAC 转化后经过功放放大信号,最后才是扬声器接收的信号。
- 扬声器播放音乐需要使用 DMA 通道播放。
- I2S 是专用于声音传输的协议,只需要三根线就可以传输音乐数据。