0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于MM32F5270的I2S音频播放

jf_pJlTbmA9 来源:瑞萨MCU小百科 作者:瑞萨MCU小百科 2023-10-30 17:13 次阅读

MM32F5270 系列控制器支持 I2S 总线接口,本章节在接下来会对 MM32F5270 I2S进行介绍,并使用 MM32F5270 和 CS4344 芯片进行 I2S 通信来演示播放一段声音。

I2S 简介

I2S ( Inter—IC Sound ) 总线是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,该总线专责于音频设备之间的数据传输,广泛应用于各种多媒体系统。它采用了沿独立的导线传输时钟与数据信号的设计,通过将数据和时钟信号分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。在飞利浦公司的 I2S 标准中,既规定了硬件接口规范,也规定了数字音频数据的格式。

在 MM32F5270 中,SPI 与 I2S 共用引脚。在 I2S 的描述中,支持半双工通信,也支持全双工模式。I2S 与 SPI 区别在于,I2S 主模式的控制逻辑使用独立的时钟分频处理单元。在半双工模式下,可使用 MCK 引脚输出驱动时钟,用于驱动外部音频组件。在全双工模式下,为了能同时进行数据的收发,MCK 驱动时钟只能从专用的 MCK 功能引脚输出。I2S 的功能框图如图 1 所示,包括时钟单元,寄存器控制单元,主从模式控制单元等。

wKgaomUD3a6ActtQAAGSyMNl8oo423.png 图1. I2S 功能框图

MM32F5270 中 I2S 主要特征

● 支持半双工通信(仅发射机或接收机)和全双工通信(SD,extSD 的数据方向根据主/从模式配置决定)两种通信方式

● 9 位可编程线性预分频器,以达到精确的音频采样频率( 8KHz 到 192KHz)

● 数据帧格式可以是 16 位、 24 位或 32 位

● 数据包帧固定为 16 位(16 位有效数据)或 32 位(16 位、 24 位、 32 位有效数据)

● 可编程时钟极性(稳定状态)

● 发射模式下的下溢标志(仅从机),接收模式下的上溢标志(主和从机)和接收/发射模式下的帧错误标志(仅从机)

● 用于传输和接收的 32 位寄存器为两个声道分时复用

● 支持 I2S 协议

▶ 飞利浦标准

▶ MSB 对齐标准(左对齐)

▶ LSB 对齐标准(右对齐)

▶ PCM 标准(在 16 位信道帧上具有短帧和长帧同步或扩展到 32 位信道帧的 16 位数据帧)

● 数据方向始终是 MSB 优先

DMA 传输能力

● 可配置输出 MCLK 来驱动外部音频组件,比率固定在 256× FS(其中 FS 为音频采样频率)

I2S 信号接口

I2S 和 SPI 共用三个公共管脚:

● 串行时钟 CK

映射在 SCK 引脚上,也叫位时钟 BCLK,是主模式下的串行时钟输出以及从机模式下的串行时钟输入。SCLK 频率 = 2 x 采样频率 x 采样位数

● 帧时钟 WS

映射在 NSS 引脚上,是主模式下的串行时钟输出以及从机模式下的串行时钟输入。用于切换左右声道,LRCK 频率 = 采样频率

● 串行数据 SD

映射在 MOSI 管脚上,二进制补码表示的音频数据,用于发送或接收两次多路数据通道(仅在半双工模式下)。

● 当某些外部设备需要主时钟输入时,可以使用一个附加的管脚输出时钟到音频设备

● 主时钟 MCLK

映射在 MISO 引脚或专用 MCK 引脚上,当 I2S 配置为主模式时使用此时钟。MCLK 频率 = 256 x 采样频率 Fs

● I2S 引脚信号如图 2 所示。

wKgaomUD3a-Ad28hAANfi7UKZ1M596.png 图2. I2S 引脚信号

数据格式

三线总线处理音频数据,必须经过分时复用两个声道:右声道和左声道。因为只有一个 32 位寄存器用于传输或接收,所以软件应依次配置寄存器 TXREG 为各声道的数据,或依次读取寄存器 RXREG 为各声道的数据。按照 I2S 协议,总是先发送左声道,然后发送右声道。

数据格式可以采用以下格式进行发送:

● 16 位数据打包在 16 位帧中

● 16 位数据打包在 32 位帧中

● 24 位数据打包在 32 位帧中

● 32 位数据打包在 32 位帧中

当使用 32 位帧上发送 16 位数据时,前 16 位(MSB)是有效的位,16 位 LSB 制为 0,无需任何软件操作,通过硬件实现,其他格式相似。

通信标准

I2S 接口支持四种音频标准,通过配置寄存器 SPI_I2S_I2SCFGR 中的 I2SSTD[1:0]、PCMSYNC 位进行切换;数据格式则通过配置 DATLEN[1:0]、CHLEN 来进行选择。对于所有通信标准及数据格式,总是先发送最高位(MSB 优先)。

● 飞利浦标准

对于飞利浦标准,WS 信号用于指示正在传输的声道。发射器在 CK 的下降沿锁存数据,接收器并在 CK 的上升读取数据。WS 信号也在 CK 的下降沿被锁定。对于这种标准 I2S 格式的信号,无论有多少位有效数据,数据的最高位总是出现在 WS 变化(也就是一帧开始)后的第 2 个 CK 脉冲处,如图 3 所示。

wKgZomUD3bKAKdL1AADz5zitP8Q211.png 图3. 飞利浦标准示意图

● MSB 对齐标准

对于 MSB 对齐标准,第一个数据在 WS 变化后的第一个沿有效,如图 4 所示。

wKgZomUD3bOACko_AAEoZUsLWVo322.png 图4. MSB 对齐标准示意图

● LSB 对齐标准

对于 LSB 对齐标准,每个数据包帧的最低有效位总(LSB 位)是出现在 WS 变化前的 1 个 CK 脉冲周期处,如图 5 所示。

wKgZomUD3bSAY4f9AAEEY33ZhHE516.png 图5. LSB 对齐标准示意图

● PCM 标准

对于 PCM 标准,不需要使用声道信息。PCM 有两个模式:短帧模式和长帧模式,通过配置SPI_I2S_I2SCFGR 寄存器的 PCMSYNC 位进行切换。在 PCM 模式下,输出信号(WS, SD)在 CK 信号的上升沿进行采样。输入信号(WS, SD)在 CK 下降沿被捕获。注意在主模式下, CK 和 WS 被配置为输出,如图 6 所示。

wKgaomUD3bWAfZB7AADhaxkSFQ8173.png 图6. PCM 对齐标准示意图

I2S 配置

I2S 的配置主要包括主从模式选择,时钟极性,全双工半双工模式选择,采样频率和通信标准的配置,从而进行数据传输。

主模式

I2S 功能的主模式下,选择全双工工作时,SD 引脚作为主机发送接口,extSD 作为主机接收接口,SCK 和 WS作为主机的输出信号,同时 MCK 向外部提供可选的驱动时钟(配置 SPI_I2S_I2SCFGR.MCKOE 位为 ‘1’ 使能 MCK 输出),如图 7 所示。

wKgaomUD3beAKu45AADWcrg5oGU391.png 图7. I2S 主模式全双工通信

基于 MM32F5270 的声音播放实验

CS4344 芯片是实现本次实验功能的重要器件之一。CS4344 是一种立体声音频数模转换器 (DAC) ,可使用单个 +3.3 V 或 +5 V 电源,仅需要最小的支持电路。该系列线性模拟低通滤波器和自动速度模式检测,当自动选择 2 kHz 和 200 kHz 之间的采样率,使用采样率和主时钟速率方法。

本实验的基本原理是 MM32F3270 读取正弦波采样计算出的左右声道的数组数据,通过 I2S 接口将 PCM 信号传输给 CS4344,再经过 TS4871(音频功率放大器)连接到耳机接口,可以接入耳机等音频播放装置。

硬件设计

如图 8-9 是 PLUS-F5270 的 I2S 电路部分,完整原理图可以通过官网下载。其中,引脚信号对应分别为:

▶ I2S2_SD 对应于引脚 E6

▶ I2S2_CK 对应于引脚 D3

