第三十五章 I2S——音频传输接口

第三十五章 I2S——音频传输接口

目录

第三十五章 I2S——音频传输接口

1 I2S概述

1.1 简介

1.2 功能特点

1.3 工作原理

1.4 利用DMA通信的I2S

1.4.1 I2S配合DMA通信工作原理

1.4.2 配置要点

2 应用场景

2.1 消费类音频设备

2.2 专业音频设备

2.3 通信设备

2.4 汽车电子

2.5 嵌入式系统

3 注意事项

4 程序设计

4.1 IIS_CS4344例程

4.1.1 I2S初始化

4.1.2 DMA初始化

4.1.3 中断配置函数

4.1.4 中断服务函数

4.1.5 数据处理函数

4.1.6 主程序

4.1.7 下载验证

4.2 IIS_Dma例程

4.2.1 发送数据

4.2.2 中断服务函数

4.2.3 主程序

4.2.4 下载验证

4.3 IIS_Int例程

4.3.1 I2S初始化

4.3.2 中断服务函数

4.3.3 主程序

4.4.4 下载验证

5 总结


I2S(Inter-Integrated Circuit Sound)W55MH32中用于数字音频传输的重要接口,广泛应用于各种音频设备与嵌入式系统。本文将从工作原理、注意事项、应用场景以及程序设计来讲解I2S接口,和大家一起学习和使用这一技术。

1 I2S概述

1.1 简介

I2S(Inter-Integrated Circuit Sound)是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准,专门用于音频设备之间的高质量数字音频传输。在W55MH32中,I2S功能与SPI模块共享相同的硬件资源,通过将寄存器SPI_I2SCFGRI2SMOD位置为'1'即可使能I2S功能,将SPI模块转换为I2S音频接口。

I2S接口与SPI接口使用大致相同的引脚、标志和中断,但专为音频数据传输优化。它采用独立的导线传输时钟与数据信号,通过将数据和时钟信号分离,避免了因时差诱发的失真,为用户节省了购买抵抗音频抖动的专业设备的费用。I2S已成为数字音频领域的事实标准接口,广泛应用于各种消费电子和专业音频设备中。

1.2 功能特点

W55MH32I2S接口有以下特点:

  • 单工通信(仅发送或接收)
  • 主或者从操作
  • 8位线性可编程预分频器,获得精确的音频采样频率(8KHz96kHz)
  • 数据格式可以是16位,24位或者32
  • 音频信道固定数据包帧为16(16位数据帧)32(162432位数据帧)
  • 可编程的时钟极性(稳定态)
  • 从发送模式下的下溢标志位和主/从接收模式下的溢出标志位
  • 16位数据寄存器用来发送和接收,在通道两端各有一个寄存器
  • 支持的I2S协议:
    • I2S飞利浦标准
    • MSB对齐标准(左对齐)
    • LSB对齐标准(右对齐)
  • PCM标准(16位通道帧上带长或短帧同步或者16位数据帧扩展为32位通道帧)
  • 数据方向总是MSB在先
  • 发送和接收都具有DMA能力
  • 主时钟可以输出到外部音频设备,比率固定为256xFs(Fs为音频采样频率)

1.3 工作原理

I2S接口的核心工作原理基于三个主要信号线的协同工作:

  • 串行时钟(SCK/CK):也称为位时钟(BCLK),由主设备产生,用于同步数据传输。每个时钟周期对应音频数据的一位。SCK的频率计算公式为:SCK频率 = 2 × 采样频率 × 采样位数。例如,对于44.1kHz采样率、16位精度的立体声音频,SCK频率应为44.1kHz×16bits×2(左右声道)=1.4112MHz
  • 字选择(WS):也称为帧时钟(LRCK),用于指示当前传输的音频数据所属声道。在I2S飞利浦标准下,WS'0'表示左声道数据,为'1'表示右声道数据。WS信号在发送第一位数据(MSB)1个时钟周期即变为有效。
  • 串行数据(SD):承载实际的音频数据,采用二进制补码表示。数据总是从最高位(MSB)开始传输,与SPI接口的MSB优先模式类似。

