stm32音頻接口I2S


stm32音頻接口I2S

1 I2S簡介

  I2S(Inter-IC Sound)飛利浦公司為數字音頻設備之間的音頻數據傳輸而制定的一種總線標准。I2S有3個主要信號

1.串行時鍾SCLK,也叫位時鍾(BCLK),即對應數字音頻的每一位數據,SCLK都有1個脈沖。SCLK的頻率=2×采樣頻率×采樣位數。

2. 幀時鍾LRCK,(也稱WS),用於切換左右聲道的數據。LRCK為“1”表示正在傳輸的是右聲道的數據,為“0”則表示正在傳輸的是左聲道的數據。LRCK的頻率等於采樣頻率。

3.串行數據SDATA,就是用二進制補碼表示的音頻數據。

有時為了使系統間能夠更好地同步,還需要另外傳輸一個信號MCLK,稱為主時鍾,也叫系統時鍾(Sys Clock),是采樣頻率的256倍或384倍。

串行數據(SD)

  I2S格式的信號無論有多少位有效數據,數據的最高位總是出現在LRCK變化(也就是一幀開始)后的第2個SCLK脈沖處。這就使得接收端與發送端的有效位數可以不同。如果接收端能處理的有效位數少於發送端,可以放棄數據幀中多余的低位數據;如果接收端能處理的有效位數多於發送端,可以自行補足剩余的位。這種同步機制使得數字音頻設備的互連更加方便,而且不會造成數據錯位。(以上信息來自百度百科)

2  從設備ADMP441

  接口:標准飛利浦數字I2S接口,24-bit數據

  SCK :I2S接口的串行數據時鍾引腳。

  SD  :I2S接口的串行數據輸出引腳。

  WS :I2S接口的串行數據字選擇引腳。

  電源電壓:1.8 V < VDD < 3.3 V。

  數據格式:從機串行數據端口的格式為I2S 24-bit二進制補碼。

  默認的數據格式為I2S (二進制補碼),MSB 優先。

從機串行數據端口的格式為I2S 24-bit二進制補碼。每個WS立體聲數據幀對應64 個SCK 周期(fSCK = 64 × fWS)。;每個數據字必須對應32個SCK 周期。L/R控制引腳決定ADMP441從左通道還是右通道輸出數據。

圖1   硬件連接圖

圖2   立體聲輸出I2S時序圖

3         stm32中I2S配置

3.1管腳映射

  stm32的大容量產品和互聯型產品支持I2S音頻協議(本文檔使用stm32f103fzet6)。可以將SPI模塊用作I2S音頻接口。I2S和SPI共用3個引腳:

  ● SD:串行數據(映射至MOSI引腳),用來發送和接收2路時分復用通道的數據(PB15);

  ● WS:字選(映射至NSS引腳),主模式下作為數據控制信號輸出,從模式下作為輸入(PB12);

  ● CK:串行時鍾(映射至SCK引腳),主模式下作為時鍾信號輸出,從模式下作為輸入(PB13)。

  ● MCK:主時鍾(獨立映射),在I2S 配置為主模式,寄存器SPI_I2SPR的MCKOE位為’1’時,作為輸出額外的時鍾信號引腳使用。輸出時鍾信號的頻率預先設置為256×Fs,其中Fs是音頻信號的采樣頻率。(ADMP441用不到)

3.2參數說明和配置

  ●模式配置(IS_I2S_MODE):設置寄存器SPI_I2SCFG[1:0]選擇I2S主模式和方向。

      00: 從設備發送(I2S_Mode_SlaveTx);

    01: 從設備接收(I2S_Mode_SlaveRx);

    10: 主設備發送(I2S_Mode_MasterTx);

  11: 主設備接受(I2S_Mode_MasterRx)。

    主設備輸出WS,SCK;從設備WS,SCK作為輸入信號。

    發送端輸出SD;接收端SD作為輸入信號。

圖3 I2S模式配置

  ●數據格式(IS_I2S_DATA_FORMAT)

IS_I2S_DATA_FORMAT

IS_I2S_STANDARD