▶ I2S2_WS 对应于引脚 E4

▶ I2S2_MCK 对应于引脚 E5

wKgZomUD3bmADlxxAAGDC8dm8xM772.png 图8. I2S 电路图(1)
wKgaomUD3buARtDsAAI-hQn2YbE637.png 图9. I2S 电路图(2)

GPIO 初始化 BOARD_InitPins()

配置 I2S 引脚,I2S_CK 为 PD3 引脚,I2S_SD 为 PE6 引脚,I2S_WS 为 PE4 引脚,I2S_MCK 为 PE5 引脚,复用通道为 AF5 。

void BOARD_InitPins(void)
{
    /* PB7 - UART1_TX. */
    GPIO_Init_Type gpio_init;
    gpio_init.Pins  = GPIO_PIN_6;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull; //GPIO_PinMode_AF_PushPull
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,  gpio_init);
    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

    /* PB6 - UART1_RX. */
    gpio_init.Pins  = GPIO_PIN_7;
    gpio_init.PinMode  = GPIO_PinMode_In_Floating; //GPIO_PinMode_In_Floating
    gpio_init.Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,  gpio_init);
    GPIO_PinAFConf(GPIOB, gpio_init.Pins, GPIO_AF_7);

    /* PD3 - I2S_CK. */
    gpio_init.Pins  = GPIO_PIN_3;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull; //GPIO_PinMode_In_PushPull
    gpio_init.Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOD,  gpio_init);
    GPIO_PinAFConf(GPIOD, gpio_init.Pins, GPIO_AF_5);

    /* PE6 - I2S_SD. */
    gpio_init.Pins  = GPIO_PIN_6;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull; //GPIO_PinMode_In_PushPull
    gpio_init.Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOE,  gpio_init);
    GPIO_PinAFConf(GPIOE, gpio_init.Pins, GPIO_AF_5);

    /* PE4 - I2S_WS. */
    gpio_init.Pins  = GPIO_PIN_4;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull; //GPIO_PinMode_In_PushPull
    gpio_init.Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOE,  gpio_init);
    GPIO_PinAFConf(GPIOE, gpio_init.Pins, GPIO_AF_5);

    /* PE5 - I2S_MCK. */
    gpio_init.Pins  = GPIO_PIN_5;
    gpio_init.PinMode  = GPIO_PinMode_AF_PushPull; //GPIO_PinMode_In_PushPull
    gpio_init.Speed = GPIO_Speed_10MHz;
    GPIO_Init(GPIOE,  gpio_init);
    GPIO_PinAFConf(GPIOE, gpio_init.Pins, GPIO_AF_5);
}

I2S 配置初始化 app_i2s_master_init()

初始化 I2S,配置时钟频率、采样率、数据长度、通信协议、传输模式及是否使能 MCLK 。

void app_i2s_master_init(void)
{
    /* setup I2S master module. */
    I2S_Master_Init_Type i2s_master_init;

    i2s_master_init.ClockFreqHz  = BOARD_I2S_FREQ;
    i2s_master_init.SampleRate   = BOARD_I2S_SAMPLE_RATE;
    i2s_master_init.DataWidth    = BOARD_I2S_DATA_WIDTH;
    i2s_master_init.Protocol     = BOARD_I2S_PROTOCOL;
    i2s_master_init.EnableMCLK   = true;
    i2s_master_init.Polarity     = BOARD_I2S_CPOL;
    i2s_master_init.XferMode     = I2S_XferMode_TxOnly;

    I2S_InitMaster(BOARD_I2S_PORT,  i2s_master_init);

    /* enable I2S. */
    I2S_Enable(BOARD_I2S_PORT, true);
}

● Protocol

通信标准格式选择,可选 I2S Philips 标准、左对齐标准、右对齐标准、 PCM 短帧标准或 PCM 长帧标准,它设定 SPI_I2S_I2SCFGR 寄存器 I2SSTD位和 PCMSYNC位的值。一般设置为 I2S Philips 标准即可。

● DataWidth

数据格式选择,设定有效数据长度和帧长度,可选标准 16bit 格式、扩展 16bit( 32bit 帧长度) 格式、 24bit 格式和 32bit 格式,它设定 SPI_I2SCFGR 寄存器 DATLEN 位和CHLEN 位的值。对应 16bit 数据长度可选 16bit 或 32bit 帧长度,其他都是 32bit 帧长度。

● EnableMCLK

主时钟输出使能控制,可选使能输出或禁止输出,它设定 SPI_I2SPR 寄存器 MCKOE 位的值。为提高系统性能一般使能主时钟输出。

● SampleRate

采样频率设置,标准库提供采样采样频率选择,分别为 4KHz、8kHz、 11kHz、12KHz、16kHz、22kHz、32kHz、44kHz、48kHz、96kHz、192kHz 以及默认 2Hz,它设定 SPI_I2S_SPBRG 寄存器的值。

● Polarity

空闲状态的 CK 线电平,可选高电平或低电平,它设定 SPI_I2S_CCTL 寄存器 CPOL位的值。一般设置为低电平即可。

左右声道数据

采样函数 f (t) = A *sin( B*t ) , t 为采样时间,单位: s。采样位宽为 16bit,采样频率为 8 khz,系数 A 为10000,B 为2000π。

/* i2s left channel xfer data. */
const int16_t sound_buf_left[SOUND_BUF_SIZE] =
{
    0, 3535, 5000, 3535, 0, -3535, -5000, -3535,
    0, 3535, 5000, 3535, 0, -3535, -5000, -3535,
};

/* i2s right channel xfer data. */
const int16_t sound_buf_right[SOUND_BUF_SIZE] =
{
    0,  3827,  7071,  9238,  10000,  9238,  7071,  3827,
    0, -3827, -7071, -9238, -10000, -9238, -7071, -3827
};

左右声道数据传输

/* put data into left channel. */
void app_i2s_put_data_left(void)
{
    I2S_PutData(BOARD_I2S_PORT, (uint32_t)sound_buf_left[sound_buf_index_left]);
    sound_buf_index_left++;
    if (sound_buf_index_left >= SOUND_BUF_SIZE)
    {
        sound_buf_index_left = 0;
    }
}

/* put data into right channel. */
void app_i2s_put_data_right(void)
{
    I2S_PutData(BOARD_I2S_PORT, (uint32_t)sound_buf_right[sound_buf_index_right]);
    sound_buf_index_right++;
    if (sound_buf_index_right >= SOUND_BUF_SIZE)
    {
        sound_buf_index_right = 0;
    }
}

main() 函数

main() 函数结合上述操作,串口打印 "i2s_master_basic" ,初始化 I2S 后,将发送数组数据到左右声道缓冲区,进行声音播放。

int main(void)
{
    BOARD_Init();

    printf("i2s_master_basic.rn");

    app_i2s_master_init();

    while (1)
    {
        while(0u != (I2S_GetStatus(BOARD_I2S_PORT)   SPI_I2S_CSTAT_TXFULL_MASK) )
        {}

        app_i2s_put_data_left(); /* sending left channel data. */

        while(0u != (I2S_GetStatus(BOARD_I2S_PORT)   SPI_I2S_CSTAT_TXFULL_MASK) )
        {}
        app_i2s_put_data_right(); /* sending right channel data. */
    }
}

实验演示

本实验以搭载 MM32F5277E9PV 的 PLUS-F5270 开发板为平台,其扬声器将会播放左声道数据,演示视频如下:

演示1. 播放左声道数据

音响数据的采集、处理和传输是多媒体技术的重要组成部分。众多的数字音频系统已经进入消费市场,例如数字音频录音带、数字声音处理器。对于设备和生产厂家来说,标准化的信息传输结构可以提高系统的适应性。

本文介绍了 MM32F5270 中通过 I2S 和 CS4344 芯片进行通信来演示播放一段声音,后续将进行 MP3 的播放,未完待续!

来源:瑞萨MCU小百科

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 接口
    +关注

    关注

    33

    文章

    8575

    浏览量

    151015
  • 总线
    +关注

    关注

    10

    文章

    2878

    浏览量

    88051
  • 音频播放
    +关注

    关注

    0

    文章

    8

    浏览量

    7764