在某些需要更高精度时钟同步的系统中,还可以使用第四个信号线:

  • 主时钟(MCK)为外部音频编解码器提供系统时钟参考,通常设置为采样频率的256(256xFs)。当寄存器SPI_I2SPRMCKOE位为'1'时,W55MH32可输出此额外时钟信号。

I2S的数据传输遵循严格的时序关系。在I2S飞利浦标准下,发送方在时钟信号(CK)的下降沿改变数据,接收方在上升沿读取数据。WS信号也在时钟信号的下降沿变化。这种同步机制确保了数据传输的可靠性,即使在高速率下也能保持较低的误码率。

对于不同数据格式的处理,I2S硬件提供了自动的数据对齐和填充功能。例如,当16位数据扩展到32位帧时,高16(MSB)为有效数据,低16位被硬件强制为0x0000,无需软件干预。24位数据扩展到32位帧时,高24位为有效数据,低8位由硬件置0。这种自动处理大大简化了软件开发,特别是在使用DMA传输时。

I2S的功能框图如下:

1.4 利用DMA通信的I2S

1.4.1 I2S配合DMA通信工作原理

I2S接口与DMA控制器协同工作时,形成高效的数据传输通道。通过将寄存器SPI_CR2TXDMAEN/RXDMAEN位置1,可使能DMA传输请求。I2S模式下DMA的工作方式与SPI模式基本相同,只是没有CRC功能。当I2S接口需要发送或接收数据时,会自动触发DMA请求:

  • 发送过程TXE标志置1时触发DMA请求,DMA控制器将数据从内存搬运至SPI_DR寄存器。
  • 接收过程RXNE标志置1时触发DMA请求,DMA控制器将数据从SPI_DR寄存器搬运至内。

使用DMA发送和接收的时序图如下:

1.4.2 配置要点

数据格式处理

I2S支持多种数据格式,DMA需要相应配置:

数据格式

DMA传输次数

备注

16位→16位帧

1

直接传输

16位→32位帧

1

硬件自动补0

24位→32位帧

2

硬件补低80

32位→32位帧

2

完整32位处理

声道管理

  • 左声道数据总是先传输
  • 通过CHSIDE标志识别当前声道
  • 从模式需提前准备好第一个数据

发送流程

  1. 配置DMA:内存→SPI_DR,设置数据宽度
  2. 启动传输:TXE=1时自动触发
  3. 声道切换:根据CHSIDE处理左右声道
  4. 完成处理:等待TXE=1BSY=0后关闭

接收流程

  1. 配置DMASPI_DR→内存,设置数据宽度
  2. 启动传输:RXNE=1时自动触发
  3. 数据解析:根据标准处理数据对齐
  4. 关闭时序:按数据格式选择正确时序

2 应用场景

W55MH32I2S接口凭借其高质量数字音频传输能力,在众多领域得到广泛应用:

2.1 消费类音频设备

便携式音乐播放器:连接音频DAC实现高质量音乐播放,支持从MP3解码器到功率放大器的数字音频传输。

智能音箱:用于主控芯片与数字音频处理器之间的连接,实现语音助手和音乐播放功能。

数字电视和机顶盒:传输数字音频信号到音频处理芯片或直接驱动数字功放。

2.2 专业音频设备

录音设备:连接高性能ADC实现多通道音频采集,支持24位高分辨率录音。

音频混音器:在数字域混合多个音频源,保持信号完整性。

效果处理器:传输音频数据到DSP芯片进行实时效果处理。

2.3 通信设备

VoIP电话:实现双向语音通信,同时支持回声消除等高级功能。

会议系统:连接数字麦克风阵列和音频处理单元。

无线耳机:在蓝牙模块与编解码器之间传输音频数据。

2.4 汽车电子

车载娱乐系统:连接多个音频源和功放,支持环绕声处理。

主动降噪系统:实时采集车内噪声并生成反相声波。

语音识别系统:传输高清晰度语音数据到语音处理单元。

2.5 嵌入式系统

工业控制人机界面:实现语音提示和报警功能。

医疗监护设备:传输心音、呼吸音等生物音频信号。

智能家居:用于门铃、对讲系统等需要音频功能的设备。

3 注意事项

  1. 时钟同步:从模式需确保在外部时钟有效前完成初始化。
  2. 数据对齐:注意不同标准(Philips/MSB/LSB)的数据对齐差异。
  3. 电源管理:模拟部分供电需加强滤波处理。
  4. PCB布局:时钟信号线应尽量短并考虑端接匹配。
  5. 关闭顺序:严格按照规范流程关闭接口,避免数据损坏。

4 程序设计

4.1 IIS_CS4344例程

IIS_CS4344例程主要实现了基于W55MH32芯片的I2S音频传输功能。以下是实现过程和结果验证:

4.1.1 I2S初始化

I2S的初始化函数为IIS_Configuration()函数:

void IIS_Configuration(void)
{
    I2S_InitTypeDef  I2S_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_3 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOC, &GPIO_InitStructure);SPI_I2S_DeInit(SPI3);
    I2S_InitStructure.I2S_Mode       = I2S_Mode_MasterTx;
    I2S_InitStructure.I2S_Standard   = I2S_Standard_Phillips;
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
    I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_8k;
    I2S_InitStructure.I2S_CPOL       = I2S_CPOL_Low;
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;I2S_Init(SPI3, &I2S_InitStructure);SPI_I2S_DMACmd(SPI3, SPI_I2S_DMAReq_Tx, ENABLE);I2S_Cmd(SPI3, ENABLE);
}

该函数首先使能了相关时钟并释放GPIOA15资源(PA15默认为调试接口,必须先释放其默认的调试功能,否则,调试接口会持续占用该引脚,导致I2S无法正常工作。),然后配置GPIOA15GPIOB3GPIOB5GPIOC7为复用推挽输出模式以连接I2SSCKSDWSMCLK信号,接着将SPI3初始化为I2S模式并设置为主机发送模式,采用飞利浦标准、16位数据格式、8kHz采样率,启用MCLK输出和低时钟极性,最后使能DMA传输以提高数据效率并激活I2S外设。

4.1.2 DMA初始化

DMA_Configuration()DMA初始化函数:

void DMA_Configuration(void)
{
    DMA_InitTypeDef DMA_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);DMA_DeInit(DMA2_Channel2);    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&SPI3->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32_t)I2S3_Buffer_Tx;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize         = BufferSize;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;DMA_Init(DMA2_Channel2, &DMA_InitStructure);DMA_ITConfig(DMA2_Channel2, DMA_IT_TC, ENABLE);/* Enable SPI1 DMA TX request */DMA_Cmd(DMA2_Channel2, DISABLE);
}

该函数首先使能了DMA2时钟,然后将DMA2通道2初始化为从内存到外设的传输模式,设置外设基址为SPI3的数据寄存器(用于I2S通信),内存基址为音频数据缓冲区I2S3_Buffer_Tx,配置传输方向为内存到外设、缓冲区大小为BufferSize,禁用外设地址自增、启用内存地址自增,设置数据宽度为半字(16位,与I2S数据格式匹配),采用循环模式确保连续传输,设置优先级为非常高,禁用内存到内存模式,最后使能传输完成中断并暂时禁用DMA通道。

4.1.3 中断配置函数

NVIC_Configuration()NVIC(嵌套向量中断控制器)的配置函数:

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel                   = DMA2_Channel2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

该函数首先定义NVIC了初始化结构体,然后将中断通道设置为DMA2通道2(对应I2S3TX DMA传输),配置抢占优先级和子优先级均为0(最高优先级),使能该中断通道,最后调用初始化函数完成配置,整体实现了对DMA2通道2传输完成事件的高优先级中断响应设置,确保音频数据传输中断能被及时处理。

4.1.4 中断服务函数

DMA2_Channel2_IRQHandler()DMA2通道2的中断服务函数:

void DMA2_Channel2_IRQHandler(void)
{if (DMA_GetITStatus(DMA2_IT_TC2) == SET){DMA_ClearITPendingBit(DMA2_IT_TC2);DMA_ClearFlag(DMA2_FLAG_TC2);DMA_Cmd(DMA2_Channel2, DISABLE);
        Flag = 1;}
}

程序首先检查是否为DMA传输完成中断(TC2),若是则清除中断挂起位和完成标志位,禁用DMA2通道2以暂停传输,最后将标志位Flag1以通知主程序数据已传输完毕,整体实现了对I2S音频数据DMA传输完成的响应处理,确保在数据发送完成后能进行必要的状态更新和后续操作。

4.1.5 数据处理函数

DATA_Processing()是数据处理函数,通过以下步骤实现将8位数据转换为16位格式:

void DATA_Processing(void)
{
    uint32_t i;    for (i = 0; i < DATA_LEN / 2; i++){
        I2S3_Buffer_Tx[i] = DATA[2 * i] << 8 | DATA[2 * i + 1];}
}

程序首先定义循环计数器,然后对长度为DATA_LEN8位数据源数组DATA进行遍历,每次取连续的两个8位数据,将前一个左移8位后与后一个按位或运算,组合成一个16位数据存入目标数组I2S3_Buffer_Tx中,整体实现了将8位原始数据转换为适合I2S传输的16位数据格式,确保音频数据能够正确地通过I2S接口发送。

4.1.6 主程序

主程序main()通过以下步骤实现I2S音频数据的持续传输:

int main(void)
{
    RCC_ClocksTypeDef clocks;delay_init();UART_Configuration(115200);RCC_GetClocksFreq(&clocks);printf("\n");printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);printf("IIS CS4344 Test.\n");IIS_Configuration();DMA_Configuration();NVIC_Configuration();DATA_Processing();DMA_Cmd(DMA2_Channel2, ENABLE);    while (1){if (Flag == 1){printf("IIS DMA Data Send Success\n");
            Flag = 0;DMA_Configuration();DMA_Cmd(DMA2_Channel2, ENABLE);}}
}

程序首先初始化系统时钟和延时函数,配置115200波特率的UART用于调试信息输出,获取并打印系统各时钟频率;接着依次配置I2S接口、DMA通道、NVIC中断控制器,并将8位原始数据处理为16位格式以适配I2S传输;然后启用DMA通道开始数据传输;最后在主循环中检测传输完成标志Flag,若置1则打印成功信息、重置标志,重新配置并启用DMA通道以实现循环传输,整体实现了通过I2S接口持续发送音频数据的功能。

4.1.7 下载验证

程序下载运行后,首先打印了系统各时钟的频率和示例名称,然后每发送成功一次I2S数据就会打印数据发送成功的信息:

此时我们接上DAC音频转换器、戴上耳机就能持续听到“微信到账100万元”的音频内容。

4.2 IIS_Dma例程

IIS_Dma例程通过I2S接口和DMA传输机制,发送预设的音频数据。该例程的I2S初始化、DMA初始化、中断配置函数与IIS_CS4344例程保持一致,这里不再赘述。其他程序设计如下:

4.2.1 发送数据

I2S3_Buffer_Tx为需要发送的测试数据:

uint16_t I2S3_Buffer_Tx[BufferSize] = {0x0102, 0x0304, 0x0506, 0x0708, 0x090A, 0x0B0C,
                                       0x0D0E, 0x0F10, 0x1112, 0x1314, 0x1516, 0x1718,
                                       0x191A, 0x1B1C, 0x1D1E, 0x1F20, 0x2122, 0x2324,
                                       0x2526, 0x2728, 0x292A, 0x2B2C, 0x2D2E, 0x2F30,
                                       0x3132, 0x3334, 0x3536, 0x3738, 0x393A, 0x3B3C,
                                       0x3D3E, 0x3F40};

