第三十五章 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_I2SCFGR的I2SMOD位置為'1'即可使能I2S功能,將SPI模塊轉換為I2S音頻接口。
I2S接口與SPI接口使用大致相同的引腳、標志和中斷,但專為音頻數據傳輸優化。它采用獨立的導線傳輸時鐘與數據信號,通過將數據和時鐘信號分離,避免了因時差誘發的失真,為用戶節省了購買抵抗音頻抖動的專業設備的費用。I2S已成為數字音頻領域的事實標準接口,廣泛應用于各種消費電子和專業音頻設備中。
1.2 功能特點
W55MH32的I2S接口有以下特點:
- 單工通信(僅發送或接收)
- 主或者從操作
- 8位線性可編程預分頻器,獲得精確的音頻采樣頻率(8KHz到96kHz)
- 數據格式可以是16位,24位或者32位
- 音頻信道固定數據包幀為16位(16位數據幀)或32位(16、24或32位數據幀)
- 可編程的時鐘極性(穩定態)
- 從發送模式下的下溢標志位和主/從接收模式下的溢出標志位
- 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_I2SPR的MCKOE位為'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_CR2的TXDMAEN/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次 | 硬件補低8位0 |
32位→32位幀 | 2次 | 完整32位處理 |
聲道管理
- 左聲道數據總是先傳輸
- 通過CHSIDE標志識別當前聲道
- 從模式需提前準備好第一個數據
發送流程
- 配置DMA:內存→SPI_DR,設置數據寬度
- 啟動傳輸:TXE=1時自動觸發
- 聲道切換:根據CHSIDE處理左右聲道
- 完成處理:等待TXE=1及BSY=0后關閉
接收流程
- 配置DMA:SPI_DR→內存,設置數據寬度
- 啟動傳輸:RXNE=1時自動觸發
- 數據解析:根據標準處理數據對齊
- 關閉時序:按數據格式選擇正確時序
2 應用場景
W55MH32的I2S接口憑借其高質量數字音頻傳輸能力,在眾多領域得到廣泛應用:
2.1 消費類音頻設備
便攜式音樂播放器:連接音頻DAC實現高質量音樂播放,支持從MP3解碼器到功率放大器的數字音頻傳輸。
智能音箱:用于主控芯片與數字音頻處理器之間的連接,實現語音助手和音樂播放功能。
數字電視和機頂盒:傳輸數字音頻信號到音頻處理芯片或直接驅動數字功放。
2.2 專業音頻設備
錄音設備:連接高性能ADC實現多通道音頻采集,支持24位高分辨率錄音。
音頻混音器:在數字域混合多個音頻源,保持信號完整性。
效果處理器:傳輸音頻數據到DSP芯片進行實時效果處理。
2.3 通信設備
VoIP電話:實現雙向語音通信,同時支持回聲消除等高級功能。
會議系統:連接數字麥克風陣列和音頻處理單元。
無線耳機:在藍牙模塊與編解碼器之間傳輸音頻數據。
2.4 汽車電子
車載娛樂系統:連接多個音頻源和功放,支持環繞聲處理。
主動降噪系統:實時采集車內噪聲并生成反相聲波。
語音識別系統:傳輸高清晰度語音數據到語音處理單元。
2.5 嵌入式系統
工業控制人機界面:實現語音提示和報警功能。
醫療監護設備:傳輸心音、呼吸音等生物音頻信號。
智能家居:用于門鈴、對講系統等需要音頻功能的設備。
3 注意事項
- 時鐘同步:從模式需確保在外部時鐘有效前完成初始化。
- 數據對齊:注意不同標準(Philips/MSB/LSB)的數據對齊差異。
- 電源管理:模擬部分供電需加強濾波處理。
- PCB布局:時鐘信號線應盡量短并考慮端接匹配。
- 關閉順序:嚴格按照規范流程關閉接口,避免數據損壞。
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無法正常工作。),然后配置GPIOA15、GPIOB3、GPIOB5和GPIOC7為復用推挽輸出模式以連接I2S的SCK、SD、WS和MCLK信號,接著將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(對應I2S3的TX 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以暫停傳輸,最后將標志位Flag置1以通知主程序數據已傳輸完畢,整體實現了對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_LEN的8位數據源數組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_IRQHandler是W55MH32中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完成預設的32個16位數據傳輸后觸發。函數首先檢查傳輸完成中斷狀態,若中斷已觸發則清除中斷掛起位和傳輸完成標志,避免重復響應;接著禁用DMA2通道2,停止數據傳輸;最后將全局標志位Flag置1,通知主程序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開始將預設的32個16位音頻數據循環傳輸到I2S接口,主循環持續檢測DMA傳輸完成標志位Flag,當Flag被中斷處理函數置1時,打印傳輸成功信息并重置標志,不過因中斷處理函數中禁用了DMA通道,實際數據僅能傳輸一次,此代碼常用于音頻設備初始化測試。
4.2.4?下載驗證
程序下載運行后,首先打印了系統各時鐘的頻率和示例名稱,然后I2S數據發送成功后打印數據發送成功的信息:
通過邏輯分析儀就可以解析出發送的數據:
首幀和尾幀的數據實際已經可以看到有數據脈沖信號,未解析屬于硬件初始化特性(FIFO填充)或解析器同步延遲原因,不影響實際音頻功能。
4.3 IIS_Int例程
IIS_Int例程通過I2S接口和中斷控制器實現音頻數據的中斷驅動傳輸。其他程序設計如下:
4.3.1?I2S初始化
IIS_Configuration()函數用于初始化W55MH32的I2S接口(復用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/C和SPI3的時鐘,配置相關引腳為復用推挽輸出(包括數據輸出、字選擇、串行時鐘和主時鐘引腳);接著配置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 總結
W55MH32的I2S接口為數字音頻應用提供了強大而靈活的解決方案。通過與SPI模塊共享硬件資源,它既實現了專用音頻接口的高性能,又保持了設計的經濟性。支持多種音頻標準和數據格式使其能夠與絕大多數音頻編解碼器無縫協作,滿足從消費電子到專業音頻設備的各種需求。