音響數(shù)據(jù)的采集、處理和傳輸是多媒體技術的重要組成部分。眾多的數(shù)字音頻系統(tǒng)已經(jīng)進入消費市場,例如數(shù)字音頻錄音帶、數(shù)字聲音處理器。對于設備和生產廠家來說,標準化的信息傳輸結構可以提高系統(tǒng)的適應性。
I2S(Inter—IC Sound)總線是飛利浦公司為數(shù)字音頻設備之間的音頻數(shù)據(jù)傳輸而制定的一種總線標準,該總線專責于音頻設備之間的數(shù)據(jù)傳輸,廣泛應用于各種多媒體系統(tǒng)。它采用了沿獨立的導線傳輸時鐘與數(shù)據(jù)信號的設計,通過將數(shù)據(jù)和時鐘信號分離,避免了因時差誘發(fā)的失真,為用戶節(jié)省了購買抵抗音頻抖動的專業(yè)設備的費用。在飛利浦公司的 I2S 標準中,既規(guī)定了硬件接口規(guī)范,也規(guī)定了數(shù)字音頻數(shù)據(jù)的格式。
I2S 總線接口有 3 個主要信號,但只能實現(xiàn)數(shù)據(jù)半雙工傳輸,后來為實現(xiàn)全雙工傳輸有些設備增加了擴展數(shù)據(jù)引腳。
MM32F3270 系列控制器支持 I2S 總線接口,本章節(jié)在接下來會對MM32F3270 I2S進行介紹,并使用MM32F3270和CS4344芯片進行I2S通信來演示播放MP3。
01、I2S 主要特征
1)半雙工通信(僅發(fā)射機或接收機)
2)主操作或從操作
3)8 位可編程線性預分頻器,以達到精確的音頻采樣頻率( 8KHz 到 192KHz)
4)數(shù)據(jù)格式可以是 16 位、 24 位或 32 位
5)數(shù)據(jù)包幀固定為 16 位(16 位數(shù)據(jù)幀)或 32 位(16 位、 24 位、 32 位數(shù)據(jù)幀)
6)可編程時鐘極性(穩(wěn)定狀態(tài))
7)發(fā)射模式下的下溢標志(僅從機),接收模式下的上溢標志(主和從機)和接收/發(fā)射模式下的幀錯誤標志(僅從機)
8)用于傳輸和接收的 32 位寄存器為兩個聲道分時復用
9)支持 I2S 協(xié)議:
– 飛利浦標準
– MSB 對齊標準(左對齊)
– LSB 對齊標準(右對齊)
– PCM 標準(在 16 位信道幀上具有短幀和長幀同步或擴展到 32 位信道幀的 16 位數(shù)據(jù)幀)
10)數(shù)據(jù)方向始終是 MSB 優(yōu)先
11)DMA 傳輸能力( 32 位寬)
12)可配置輸出 MCLK 來驅動外部音頻組件,比率固定在 256× FS(其中 FS 為音頻采樣頻率)
02、I2S 總線接口
I2S 與 SPI 共用三個公共管腳:
1)SD:串行數(shù)據(jù)(映射在 MOSI 管腳上),用于發(fā)送或接收兩次多路數(shù)據(jù)通道(僅在半雙工模式下)。
2)WS:聲道選擇(映射在 NSS 引腳上),是 master 中的數(shù)據(jù)控制信號輸出模式和從模式輸入。
3)CK:串行時鐘(映射在 SCK 引腳上),是主模式下的串行時鐘輸出以及從機模式下的串行時鐘輸入。
4)當某些外部設備需要主時鐘輸入時,可以使用一個附加的管腳輸出時鐘到音頻設備。
5)MCK:驅動時鐘(映射在 MISO 引腳上),用于驅動外部音頻組件,僅主模式時使用。
03、I2S 數(shù)據(jù)格式
三線總線處理音頻數(shù)據(jù)的線路必須經(jīng)過分時復用兩個聲道:右聲道和左聲道。但是只有一個 32 位寄存器用于傳輸或接收。所以由軟件依次配置寄存器 TXREG 為每個聲道側的值,或依次讀取寄存器 RXREG的數(shù)據(jù)。總是先發(fā)送左聲道,然后發(fā)送右聲道( CHSIDE 對 PCM 協(xié)議沒有意義)。
數(shù)據(jù)可采用以下格式發(fā)送:
1) 16 位數(shù)據(jù)打包在 16 位幀中
2) 16 位數(shù)據(jù)打包在 32 位幀中
3) 24 位數(shù)據(jù)打包在 32 位幀中
4) 32 位數(shù)據(jù)打包在 32 位幀中
當使用 32 位幀上發(fā)送 16 位數(shù)據(jù)時,前 16 位(MSB)是有效的位,16 位 LSB 制為 0,無需任何軟件操作,通過硬件實現(xiàn)。其他格式相似。
04、通信標準
對于所有數(shù)據(jù)格式和通信標準,總是先發(fā)送最高位( MSB 優(yōu)先)。I2S 接口支持四種音頻標準,可通過配置 SPI_I2S_I2SCFGR 寄存器的 I2SSTD[1:0]和 PCMSYNC 進行切換。
飛利浦標準
對于本標準, WS 信號用于指示正在傳輸?shù)穆暤馈0l(fā)射器在 CK 的下降沿鎖存數(shù)據(jù),接收器并在 CK的上升讀取數(shù)據(jù)。WS 信號也在 CK 的下降沿被鎖定。對于這種標準 I2S 格式的信號,無論有多少位有效數(shù)據(jù),數(shù)據(jù)的最高位總是出現(xiàn)在 WS 變化(也就是一幀開始)后的第 2 個 CK 脈沖處。
飛利浦標準示意圖
MSB 對齊標準
對于這個標準,第一個數(shù)據(jù)在 WS 變化后的第一個沿有效。
MSB 對齊標準示意圖
LSB 對齊標準
LSB 對齊標準示意圖
PCM 標準
對于 PCM 標準,不需要使用聲道信息。PCM 有兩個模式:短幀模式和長幀模式,通過配置SPI_I2S_I2SCFGR 寄存器的 PCMSYNC 位進行切換。在 PCM 模式下,輸出信號(WS, SD)在 CK 信號的上升沿進行采樣。輸入信號(WS, SD)在 CK 下降沿被捕獲。注意在主模式下, CK 和 WS 被配置為輸出。
PCM 標準示意圖
05、基于MM32F3270的音頻播放實驗
CS4344芯片是實現(xiàn)本次實驗功能的重要器件之一。CS4344是一種立體聲音頻數(shù)模轉換器 (DAC) ,可使用單個 +3.3 V 或 +5 V 電源,僅需要最小的支持電路。該系列線性模擬低通濾波器和自動速度模式檢測,當自動選擇 2 kHz 和 200 kHz 之間的采樣率,使用采樣率和主時鐘速率方法。
本實驗的基本原理是MM32F3270 讀取SD卡中的MP3文件,并對其解碼得到PCM信號,通過I2S接口將PCM信號傳輸給CS4344,由CS4344進行DA轉換輸出模擬信號,再經(jīng)過TS4871(音頻功率放大器)連接到耳機接口,可以接入耳機等音頻播放裝置。
硬件設計
如圖是MB-039的I2S部分,完整原理圖可以通過官網(wǎng)下載。
各個信號引腳對應如下:
程序設計
根據(jù)接口電路配置GPIO初始化
static void I2S3_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // I2S MCLK, SD, CK and WS pins configuration RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_6); //I2S WS GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_6); //I2S CK I2S_SCK GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_6); //I2S SD I2S_DATAOUT MOSI GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_5); //I2S MCK I2S_MCLK 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_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOC, GPIO_InitStructure); // config as the control I/O for power on or enter standby GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, GPIO_InitStructure); }
I2S配置初始化
static void I2S_Mode_Config(SPI_I2S_STANDARD_TypeDef usStandard, SPI_I2S_DATAFORMAT_TypeDef usWordLen, SPI_I2S_AUDIO_FREQ_TypeDef usAudioFreq, SPI_I2S_TRANS_MODE_TypeDef usMode) { I2S_InitTypeDef I2S_InitStructure; if ((usMode == I2S_Mode_SlaveTx) (usMode == I2S_Mode_SlaveRx)) { return; } RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE); SPI_DeInit(SPI3); RCC_APB1PeriphClockCmd(RCC_APB1ENR_SPI3, ENABLE); if (usMode == I2S_Mode_MasterTx) { I2S_InitStructure.I2S_Mode = I2S_Mode_MasterTx; I2S_InitStructure.I2S_Standard = usStandard; I2S_InitStructure.I2S_DataFormat = usWordLen; I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; I2S_InitStructure.I2S_AudioFreq = usAudioFreq; I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; I2S_Init(SPI3, I2S_InitStructure); } else if (usMode == I2S_Mode_MasterRx) { I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx; I2S_InitStructure.I2S_Standard = usStandard; I2S_InitStructure.I2S_DataFormat = usWordLen; I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Enable; I2S_InitStructure.I2S_AudioFreq = usAudioFreq; I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low; I2S_Init(SPI3, I2S_InitStructure); } SPI_DMACmd(SPI3, ENABLE); I2S_Cmd(SPI3, ENABLE); }
(1)I2S_Mode:I2S 模式選擇,可選主機發(fā)送、主機接收、從機發(fā)送以及從機接收模式,它設定SPI_I2S_GCTL寄存器MODE位的值。一般設置 MM32 控制器為主機模式,當播放聲音時選擇發(fā)送模式,當錄制聲音時選擇接收模式。
(2) I2S_Standard:通信標準格式選擇,可選 I2S Philips 標準、左對齊標準、右對齊標準、 PCM 短幀標準或 PCM 長幀標準,它設定SPI_I2S_I2SCFGR 寄存器 I2SSTD位和 PCMSYNC位的值。一般設置為 I2S Philips 標準即可。
(3)I2S_DataFormat:數(shù)據(jù)格式選擇,設定有效數(shù)據(jù)長度和幀長度,可選標準 16bit 格式、擴展16bit(32bit 幀長度) 格式、 24bit 格式和 32bit 格式,它設定 SPI_I2SCFGR 寄存器 DATLEN 位和CHLEN 位的值。對應 16bit 數(shù)據(jù)長度可選 16bit 或 32bit 幀長度,其他都是 32bit 幀長度。
(4)I2S_MCLKOutput:主時鐘輸出使能控制,可選使能輸出或禁止輸出,它設定 SPI_I2SPR 寄存器 MCKOE 位的值。為提高系統(tǒng)性能一般使能主時鐘輸出。
(5)I2S_AudioFreq:采樣頻率設置,標準庫提供采樣采樣頻率選擇,分別為 4KHz、8kHz、 11kHz、12KHz、16kHz、22kHz、32kHz、44kHz、48kHz、96kHz、192kHz 以及默認 2Hz,它設定 SPI_I2S_SPBRG 寄存器的值。
(6)I2S_CPOL:空閑狀態(tài)的 CK 線電平,可選高電平或低電平,它設定 SPI_I2S_CCTL 寄存器 CPOL位的值。一般設置為低電平即可。
在I2S_StartPlay()函數(shù)中調用I2S_Mode_Config()函數(shù),
void I2S_StartPlay(SPI_I2S_STANDARD_TypeDef usStandard, SPI_I2S_DATAFORMAT_TypeDef usWordLen, SPI_I2S_AUDIO_FREQ_TypeDef usAudioFreq) { // config I2S interface as standard, bit length, frequence ,the Master Tx mode I2S_Mode_Config(usStandard, usWordLen, usAudioFreq, I2S_Mode_MasterTx); SPI3->GCTL |= 0xF; }
在PlayMP3FileDemo()函數(shù)中調用I2S_StartPlay()函數(shù),并配置傳輸模式為主機發(fā)送I2S_Mode_MasterTx,選擇Phillips標準,16位數(shù)據(jù)長度,采樣頻率配置為44KHz。
I2S_StartPlay(I2S_Standard_Phillips, I2S_DataFormat_16b, I2S_AudioFreq_44k);
PlayMP3File()函數(shù)是 MP3 播放器的實現(xiàn)函數(shù),定義如下:
void PlayMP3File(void) { DIR dirs; FILINFO finfo; FRESULT res; static UINT br; DELAY_Init(); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOE, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBENR_SDIO, ENABLE); CONSOLE_Init(115200); SDIO_ConfigInit(); printf("SDCARD TESTrn"); while(SD_Init()) { printf("SD Card Error!rn"); } MX_FATFS_Init(); f_mount( SDFatFS, (TCHAR const*)SDPath, 0); u8 buff[2] = {0x01, 0x02}; I2S_TX_DMA_Init( buff[0], 1); DMA_Cmd(DMA2_Channel2, ENABLE); // while(1){ if (f_opendir( dirs, "") == FR_OK) { //success to open directory while (f_readdir( dirs, finfo) == FR_OK) { //if there is file in this directory if (finfo.fattrib AM_ARC) { if(!finfo.fname[0]) break; printf("rn Now Playing:["); printf(finfo.fname); printf("]rn"); res = f_open( fsrc, finfo.fname, FA_OPEN_EXISTING | FA_READ); SET_BIT(SPI3->GCR, SPI_GCR_SPIEN); MODIFY_REG(DMA2_Channel2->CCR, DMA_CCR_EN, ENABLECCR, DMA_CCR_EN, DISABLE << DMA_CCR_EN_Pos); f_close( fsrc); bytesLeft = 0; } } } while(1); // } }
MP3文件是經(jīng)過壓縮算法壓縮而存在的,為得到 PCM 信號,需要對 MP3 文件進行解碼。本實驗使用Helix MP3解碼器,Helix MP3 解碼器的源代碼是開源代碼,受制于源代碼隨附文件中描述的許可協(xié)議。該算法支持浮點和定點實現(xiàn),可移植到任意32位定點處理器上運行,提供對 MPEG-1、 MPEG-2 以及 MPEG-2.5 標準的 Layer3 解碼,以及支持可變位速率、恒定位速率,以及立體聲和單聲道音頻格式。關于Helix MP3解碼器的移植,在本文中不做重點講述,更多信息可訪問網(wǎng)站:
https://datatype.helixcommunity.org/Mp3dec
f_open 函數(shù)用于打開文件,如果文件打開失敗則直接退出播放。
MP3InitDecoder 函數(shù)用于初始化Helix 解碼器,分配解碼器必須內存空間,如果初始化解碼器失敗直接退出播放。
f_read 函數(shù)從 SD 卡讀取 MP3 文件數(shù)據(jù),存放在 readBuf緩沖區(qū)中, br變量保存實際讀取到的數(shù)據(jù)的字節(jié)數(shù)。如果讀取數(shù)據(jù)失敗則運行 MP3FreeDecoder 函數(shù)關閉解碼器后退出播放器。
MP3Decode 函數(shù)開始對源數(shù)據(jù)緩沖區(qū)中幀數(shù)據(jù)進行解碼,通過函數(shù)返回值可判斷得到解碼狀態(tài),如果發(fā)生解碼錯誤則執(zhí)行對應的代碼。
讀取到文件末尾就退出循環(huán), 此時MP3文件已經(jīng)完整播放。
實驗演示
SD卡中存儲有MP3文件,并將SD卡、耳機設備接入MB-039開發(fā)板,運行程序,就可以聽到音樂播放。
本次實驗的例程可以通過MindMotion的官網(wǎng)下載MM32F3270 lib_Samples:
工程路徑如下:
~MM32F327x_SamplesDemo_appPlayWave_DemoSPI_I2S_SDIO_FatFsMP3_CS4344_Demo
可以看到詳細的樣例與功能操作。
下章的題目為《使用MM32F3270 的SDIO 驅動SD卡》講解通過SDIO外接MicroSD卡的實現(xiàn)。
來源:靈動MM32MCU
審核編輯:湯梓紅
-
控制器
+關注
關注
112文章
16332瀏覽量
177812 -
接口
+關注
關注
33文章
8575瀏覽量
151019 -
總線
+關注
關注
10文章
2878瀏覽量
88052 -
I2S總線
+關注
關注
0文章
8瀏覽量
8750
發(fā)布評論請先 登錄
相關推薦
評論