I2S_DataFormat_16b (16位全精度)

I2S_Standard_Phillips(飛利浦規定的格式)

I2S_DataFormat_16bextended(16位擴展32位)

I2S_Standard_MSB(日本格式、普通格式)

I2S_DataFormat_24b(24位幀)

I2S_Standard_LSB(較少使用)

I2S_DataFormat_32b(32位全精度)

I2S_Standard_PCMShort

  ADMP使用飛利浦24bit標准的I2S格式。如果只是讀取前16bit的數據,也可以使用。在I2S 配置階段,如果選擇將16位數據擴展到32位聲道幀,只需要訪問一次寄存器SPI_DR。用來擴展到32位的低16位被硬件置為0x0000。接收時,每次收到高16位半字(MSB) 后,標志位RXNE 置’1’ ,如果允許了相應的中斷,則可以產生中斷。這樣,在2次讀和寫之間有更多的時間,可以防止下溢或者上溢的情況發生。在使用16位數據擴展到32位幀時,前16位(MSB) 是有意義的數據,后16位(LSB) 被強制為0,該操作不需要軟件干預,也不需要有DMA請求(僅需要一次讀/ 寫操作)。

圖4   Phillips_I2S_DataFormat_16bextended

  ADMP取24bit數據時,24位數據幀需要CPU對寄存器SPI_DR進行2 次讀或寫操作,在使用DMA時,需要2 次DMA傳輸。對於24位數據,擴展到32位后,最低8位由硬件置0。如果接收0X8EAA33,第一次讀SPI_DR得到0X8EAA,第二次讀SPI_DR得到0X3300,只有高8位有效,低8位始終是00。

 

圖5   Phillips_I2S_DataFormat_16b

3.3代碼配置

●GPIO

         //Configure the GPIO Pins for I2S

    GPIO_InitTypeDef GPIO_InitStructure;

         /* Enable GPIOB, GPIOC and AFIO clock */

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOG | RCC_APB2Periph_GPIOF |    RCC_APB2Periph_AFIO, ENABLE);

         /* I2S2 SD, CK and WS pins configuration */

/*I2S2_SD-PB15;I2S2_ CK-PB13;I2S2_WS-PB12*/

         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15;

         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

         GPIO_Init(GPIOB, &GPIO_InitStructure); 

●I2S

// Initialise and Configure the Mode for I2S

     I2S_InitTypeDef I2S_InitStructure;

/* Enable I2S peripheral clocks*/

         RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

         /*Reset SPI2*/

         SPI_I2S_DeInit(SPI2);

         I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;                                 I2S_InitStructure.I2S_Standard = _I2S_Standard_Phillips;           

    I2S_InitStructure.I2S_DataFormat = _I2S_DataFormat_16bextended;

    I2S_InitStructure.I2S_AudioFreq = _I2S_AudioFreq_8k;         

/*I2S clock steady state is low level */

         I2S_InitStructure.I2S_CPOL = I2S_CPOL_Low;                       

         I2S_Init(SPI2, &I2S_InitStructure);

         SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, DISABLE);

         I2S_Cmd(SPI2, ENABLE);

         SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);      

●NVIC

//Initialise the Nested Vectored Interrupt Controller
 NVIC_InitTypeDef NVIC_InitStructure;

         NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;

         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

         NVIC_Init(&NVIC_InitStructure);

●SPI2_IRQHandler

extern uint32_t usData;

extern uint32_t usData1;

void SPI2_IRQHandler(void)

{

         usData = SPI_I2S_ReceiveData(SPI2);

         if (SPI_I2S_GetFlagStatus(SPI2, I2S_FLAG_CHSIDE) != SET)   /*if it is left chanel*/

                   usData1 = usData;}

4實驗結果

 

圖6   邏輯分析儀采集(D1:SCK;D2:WS;D3:SD)

 

 

圖7   電壓-時間圖(聲音為語音信號)

5參考資料

  1. ADMP441_cn.pdf
  2. 百度百科
  3. STM32固件庫使用手冊的中文翻譯版.pdf
  4. STM32中文參考手冊_V10.pdf

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM