STM32和WM8960 I2S 利用DMA雙緩沖音頻播放和錄音(一)


這個實驗比串口雙緩沖要稍微復雜點,音頻播放很簡單,主要是錄音,折騰快一個禮拜了,網上查找資料倒騰來倒騰去,死活就不行,哎。不搞定這個問題,不甘心,

 腦子不停的想,這個問題可能出在哪,還有哪個地方沒考慮到。就這樣,腦子興奮的很,都沒什么困意,要不是第二天要趕着上班,都不用睡了,功夫不負有心人,經過幾天折騰終於調通了。。。

 吐槽一下,現在網上都養成了一種風氣,下載一些參考資料都是要付金幣,付了金幣下載后,發現有些資料一點技術含量都沒,基本上沒什么參考價值,真氣人。

 言歸正傳,首先設置WM8960寄存器,配置播放路徑,參數配置比較簡單。播放時,STM做主機,WM8960配置從機,可以對照資料查看各個寄存器

WM8960 寄存配置:

//播放時,ST設置的是主機,WM8960是從機
const u16 wm8960_reg_slave[]=
{
    0x0f,0x000,   //SOFT reset
    0x19,0x1c0,
    0x1a,0x1f8,
    0x2f,0x00c,
    
    0x04,0x000,
    0x00,0x13f,
    0x01,0x13f,
    0x00,0x13f,
    0x01,0x13f,
    0x15,0x1f3,
    0x16,0x1f3,
    0x19,0x1ee,
    0x20,0x138,
    0x21,0x138,
    0x2b,0x000,
    0x2c,0x000,
    0x05,0x000,
    0x07,0x002,
    0x02,0x15F,
    0x03,0x15F,
    0x28,0x17F,
    0x29,0x17F,
    0x31,0x0F7,
    0x0a,0x1FF,
    0x0b,0x1FF,
    0x22,0x180,
    0x25,0x180,
    0x18,0x000,
    0x17,0x1c3,
    0x30,0x009,
};
View Code

 音頻播放數據走向如下圖

設置WM8960寄存器,配置錄音播放路徑,這里的STM配置的是從機,WM8960做主機

//錄音時,ST設置的是從機,WM8960設置主機
//WM8960 master mode   MCLK使用的是外部有源晶振24MHz
//f2=4×2×11.2896MHz的=90.3168MHz
//R = 90.3168 / 12 = 7.5264
//PLLN = int R = 7
// K = int ( 2^24 x (7.5264 – 7)) = 8831526 = 86C226h
//-----------------------------------------------------------------------------------------------------------------------------------
//|    mclk  | DESIRED OUTPUT |   f2    | PRESCALE DIVIDE | POSTSCALE DIVIDE |    FIXED POST-DIVIDE | R          |    N   |   K     |
//|    (f1)  | (SYSCLK)       | (MHz)   | (PLLPRESCALE)   | (SYSCLKDIV[1:0]) |                      |            |        |         |
//|    (MHz) | (MHz)          |         |                 |                  |                      |            |        |         |
//|----------------------------------------------------------------------------------------------------------------------------------
//|    24    | 11.2896        | 90.3168 |            2    |       2          |            4         |    7.5264  |    7h  | 86C226h |
//-----------------------------------------------------------------------------------------------------------------------------------
const u16 wm8960_reg_master[]=
{
    0x0f,0x000,   //SOFT reset
    0x19,0x17e,        // enable MIC and MICBias
    0x1a,0x1e0,        // enable DAC and ROUTPUT LOUTPUT
    0x2f,0x03c,        // enable output mixer
    0x04,0x000,        //MCLK->div1->SYSCLK->DAC/ADC sample Freq = (SYSCLK)/(1*256) = 11.2896/256 =44.1KHz
    0x20,0x138,        //LINPUT1 Microphone config
    0x21,0x138,        //RINPUT1 Microphone config
    0x2b,0x000,        // mute LINPUT3 to Left Mixer
    0x2c,0x000,        // mute RINPUT3 to Left Mixer
    0x00,0x17f,
    0x01,0x17f,
    0x05,0x000,
    0x06,0x000,
    0x07,0x002,
    0x18,0x004,
    0x30,0x000,
    0x02,0x151,//LOUT1 Volume
    0x03,0x151,//ROUT1 Volume
    0x03,0x151,//ROUT1 Volume
    0x22,0x100,//Enable Left DAC to Left Output Mixer
    0x25,0x100,//Enable Right DAC to Right Output Mixer 
    0x2d,0x080,//Left Input Boost Mixer to Left Output Mixer
    0x2e,0x080, //Right Input Boost Mixer to Right Output Mixer
    
    0x1a,0x1e1,        // enable DAC and ROUTPUT LOUTPUT;bit0=1, PLL en
    0x04,0x005,        //DAC/ADC sample Freq = (11.2896)/(1*256)=44.1K bit[0](CLKSEL)置1:選擇PLL輸出的時鍾(置0表示選擇MCLK時鍾);bit[2:1](SYSCLKDIV)置10:分頻(除以2)
    0x07,0x042,  //bit6=1, Enable master mode; bit[1:0]=10,I2S Format;bit[3:2]=00,16 bits
    0x08,0x1C4,     // BCLKDIV[3:0]=0100 BCLK Frequency = SYSCLK/4=11.2896/4=2.8224MHz
    
    0x34,0x037, //bit4(PLLPRESCALE)置1:預分頻,如果MCLK=12M就不用設置該位了;bit[3:0](PLLN)置0111:設置PLLN的值;;bit5(SDM)置1:選擇為小數模式;
    0x35,0x086,//bit[8:0](PLLK)置01000 0110:設置PLLK的值;
    0x36,0x0c2,//bit[8:0](PLLK)置01100 0010:設置PLLK的值;
    0x37,0x026,//bit[8:0](PLLK)置00010 0110:設置PLLK的值;
    
    0x14,0x0f9
}
View Code

 

