zoukankan      html  css  js  c++  java
  • 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
    }

  • 相关阅读:
    Spring Cloud
    Hibernate 缓存
    Spring 快速入门
    Junit 单元测试
    Spring Cloud 笔记
    Swagger SpringBoot 集成
    Apache Shiro 权限框架
    Spring Boot
    跨域问题
    BeX5 常见问题解决办法
  • 原文地址:https://www.cnblogs.com/wen2376/p/12345089.html
Copyright © 2011-2022 走看看