4.2.2 中断服务函数

DMA2_Channel2_IRQHandlerW55MH32DMA2通道2的中断处理函数:

void DMA2_Channel2_IRQHandler(void)
{if (DMA_GetITStatus(DMA2_IT_TC2) == SET){DMA_ClearITPendingBit(DMA2_IT_TC2);DMA_ClearFlag(DMA2_FLAG_TC2);DMA_Cmd(DMA2_Channel2, DISABLE);
        Flag = 1;}
}

DMA完成预设的3216位数据传输后触发。函数首先检查传输完成中断状态,若中断已触发则清除中断挂起位和传输完成标志,避免重复响应;接着禁用DMA2通道2,停止数据传输;最后将全局标志位Flag1,通知主程序DMA传输已完成,主循环检测到该标志后会输出成功信息并重置标志。此函数实现了DMA传输的中断响应与状态反馈,是I2S音频数据传输流程中的关键环节。

4.2.3 主程序

主程序main()通过以下步骤实现I2S音频数据的传输:

int main(void)
{
    RCC_ClocksTypeDef clocks;delay_init();UART_Configuration(115200);RCC_GetClocksFreq(&clocks);printf("\n");printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);printf("IIS DMA Test.\n");IIS_Configuration();DMA_Configuration();NVIC_Configuration();DMA_Cmd(DMA2_Channel2, ENABLE);    while (1){if (Flag == 1){printf("IIS DMA Data Send Success\n");
            Flag = 0;}}
}

程序首先初始化系统时钟、UART调试接口并打印时钟信息,接着配置I2S接口(复用SPI3)、DMA2通道2(循环模式)和NVIC中断控制器,随后启用DMA开始将预设的3216位音频数据循环传输到I2S接口,主循环持续检测DMA传输完成标志位Flag,当Flag被中断处理函数置1时,打印传输成功信息并重置标志,不过因中断处理函数中禁用了DMA通道,实际数据仅能传输一次,此代码常用于音频设备初始化测试。

4.2.4 下载验证

程序下载运行后,首先打印了系统各时钟的频率和示例名称,然后I2S数据发送成功后打印数据发送成功的信息:

通过逻辑分析仪就可以解析出发送的数据:

首帧和尾帧的数据实际已经可以看到有数据脉冲信号,未解析属于硬件初始化特性(FIFO填充)或解析器同步延迟原因,不影响实际音频功能。

4.3 IIS_Int例程

IIS_Int例程通过I2S接口和中断控制器实现音频数据的中断驱动传输。其他程序设计如下:

4.3.1 I2S初始化

IIS_Configuration()函数用于初始化W55MH32I2S接口(复用SPI3外设)及中断配置,其内容如下:

void IIS_Configuration(void)
{
    I2S_InitTypeDef  I2S_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_3 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;GPIO_Init(GPIOB, &GPIO_InitStructure);    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;GPIO_Init(GPIOC, &GPIO_InitStructure);    NVIC_InitStructure.NVIC_IRQChannel                   = SPI3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;NVIC_Init(&NVIC_InitStructure);SPI_I2S_DeInit(SPI3);
    I2S_InitStructure.I2S_Mode       = I2S_Mode_MasterTx;
    I2S_InitStructure.I2S_Standard   = I2S_Standard_Phillips;
    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
    I2S_InitStructure.I2S_AudioFreq  = I2S_AudioFreq_8k;
    I2S_InitStructure.I2S_CPOL       = I2S_CPOL_Low;
    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable;I2S_Init(SPI3, &I2S_InitStructure);SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, ENABLE);I2S_Cmd(SPI3, ENABLE);
}

函数首先使能GPIOA/B/CSPI3的时钟,配置相关引脚为复用推挽输出(包括数据输出、字选择、串行时钟和主时钟引脚);接着配置NVIC中断控制器,设置SPI3中断的优先级并使能中断;然后重置SPI3并设置I2S参数,包括主发送模式、飞利浦标准、16位数据格式、8kHz采样率、低时钟极性和主时钟输出;最后启用发送缓冲区空中断(TXE)并使能I2S外设。该配置适用于简单音频发送场景,通过中断驱动方式实现数据传输。

4.3.2 中断服务函数

SPI3_IRQHandler()SPI3外设的中断处理函数,用于处理I2S发送缓冲区空(TXE)事件,函数内容如下:

void SPI3_IRQHandler(void)
{if (SPI_I2S_GetITStatus(SPI3, SPI_I2S_IT_TXE) == SET){/* Send a data from I2S3 */SPI_I2S_SendData(SPI3, I2S3_Buffer_Tx[TxIdx++]);}if (TxIdx == 32){SPI_I2S_ITConfig(SPI3, SPI_I2S_IT_TXE, DISABLE);}
}

当检测到TXE标志置位时,函数从预设的32元素数据缓冲区I2S3_Buffer_Tx中读取一个16位数据发送到I2S接口,并递增索引TxIdx;当TxIdx达到32时,表示所有数据发送完毕,函数禁用TXE中断以停止传输。该函数实现了基于中断的单次数据块发送,适用于小规模固定数据的传输场景。

4.3.3 主程序

以下为该例程的主程序,用于测试I2S接口的中断驱动数据发送功能:

int main(void)
{
    RCC_ClocksTypeDef clocks;delay_init();UART_Configuration(115200);RCC_GetClocksFreq(&clocks);printf("\n");printf("SYSCLK: %3.1fMhz, HCLK: %3.1fMhz, PCLK1: %3.1fMhz, PCLK2: %3.1fMhz, ADCCLK: %3.1fMhz\n",(float)clocks.SYSCLK_Frequency / 1000000, (float)clocks.HCLK_Frequency / 1000000,(float)clocks.PCLK1_Frequency / 1000000, (float)clocks.PCLK2_Frequency / 1000000, (float)clocks.ADCCLK_Frequency / 1000000);printf("IIS Int Test.\n");IIS_Configuration();    while (1);
}

程序先初始化延时函数和UART1串口,获取并打印系统各时钟频率,然后初始化I2S接口(配置GPIO、中断及I2S参数),最后进入无限循环,数据发送由I2S发送缓冲区空中断驱动,主程序不参与具体传输逻辑。

4.4.4 下载验证

程序下载运行后,首先打印了系统各时钟的频率和示例名称,I2S触发中断之后开始发送数据,数据缓冲区有数据之后便不再触发:

逻辑分析仪解析数据如下:

同样的,首帧和尾帧的数据实际也已经可以看到有数据脉冲信号,未解析属于硬件初始化特性(FIFO填充)或解析器同步延迟原因,不影响实际音频功能。

5 总结

W55MH32I2S接口为数字音频应用提供了强大而灵活的解决方案。通过与SPI模块共享硬件资源,它既实现了专用音频接口的高性能,又保持了设计的经济性。支持多种音频标准和数据格式使其能够与绝大多数音频编解码器无缝协作,满足从消费电子到专业音频设备的各种需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87052.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

产品-Figma(英文版),图像的布尔类型图例说明

文章目录 Union SelectionSubtract SelectionIntersect SelectionExclude SelectionFlatten Selection Union Selection 把多个形状合并成一个新的完整形状&#xff0c;保留所有外部轮廓&#xff0c;内部不被切割。由于红色的长方形在外面的一层&#xff0c;所以切割后&#x…

Windows CMD命令分类大全

