摘要:一簡介也叫,即總線又稱集成電路內(nèi)置音頻總線,是飛利浦公司為數(shù)字音頻設(shè)備之間的音頻數(shù)據(jù)傳輸而制定的一種總線標(biāo)準(zhǔn),該總線專責(zé)于音頻設(shè)備之間的數(shù)據(jù)傳輸,廣泛應(yīng)用于各種多媒體系統(tǒng)。位,這兩個位用于選擇標(biāo)準(zhǔn),設(shè)置為,選擇飛利浦標(biāo)準(zhǔn)。
I2S(也叫IIS,即:Inter IC Sound)總線, 又稱集成電路內(nèi)置音頻總線,是飛利浦公司為數(shù)字音頻設(shè)備之間的音頻數(shù)據(jù)傳輸而制定的一種總線標(biāo)準(zhǔn),該總線專責(zé)于音頻設(shè)備之間的數(shù)據(jù)傳輸,廣泛應(yīng)用于各種多媒體系統(tǒng)。它采用了沿獨立的導(dǎo)線傳輸時鐘與數(shù)據(jù)信號的設(shè)計,通過將數(shù)據(jù)和時鐘信號分離,避免了因時差誘發(fā)的失真,為用戶節(jié)省了購買抵抗音頻抖動的專業(yè)設(shè)備的費用。
特點
●支持全雙工/半雙工通信
●支持主/從模式設(shè)置
●8位可編程線性預(yù)分頻器,可實現(xiàn)精確的音頻采樣頻率(8~192Khz)
●支持16位/24位/32位數(shù)據(jù)格式
●數(shù)據(jù)包幀固定為16位(僅16位數(shù)據(jù)幀)或32位(可容納16/24/32位數(shù)據(jù)幀)
●可編程時鐘極性
●支持MSB對齊(左對齊)、LSB對齊(右對齊)、飛利浦標(biāo)準(zhǔn)和PCM標(biāo)準(zhǔn)等I2S標(biāo)準(zhǔn)
●支持DMA數(shù)據(jù)傳輸(16位寬)
●數(shù)據(jù)方向固定位MSB在前
●支持主時鐘輸出(固定為256*fs,fs即音頻采樣率)
I2S框圖
STM32F4的I2S是與SPI部分共用的,通過設(shè)置SPI_I2SCFGR寄存器的I2SMOD位即可開啟I2S功能,I2S接口使用了幾乎與SPI相同的引腳、標(biāo)志和中斷。
信號
1,SD:串行數(shù)據(jù)(映射到 MOSI 引腳),用于發(fā)送或接收兩個時分復(fù)用的數(shù)據(jù)通道上的數(shù)據(jù)(僅半雙工模式)。
2,WS:字選擇(映射到NSS引腳),即左右時鐘,用于切換左右聲道的數(shù)據(jù)。WS頻率等于音頻信號采樣率(fs)。
3,CK:串行時鐘(映射到SCK引腳),即位時鐘,是主模式下的串行時鐘輸出以及從模式下的串行時鐘輸入。CK頻率=WS頻率(fs)216(16位寬),如果是32位寬,則是:CK頻率=WS頻率(fs)232(32位寬)。
4,I2S2ext_SD和I2S3ext_SD:用于控制I2S全雙工模式的附加串行數(shù)據(jù)引腳(映射到MISO引腳),這兩個引腳僅用于全雙工模式。
5,MCK:即主時鐘輸出,當(dāng)I2S配置為主模式(且SPI_I2SPR寄存器的MCKOE位置1)時,使用此時鐘,該時鐘頻率為 256×fs,fs:音頻信號采樣頻率。
STM32F4為支持I2S全雙工模式,除了I2S2和I2S3,還可以使用兩個額外的I2S,它們稱為擴(kuò)展I2S(I2S2_ext、I2S3_ext),其框圖為:
擴(kuò)展I2S (I2Sx_ext)只能用于全雙工模式。I2Sx_ext始終在從模式下工作。I2Sx和I2Sx_ext 均可用于發(fā)送和接收。
STM32F4的I2S支持4種數(shù)據(jù)和幀格式組合,分別是:
1,將16位數(shù)據(jù)封裝在16位幀中;
2,將16位數(shù)據(jù)封裝在32位幀中;
3,將24位數(shù)據(jù)封裝在32位幀中;
4,將32位數(shù)據(jù)封裝在32位幀中;
將16位數(shù)據(jù)封裝在32位幀中時,前16位(MSB)為有效位,16位LSB被強(qiáng)制清零,無需任何軟件操作或DMA請求(只需一個讀/寫操作)。如果應(yīng)用程序選則DMA,則24位和32位數(shù)據(jù)幀需要對SPI_DR執(zhí)行兩次CPU讀取或?qū)懭氩僮?,或者需要兩次DMA操作。24位的數(shù)據(jù)幀,硬件會將8位非有效位擴(kuò)展到帶有0位的32位數(shù)據(jù)幀。
4種幀標(biāo)準(zhǔn):
1,飛利浦標(biāo)準(zhǔn);
2,MSB 對齊(左對齊)標(biāo)準(zhǔn);
3,LSB 對齊(右對齊)標(biāo)準(zhǔn);
4,PCM標(biāo)準(zhǔn);
I2S飛利浦標(biāo)準(zhǔn)幀24位數(shù)據(jù),32位幀格式
I2S飛利浦標(biāo)準(zhǔn),使用WS信號來指示當(dāng)前正在發(fā)送的數(shù)據(jù)所屬的通道。該信號從當(dāng)前通道數(shù)據(jù)的第一個位(MSB)之前的一個時鐘開始有效。發(fā)送方在時鐘信號(CK)的下降沿改變數(shù)據(jù),接收方在上升沿讀取數(shù)據(jù)。WS信號也在CK的下降沿變化。在24位模式下數(shù)據(jù)傳輸,需要對SPI_DR執(zhí)行兩次讀取或?qū)懭氩僮?。比如要發(fā)送0X8EAA33這個數(shù)據(jù),就要分兩次寫入SPI_DR,第一次寫入:0X8EAA,第二次寫入0X33xx(xx可以為任意數(shù)值),這樣就把0X8EAA33發(fā)送出去了。
注意:從SD卡讀取到的24位WAV數(shù)據(jù)流,是低字節(jié)在前,高字節(jié)在后的,比如,我們讀到一個聲道的數(shù)據(jù)(24bit),存儲在buf[3]里面,那么要通過SPI_DR發(fā)送這個24位數(shù)據(jù),過程如下:
SPI_DR=((u16)buf[2]<<8)+buf[1];
SPI_DR=(u16)buf[0]<<8;
這樣,第一次發(fā)送高16位數(shù)據(jù),第二次發(fā)送低8位數(shù)據(jù),完成一次24bit數(shù)據(jù)的發(fā)送。
上圖中的I2SxCLK,可以來自PLLI2S輸出(通過R系數(shù)分頻)或者來自外部時鐘(I2S_CKIN引腳),一般使用前者作為I2SxCLK輸入時鐘。
需要根據(jù)音頻采樣率(fs)來計算各個分頻器的值,常用的音頻采樣率有:22.05Khz、44.1Khz、48Khz、96Khz、196Khz等。
當(dāng)MCK輸出使能時,fs頻率計算公式如下:
fs=I2SxCLK/[256 * (2 * I2SDIV+ODD)]
其中:I2SxCLK=(HSE/pllm)* PLLI2SN/PLLI2SR。 HSE是8Mhz,而pllm在系統(tǒng)時鐘初始化就確定了,是8,這樣結(jié)合以上式,可得計算公式如下:
fs= (1000 * PLLI2SN/PLLI2SR )/[256 * (2 * I2SDIV+ODD)]
fs單位是:Khz。其中:PLLI2SN取值范圍:192~ 432;PLLI2SR取值范圍:2~ 7;I2SDIV取值范圍:2~255;ODD取值范圍:0/1。
根據(jù)以上約束條件,便可根據(jù)fs來設(shè)置各個系數(shù)的值了,不過很多時候,并不能取得和fs一模一樣的頻率,只能近似等于fs,比如44.1Khz采樣率,設(shè)置PLLI2SN=271,PLLI2SR=2,I2SDIV=6,ODD=0,得到fs=44.108073Khz,誤差為:0.0183%。晶振頻率決定了有時無法通過分頻得到我們所要的fs,所以,某些fs如果要實現(xiàn)0誤差,必須得選用外部時鐘才可以。
為了方便可以將常用的fs建立對應(yīng)的表格。
//表格式:采樣率/10,PLLI2SN,PLLI2SR,I2SDIV,ODDconst u16 I2S_PSC_TBL[][5]={ {800 ,256,5,12,1}, //8Khz采樣率 {1102,429,4,19,0}, //11.025Khz采樣率 {1600,213,2,13,0}, //16Khz采樣率 {2205,429,4, 9,1}, //22.05Khz采樣率 {3200,213,2, 6,1}, //32Khz采樣率 {4410,271,2, 6,0}, //44.1Khz采樣率 {4800,258,3, 3,1}, //48Khz采樣率 {8820,316,2, 3,1}, //88.2Khz采樣率 {9600,344,2, 3,1}, //96Khz采樣率 {17640,361,2,2,0}, //176.4Khz采樣率 {19200,393,2,2,0}, //192Khz采樣率};
1、SPI_I2S配置寄存器(SPI_I2SCFGR)
I2SMOD位,設(shè)置為1,選擇I2S模式,注意,必須在I2S/SPI禁止的時候,設(shè)置該位。
I2SE位,設(shè)置為1,使能I2S外設(shè),該位必須在I2SMOD位設(shè)置之后再設(shè)置。
I2SCFG[1:0]位, 這兩個位用于配置I2S模式,設(shè)置為10,選擇主模式(發(fā)送)。
I2SSTD[1:0]位,這兩個位用于選擇I2S標(biāo)準(zhǔn),設(shè)置為00,選擇飛利浦標(biāo)準(zhǔn)。
CKPOL位,用于設(shè)置空閑時時鐘電平,設(shè)置為0,空閑時時鐘低電平。
DATLEN[1:0]位,用于設(shè)置數(shù)據(jù)長度,00,表示16位數(shù)據(jù);01表示24位數(shù)據(jù)。
CHLEN位,用于設(shè)置通道長度,即幀長度,0,表示16位;1,表示32位。
2、SPI_I2S預(yù)分頻器寄存器(SPI_I2SSPR)
設(shè)置MCKOE為1,開啟MCK輸出,ODD和I2SDIV則根據(jù)不同的fs,查表進(jìn)行設(shè)置。
3、PLLI2S配置寄存器(RCC_PLLI2SCFGR)
該寄存器用于配置PLLI2SR和PLLI2SN兩個系數(shù),PLLI2SR的取值范圍是:2~ 7,PLLI2SN的取值范圍是:192~432。同樣,這兩個也是根據(jù)fs的值來設(shè)置的。
//播放某個WAV文件//fname:wav文件路徑.//返回值://KEY0_PRES:下一曲//KEY1_PRES:上一曲//其他:錯誤u8 wav_play_song(u8* fname){ u8 key; u8 t=0; u8 res; u32 fillnum; audiodev.file=(FIL*)mymalloc(SRAMIN,sizeof(FIL)); audiodev.i2sbuf1=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); audiodev.i2sbuf2=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); audiodev.tbuf=mymalloc(SRAMIN,WAV_I2S_TX_DMA_BUFSIZE); if(audiodev.file&&audiodev.i2sbuf1&&audiodev.i2sbuf2&&audiodev.tbuf) { res=wav_decode_init(fname,&wavctrl);//得到文件的信息 if(res==0)//解析文件成功 { if(wavctrl.bps==16) { WM8978_I2S_Cfg(2,0); //飛利浦標(biāo)準(zhǔn),16位數(shù)據(jù)長度 I2S2_Init(I2S_Standard_Phillips,I2S_Mode_MasterTx,I2S_CPOL_Low,I2S_DataFormat_16bextended); //飛利浦標(biāo)準(zhǔn),主機(jī)發(fā)送,時鐘低電平有效,16位擴(kuò)展幀長度 }else if(wavctrl.bps==24) { WM8978_I2S_Cfg(2,2); //飛利浦標(biāo)準(zhǔn),24位數(shù)據(jù)長度 I2S2_Init(I2S_Standard_Phillips,I2S_Mode_MasterTx,I2S_CPOL_Low,I2S_DataFormat_24b); //飛利浦標(biāo)準(zhǔn),主機(jī)發(fā)送,時鐘低電平有效,24位擴(kuò)展幀長度 } I2S2_SampleRate_Set(wavctrl.samplerate);//設(shè)置采樣率 I2S2_TX_DMA_Init(audiodev.i2sbuf1,audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE/2); //配置TX DMA i2s_tx_callback=wav_i2s_dma_tx_callback; //回調(diào)函數(shù)指wav_i2s_dma_callback audio_stop(); res=f_open(audiodev.file,(TCHAR*)fname,FA_READ); //打開文件 if(res==0) { f_lseek(audiodev.file, wavctrl.datastart); //跳過文件頭 fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps); fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps); audio_start(); while(res==0) { while(wavtransferend==0);//等待wav傳輸完成; wavtransferend=0; if(fillnum!=WAV_I2S_TX_DMA_BUFSIZE)//播放結(jié)束? { res=KEY0_PRES; break; } if(wavwitchbuf)fillnum=wav_buffill(audiodev.i2sbuf2,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf2 else fillnum=wav_buffill(audiodev.i2sbuf1,WAV_I2S_TX_DMA_BUFSIZE,wavctrl.bps);//填充buf1 while(1) { key=KEY_Scan(0); if(key==WKUP_PRES)//暫停 { if(audiodev.status&0X01)audiodev.status&=~(1<<0); else audiodev.status|=0X01; } if(key==KEY2_PRES||key==KEY0_PRES)//下一曲/上一曲 { res=key; break; } wav_get_curtime(audiodev.file,&wavctrl);//得到總時間和當(dāng)前播放的時間 audio_msg_show(wavctrl.totsec,wavctrl.cursec,wavctrl.bitrate); t++; if(t==20) { t=0; LED0=!LED0; } if((audiodev.status&0X01)==0)delay_ms(10); else break; } } audio_stop(); }else res=0XFF; }else res=0XFF; }else res=0XFF; myfree(SRAMIN,audiodev.tbuf); //釋放內(nèi)存 myfree(SRAMIN,audiodev.i2sbuf1);//釋放內(nèi)存 myfree(SRAMIN,audiodev.i2sbuf2);//釋放內(nèi)存 myfree(SRAMIN,audiodev.file); //釋放內(nèi)存 return res;}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/122389.html
摘要:總線掛載的外設(shè)有等。外設(shè)地址映射片上外設(shè)區(qū)分為三條總線,根據(jù)外設(shè)速度的不同,不同總線掛載著不同的外設(shè),掛載低速外設(shè),和掛載高速外設(shè)。 第二章 STM32資源介紹 2...
摘要:計算機(jī)組成原理是大學(xué)中的專業(yè)必修課,也是程序員需要掌握的專業(yè)知識。所以說計算機(jī)組成原理是非常重要的一門課程,本文總結(jié)了五十個組原中的重要概念,供大家學(xué)習(xí)。通道程序通道程序由通道指令組成,他完成某種外圍設(shè)備與主存?zhèn)魉托畔⒌牟僮鳌? 計算機(jī)組成原理是大學(xué)中的專業(yè)必修課,也是程序員需要掌握的專業(yè)...
摘要:產(chǎn)品概述是我司傾力打造的一款基于全志雙核處理器的高性能核心板,可廣泛應(yīng)用于智能家居工業(yè)顯示語控設(shè)備醫(yī)療電子等產(chǎn)品。 產(chǎn)品概述 ? ?R5是我司傾力打造的一款基于全志R528-S3A雙核處理器的高性能Linux核心板,可廣泛應(yīng)用于智能家居、工業(yè)顯示、語控設(shè)備、醫(yī)療電子等產(chǎn)品。 ? 核心板體積小...
摘要:為了能讓感興趣的開發(fā)者小伙伴第一時間體驗到,聯(lián)合社區(qū)趕在春節(jié)前發(fā)起開發(fā)套件試用征集活動,該套件是基于自研語音解決方案平臺打造而成。與此同時,我們也同樣提供高度定制化模塊化的整體架構(gòu),開發(fā)者亦可方便地選擇想要集成的模塊對整個操作系統(tǒng)重新組裝。 1月28日,Rokid為人機(jī)交互設(shè)備開發(fā)的開源人工智能操作系統(tǒng)——YodaOS正式上線,可用于智能音箱、智能家居、智能穿戴和車載等多種設(shè)備和場景。...
閱讀 2829·2021-10-13 09:48
閱讀 3801·2021-10-13 09:39
閱讀 3602·2021-09-22 16:04
閱讀 1837·2021-09-03 10:48
閱讀 847·2021-08-03 14:04
閱讀 2366·2019-08-29 15:18
閱讀 3411·2019-08-26 12:19
閱讀 2880·2019-08-26 12:08