(1)、錄音和播放:對麥克風講話,音頻數據直接通過WM8960內部路徑直接到耳機進行播放。音頻數據整體走向圖如下。

 

還有一種播放是將錄音的數據保存到STM,然后STM再將錄的音頻數據播放出來

錄音前端設置,用的是LINPUT1和RINPUT1,這里只貼LINPUT1配置圖,RINPUT1參考這個配置就行

 

播放后端配置圖

 

還有重要的配置,時鍾。時鍾結構圖配置

 

//錄音時,ST設置的是從機,WM8960設置主機
//WM8960 master mode   MCLK使用的是外部有源晶振24MHz
//f2=4×2×11.2896MHz的=90.3168MHz
//R = 90.3168 / 12 = 7.5264
//PLLN = int R = 7
// K = int ( 2^24 x (7.5264 – 7)) = 8831526 = 86C226h
//-----------------------------------------------------------------------------------------------------------------------------------
//|    mclk  | DESIRED OUTPUT |   f2    | PRESCALE DIVIDE | POSTSCALE DIVIDE |    FIXED POST-DIVIDE | R          |    N   |   K     |
//|    (f1)  | (SYSCLK)       | (MHz)   | (PLLPRESCALE)   | (SYSCLKDIV[1:0]) |                      |            |        |         |
//|    (MHz) | (MHz)          |         |                 |                  |                      |            |        |         |
//|----------------------------------------------------------------------------------------------------------------------------------
//|    24    | 11.2896        | 90.3168 |            2    |       2          |            4         |    7.5264  |    7h  | 86C226h |
//-----------------------------------------------------------------------------------------------------------------------------------

    0x04,0x000,        //MCLK->div1->SYSCLK->DAC/ADC sample Freq = (SYSCLK)/(1*256) = 11.2896/256 =44.1KHz
    0x1a,0x1e1,        // enable DAC and ROUTPUT LOUTPUT;bit0=1, PLL en
    0x04,0x005,        //DAC/ADC sample Freq = (11.2896)/(1*256)=44.1K bit[0](CLKSEL)置1:選擇PLL輸出的時鍾(置0表示選擇MCLK時鍾);bit[2:1](SYSCLKDIV)置10:分頻(除以2)
    0x07,0x042,  //bit6=1, Enable master mode; bit[1:0]=10,I2S Format;bit[3:2]=00,16 bits
    0x08,0x1C4,     // BCLKDIV[3:0]=0100 BCLK Frequency = SYSCLK/4=11.2896/4=2.8224MHz
    
    0x34,0x037, //bit4(PLLPRESCALE)置1:預分頻,如果MCLK=12M就不用設置該位了;bit[3:0](PLLN)置0111:設置PLLN的值;;bit5(SDM)置1:選擇為小數模式;
    0x35,0x086,//bit[8:0](PLLK)置01000 0110:設置PLLK的值;
    0x36,0x0c2,//bit[8:0](PLLK)置01100 0010:設置PLLK的值;
    0x37,0x026,//bit[8:0](PLLK)置00010 0110:設置PLLK的值;
    
    0x14,0x0f9
}

 


免責聲明!

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



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