⚙️ ‌一、系统与磁盘管理‌ ‌系统信息‌ systeminfo&#xff1a;查看详细硬件及系统配置&#xff08;版本/内存/补丁&#xff09;211 winver&#xff1a;快速检查Windows版本11 msinfo32&#xff1a;图形化系统信息面板811‌磁盘工具‌ chkdsk /f&#xff1a;修复磁盘错误&…

【Dify系列】【Dify1.4.2 升级到Dify1.5.0】

1. 升级前准备工作 1.1 数据备份&#xff1a; 进入原安装包 docker 目录&#xff0c;备份“volumes”文件夹&#xff0c;此文件夹包含了 Dify 数据库数据&#xff1a; rootjoe:/usr/local/dify/docker/volumes# pwd /usr/local/dify/docker/volumesrootjoe:/usr/local/dify/…

DeepSeek网页版随机点名器

用DeepSeek帮我们生成了一个基于html5的随机点名器&#xff0c;效果非常棒&#xff0c;如果需要加入名字&#xff0c;请在代码中按照对应的格式添加即可。 提示词prompt 帮我生成一个随机点名的HTML5页面 生成真实一点的名字数据 点击随机按钮开始随机选择 要有闪动的效果 &…

前后端分离实战2----后端

戳我抵达前端 项目描述&#xff1a;用Vscode创建Spring Bootmybatis项目&#xff0c;用maven进行管理。创建一个User表&#xff0c;对其内容进行表的基本操作&#xff08;增删改查&#xff09;&#xff0c;显示在前端。 项目地址&#xff1a;戳我一键下载项目 运行效果如下&…

深入 ARM-Linux 的系统调用世界

1、引言 本篇文章以 ARM 架构为例&#xff0c;进行讲解。需要读者有一定的 ARM 架构基础 在操作系统的世界中&#xff0c;系统调用&#xff08;System Call&#xff09;是用户空间与内核空间沟通的桥梁。用户态程序如 ls、cp 或你的 C 程序&#xff0c;无权直接操作硬件、访问文…

LabVIEW键盘鼠标监测控制

通过Input Device Control VIs&#xff0c;实现对键盘和鼠标活动的监测。通过AcquireInput Data VI 在循环中持续获取输入数据&#xff0c;InitializeKeyboard与InitializeMouse VIs 先获取设备ID 引用&#xff0c;用于循环内监测操作&#xff1b;运行时可输出按键信息&#xf…

Linux 系统管理:自动化运维与容器化部署

在现代 IT 基础设施中&#xff0c;自动化运维和容器化部署是提高系统管理效率和可维护性的关键。Linux 系统因其稳定性和灵活性而被广泛应用于服务器和数据中心。本文将深入探讨 Linux 系统管理中的自动化运维和容器化部署技术&#xff0c;帮助系统管理员实现高效运维和快速部署…

直播 APP 开发需要多少成本

直播行业的火爆催生了大量直播 APP 开发需求&#xff0c;而开发成本是开发者最关注的问题之一。其成本构成复杂&#xff0c;受功能需求、开发方式、技术难度等多种因素影响。​ 基础功能开发是成本的重要组成部分。用户注册登录、直播间创建与管理、视频播放、聊天互动等功能开…

Reactor操作符的共享与复用

在 Reactor 中&#xff0c;transform 和 transformDeferred 是两个用于代码复用和操作符链封装的高级操作符。它们允许你将一组操作符封装成一个函数&#xff0c;并在适当的时候应用到响应式流中。以下是它们的详细总结&#xff1a; 1. transform 操作符 作用&#xff1a;tran…

C#中的Converter详解

Converter是C#中一个非常有用的概念&#xff0c;主要用于类型转换。它通常以委托或接口的形式出现&#xff0c;允许开发者定义如何将一种类型转换为另一种类型。下面我将详细介绍Converter的概念、使用场景&#xff0c;并以布尔型转换为例展示具体应用。 Converter的基本概念 …

LabVIEW荧光微管图像模拟