收藏 人收藏

    评论

    相关推荐

    基于MM32F5270开发板获取雨滴传感器的数据相关资料介绍

    MM32F5270 微控制器厉害了,曾经获得2022中国IC设计成就奖之年度最佳MCU,让我们一起目睹该开发板的真容吧。  该开发板的集成的了:  4KB L1 I-Cache,4KB L1 D-Cache
    发表于 08-24 15:20

    一文解析MM32F5270开发板+PWM测试与调制

    1、MM32F5270开发板+ PWM测试与调制  PWM接口引脚  MM32F5270开发板有引出PWM引脚给我们,我们可以直接使用就行。  主要代码部分如下  2.1 hal_tim.c
    发表于 09-06 11:24

    聊聊 MM32F5270是如何通过高并行度的总线设计实现系统吞吐率的最大化的

    基于 MM32F5270 制作一个带显示的音频播放器,这是一种很常见的应用场景,实际产品中所包含的功能可能是多种多样的,这里为了简化,以如下规格要求为例:可播放 SD 卡上的
    发表于 09-06 15:06

    MM32F5270开发板上播放TF卡WAV格式音乐

    。  在MM32F5270中,SPI与I2S共用引脚。在I2S的描述中,支持半双工通信,也支持全双工模式(通过配置SPI_I2S_I2SCFGR.HDSEL 位来决定)。原作者:kin
    发表于 09-20 15:26

    103xx通过外部I2S音频解码器播放音频文件

    103xx通过外部I2S音频解码器播放音频文件。
    发表于 01-12 18:26 56次下载

    MM32F5270总线架构设计

    本文介绍了MM32F5270 中所采用的多并发总线架构,并通过带显示的音频播放器的实例说明了该架构在实际应用中所能达到的吞吐率提升效果。
    的头像 发表于 05-11 11:15 2170次阅读
    <b class='flag-5'>MM32F5270</b>总线架构设计

    基于MM32F5270控制器的I2S音频播放

    MM32F5270 系列控制器支持 I2S 总线接口,本章节在接下来会对 MM32F5270 I2S进行介绍,并使用 MM32F5270
    的头像 发表于 09-16 10:39 2353次阅读

    MM32F5270】Keil开发环境搭建

    本文是对MM32F5270相关的灵动官网资料和社区现有几篇环境搭建帖的整理和总结。详细且完整的记录了——如何从零搭建MM32F5270 Keil开发环境以及如何编译运行MM32F5270 SDK中
    的头像 发表于 11-06 16:14 2748次阅读
    【<b class='flag-5'>MM32F5270</b>】Keil开发环境搭建

    MM32F5270 产品手册(中文版)

    MM32F5270 产品手册(中文版)
    发表于 02-23 18:45 0次下载
    <b class='flag-5'>MM32F5270</b> 产品手册(中文版)

    MM32F5270 产品手册(英文版)

    MM32F5270 产品手册(英文版)
    发表于 02-23 18:45 0次下载
    <b class='flag-5'>MM32F5270</b> 产品手册(英文版)

    MM32F5270 用户手册(中文版)

    MM32F5270 用户手册(中文版)
    发表于 02-23 18:46 0次下载
    <b class='flag-5'>MM32F5270</b> 用户手册(中文版)

    MM32F5270 用户手册(英文版)

    MM32F5270 用户手册(英文版)
    发表于 02-23 18:46 0次下载
    <b class='flag-5'>MM32F5270</b> 用户手册(英文版)

    MM32F5270 勘误表(中文版)

    MM32F5270 勘误表(中文版)
    发表于 02-23 18:47 0次下载
    <b class='flag-5'>MM32F5270</b> 勘误表(中文版)

    MM32F5270 勘误表(英文版)

    MM32F5270 勘误表(英文版)
    发表于 02-23 18:48 0次下载
    <b class='flag-5'>MM32F5270</b> 勘误表(英文版)

    基于MM32F3270 I2S使用

    基于MM32F3270 I2S使用
    的头像 发表于 09-27 15:50 796次阅读
    基于<b class='flag-5'>MM32F</b>3270 <b class='flag-5'>I2S</b>使用