利用LabVIEW平台&#xff0c;集成 PI 压电平台、Nikon 荧光显微镜及Andor sCMOS 相机等硬件&#xff0c;构建荧光微管滑行实验图像序列模拟系统。通过程序化模拟微管运动轨迹、荧光标记分布及显微成像过程&#xff0c;为生物医学领域微管跟踪算法测试、运动特性分析提供标准化仿…

CentOS下Nginx服务器搭建全攻略

Nginx 安装与配置完整指南 一、安装 Nginx 1.1 添加 Nginx 官方仓库 在 CentOS 系统中&#xff0c;默认仓库的 Nginx 版本可能较旧&#xff08;通常为 1.12 或更早版本&#xff09;&#xff0c;建议添加官方仓库来安装最新稳定版本&#xff08;目前为 1.25.x&#xff09;&am…

网络拓扑图绘制全流程:从架构解析到工具实战

在数据呈现与系统管理中&#xff0c;清晰展示设备间的逻辑关系至关重要。网络拓扑图正是这样一种有效的可视化工具。它通过节点设备和连接线路&#xff0c;直观呈现网络结构或项目流程中各元素的布局与交互关系&#xff0c;帮助理解系统运作、诊断问题并确保项目顺利进行。 1. …

Git 简介安装教程

&#x1f4e2;欢迎点赞&#x1f44d;收藏⭐留言&#x1f4dd;如有错误敬请指正&#xff01; 目录 一、Git 的安装1.1 Git 的下载1.2 Git 的安装1.2.1 使用许可声明1.2.2 选择安装目录1.2.3 选择安装组件1.2.4 选择开始菜单文件夹1.2.5 选择 Git 默认编辑器1.2.6 决定初始化新项…

鸿蒙NEXT-鸿蒙三层架构搭建,嵌入HMRouter,实现便捷跳转,新手攻略。(2/3)

在上一小节我们已经完成了关于三层架构的搭建&#xff0c;接下来我们来实现在三层架构中的导入依赖&#xff0c;将他们相互联系起来。 第一步&#xff1a;在features产品定制层中&#xff0c;对其中所有的动态共享包导入依赖&#xff0c;示例features>my>oh-package.jso…

【每天一个知识点】语料投毒(Corpus Poisoning)

“语料投毒”&#xff08;Corpus Poisoning&#xff09; 是指攻击者通过向大型语言模型&#xff08;如 ChatGPT&#xff09;使用的外部知识库中注入恶意或误导性文档&#xff0c;从而干扰模型的检索与回答过程&#xff0c;导致其输出错误、虚假或有害内容。 &#x1f50d; 举个…

疏通经脉: Bridge 联通逻辑层和渲染层

本节概述 经过前面两节的开发&#xff0c;我们已经完成了小程序逻辑线程和 UI 线程的启动引擎准备&#xff0c;这节开始&#xff0c;我们将完善 native bridge 层的搭建&#xff0c;构建起逻辑线程和UI线程之间的桥梁。 开始之前我们先来回顾一下逻辑引擎小节相关的流程图: 一…

【攻防篇】解决:阿里云docker 容器中自动启动xmrig挖矿

解决&#xff1a;阿里云服务器docker容器被植入挖矿程序 **1. 紧急处理&#xff1a;停止挖矿进程****&#xff08;1&#xff09;查找并终止 xmrig 进程****&#xff08;2&#xff09;删除恶意文件** **2. 清理被感染的容器****&#xff08;1&#xff09;停止并删除容器****&…

对称非对称加密,https和http,https通讯原理,Charles抓包原理

文章目录 对称加密的非对称加密http和https原理TCP三次握手四次挥手https通讯流程&#xff1a;Charles抓包原理 对称加密的非对称加密 对称加密&#xff1a;发送方的接收方式使用同一个秘钥进行加密和解密&#xff0c;发送方将需要发送的数据&#xff0c;选择某种加密算法&…