SYD8821 I2S模块发送功能使用说明

SYD8821是具有全球领先低功耗(RX 2.4mA @-94.5dBm灵敏度,TX 4.3mA @0dBm输出功率)的蓝牙低功耗SOC芯片,在极低电流下实现了优异的射频性能,搭配176kB SRAM,512kB flash,非常适合中高阶可穿戴、智能家居、物联网等低功耗应用。具体可咨询:http://www.syd-tek.com/

SYD8821 I2S模块使用说明

     SYD8821崇尚高性能与低功耗,增加I2S接口也就是必然的选择。

     SYD8821的I2S接口完全符合标准I2S协议,关于I2S协议这里不再深入说明,有兴趣可看:I2S总线原理及其实例:《https://blog.csdn.net/chengdong1314/article/details/81210205

        本博客将做这样的测试:使用syd8821播放音乐《擦肩而过.wav》的前面200KB数据,大约是6.3S的数据!

       这里首先介绍一下硬件平台,因为SYD8821开发板上并没有I2S的模块,所以这里借用WIFI开发板上的I2S模块进行音频的解码,测试实物图如下:

    WIFI开放板的IIS模块的原理图如下:

     因为该WIFI开发板上已经集成了发出MCLK的有源时钟晶振,所以这里SYD8821只要和该I2S模块连接三根线即可,分别为:SCLK(GPIO7)、LRCLK(GPIO8)、SDO(GPIO9)即可。具体连接图请看上面的实物图!

      SYD8821的main函数如下:

#define    WAV_FILE_HEADER 0x2c     //WAV文件数据头
#define    CONST_BUFF_LEN 204800    //WAV文件的大小
#define    RAM_BUFF_LEN 16*1024     //分配给I2S模块的DMA内存大小

static __align(4) uint8_t buf_Ram[RAM_BUFF_LEN]={0};
const uint8_t buf_const[CONST_BUFF_LEN];
int DMA_size = 0;

#define DEBUG_I2S_DMA    //启用I2Sdebug打印功能

#ifdef DEBUG_I2S_DMA
unsigned char DMA_cnt = 0,DMA_cnt_last = 0;
#endif

const uint8_t * audio_data_p=buf_const;
uint8_t * audio_rambuff_p=buf_Ram;
/*
0:空闲状态   依旧发送静态音频
1:播放状态
2:播放完成
*/
char  audio_state=0;

void i2s_test_init(void)     //I2S初始化函数
{
    int i;
    
    for (i = 7; i < 12; i++)    //初始化IO口
        pad_mux_write(i, 9); // MCK, SCK, LRCK, DO, DI

    // 8K 16-bit configuration 
    i2s_set_mclk(I2S_CLK_DIV31);    //MCLK时钟的分频系数
    i2s_set_bit_clk(I2S_MCLK_DIV4);   //BIT CLOCK的风频系数,其中/BIT CLOCK来源于MCLK
    
    i2s_set_channel_clock(I2S_LEFT_LOW);     //设置发送左声道数据时LRCLK为低电平
    i2s_set_channel(I2S_STEREO);    //设置播放模式为立体声播放,两个声道都有数据
    i2s_set_bit_order(I2S_TX, I2S_MSB_FIRST);    //设置I2S数据模式为高位在前
    i2s_set_transfer_format(I2S_FISRT_BIT_SECOND_CYCLE);    //设置数据在LRCLK边沿的第二个上升沿有效
    
    i2s_set_sample_width(I2S_16BIT);    //设置音频数据为16BIT
    i2s_enable_int(I2S_DMA_ALL_INT);    //使能I2S模块的所有中断
    NVIC_EnableIRQ(I2S_IRQn);
}

static void i2s_test_slient_irq_cb(uint32_t int_st)     //I2S中断回调函数
{
    DMA_cnt++;
    if(audio_state==0)
    {
        //DBG("idle dma_cnt:%x\r\n",DMA_cnt);
    }
    else if(audio_state==1)
    {
        //DBG("play dma_cnt:%x ",DMA_cnt);
        if (int_st & I2S_DMA_HALF_DONE_INT_ST) {    //更具DMA是半中断或者全中断来填充数组
            audio_rambuff_p=buf_Ram+DMA_size/2;
            memcpy(audio_rambuff_p,audio_data_p,DMA_size/2);
            audio_data_p+=DMA_size/2;
            //DBG("buf_Ram_p2:%x ",(buf_Ram+DMA_size/2));
        }
        else if (int_st & I2S_DMA_DONE_INT_ST) {
            audio_rambuff_p=buf_Ram;
            memcpy(audio_rambuff_p,audio_data_p,DMA_size/2);
            audio_data_p+=DMA_size/2;
            //DBG("buf_Ram_p1:%x ",buf_Ram);
        }
        if(audio_data_p>=(buf_const+CONST_BUFF_LEN))
        {
            audio_state=2;
        }
        //DBG("data_p:%x\r\n",audio_data_p);
    }
    else if(audio_state==2)
    {
        //i2s_stop();
        memset(buf_Ram,0xff,DMA_size);
        audio_state=0;
        //DBG("play finish dma_cnt:%x\r\n",DMA_cnt);
    }
}

void i2s_test_Silent_TX(void)    //I2S启动函数
{
    DMA_size=RAM_BUFF_LEN;
    
    memset(buf_Ram,0xff,DMA_size);
    
    i2s_set_irq_callback(i2s_test_slient_irq_cb);
    i2s_trigger_TXDMA(buf_Ram, DMA_size);
}

int main()
{    
    __disable_irq();
    //GPO
    pad_mux_write(LED1, 0);
    pad_mux_write(LED2, 0);
    pad_mux_write(LED3, 0);
    pad_mux_write(LED4, 0);
    gpo_config(LED1,1);
    gpo_config(LED2,1);
    gpo_config(LED3,1);
  gpo_config(LED4,1);
    
    //GPI
    pad_mux_write(KEY1, 0);
    pad_mux_write(KEY2, 0);
    pad_mux_write(KEY3, 0);
    pad_mux_write(KEY4, 0);
    gpi_config(KEY1, PULL_UP);
    gpi_config(KEY2, PULL_UP);
    gpi_config(KEY3, PULL_UP);
    gpi_config(KEY4, PULL_UP);

  //uart 0
    pad_mux_write(20, 7);
    pad_mux_write(21, 7);
    dbg_init();
    dbg_printf("SYD8821 IIS DEMO\r\n");

    i2s_test_init();
    __enable_irq();
    
    DMA_cnt=0;
    audio_state=0;
    i2s_test_Silent_TX();

    while(1)
    {
        gpo_toggle(LED4);
        
        #ifdef DEBUG_I2S_DMA
        if(DMA_cnt !=DMA_cnt_last)   //更具I2S模块的状态打印出I2S模块的运行信息
        {
            DMA_cnt_last=DMA_cnt;
            if(audio_state==0)
            {
                DBG("idle dma_cnt:%x\r\n",DMA_cnt);
            }
            else if(audio_state==1)
            {
                DBG("play dma_cnt:%x buf_Ram_p2:%x data_p:%x",DMA_cnt,audio_rambuff_p,audio_data_p);
            }
            else if(audio_state==2)
            {
                DBG("play finish dma_cnt:%x\r\n",DMA_cnt);
            }
        }
        #endif
        
        if(!gpi_get_val(KEY1)){    //按下开发板上的按键1则开始I2S播放音乐
            gpo_toggle(LED1);
            if(audio_state==0)
            {
                audio_data_p=buf_const+WAV_FILE_HEADER;
                audio_state=1;
            }
        }
    }        
}

const uint8_t buf_const[CONST_BUFF_LEN] =  
{                                                 
0x52,0x49,0x46,0x46,0xd0,0x98,0x3a,0x00,0x57,0x41,0x56,0x45,0x66,0x6d,0x74,0x20,
0x10,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x40,0x1f,0x00,0x00,0x00,0x7d,0x00,0x00,
0x04,0x00,0x10,0x00,0x64,0x61,0x74,0x61,0xac,0x98,0x3a,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

。。。。。。。。。。。。。。。。。。。。。。。。

}

     其中buf_const数据是《擦肩而过.wav》文件的前面两百KB的内容,代码运行后按下KEY1可看到如下打印:

20:54:46:912 SYD8821 IIS DEMO
20:54:47:169 idle dma_cnt:1
20:54:47:422 idle dma_cnt:2
20:54:47:676 idle dma_cnt:3
20:54:47:930 idle dma_cnt:4
20:54:48:183 idle dma_cnt:5
20:54:48:437 idle dma_cnt:6
20:54:48:684 idle dma_cnt:7
20:54:48:934 idle dma_cnt:8
20:54:49:200 idle dma_cnt:9
20:54:49:454 idle dma_cnt:a
20:54:49:708 idle dma_cnt:b
20:54:49:962 idle dma_cnt:c
20:54:50:216 idle dma_cnt:d
20:54:50:471 idle dma_cnt:e
20:54:50:723 idle dma_cnt:f
20:54:50:977 idle dma_cnt:10
20:54:51:231 idle dma_cnt:11
20:54:51:490 play dma_cnt:12 buf_Ram_p2:20000044 data_p:10003a3e
20:54:51:740 play dma_cnt:13 buf_Ram_p2:20002044 data_p:10005a3e
20:54:51:994 play dma_cnt:14 buf_Ram_p2:20000044 data_p:10007a3e
20:54:52:248 play dma_cnt:15 buf_Ram_p2:20002044 data_p:10009a3e
20:54:52:502 play dma_cnt:16 buf_Ram_p2:20000044 data_p:1000ba3e
20:54:52:756 play dma_cnt:17 buf_Ram_p2:20002044 data_p:1000da3e
20:54:53:010 play dma_cnt:18 buf_Ram_p2:20000044 data_p:1000fa3e
20:54:53:264 play dma_cnt:19 buf_Ram_p2:20002044 data_p:10011a3e
20:54:53:518 play dma_cnt:1a buf_Ram_p2:20000044 data_p:10013a3e
20:54:53:772 play dma_cnt:1b buf_Ram_p2:20002044 data_p:10015a3e
20:54:54:026 play dma_cnt:1c buf_Ram_p2:20000044 data_p:10017a3e
20:54:54:279 play dma_cnt:1d buf_Ram_p2:20002044 data_p:10019a3e
20:54:54:533 play dma_cnt:1e buf_Ram_p2:20000044 data_p:1001ba3e
20:54:54:787 play dma_cnt:1f buf_Ram_p2:20002044 data_p:1001da3e
20:54:55:048 play dma_cnt:20 buf_Ram_p2:20000044 data_p:1001fa3e
20:54:55:295 play dma_cnt:21 buf_Ram_p2:20002044 data_p:10021a3e
20:54:55:549 play dma_cnt:22 buf_Ram_p2:20000044 data_p:10023a3e
20:54:55:803 play dma_cnt:23 buf_Ram_p2:20002044 data_p:10025a3e
20:54:56:057 play dma_cnt:24 buf_Ram_p2:20000044 data_p:10027a3e
20:54:56:311 play dma_cnt:25 buf_Ram_p2:20002044 data_p:10029a3e
20:54:56:565 play dma_cnt:26 buf_Ram_p2:20000044 data_p:1002ba3e
20:54:56:819 play dma_cnt:27 buf_Ram_p2:20002044 data_p:1002da3e
20:54:57:071 play dma_cnt:28 buf_Ram_p2:20000044 data_p:1002fa3e
20:54:57:321 play dma_cnt:29 buf_Ram_p2:20002044 data_p:10031a3e
20:54:57:580 play finish dma_cnt:2a
20:54:57:834 idle dma_cnt:2b
20:54:58:087 idle dma_cnt:2c
20:54:58:334 idle dma_cnt:2d
20:54:58:595 idle dma_cnt:2e
20:54:58:835 idle dma_cnt:2f
20:54:59:100 idle dma_cnt:30
20:54:59:350 idle dma_cnt:31
20:54:59:599 idle dma_cnt:32
20:54:59:865 idle dma_cnt:33
20:55:00:118 idle dma_cnt:34
20:55:00:367 idle dma_cnt:35
20:55:00:616 idle dma_cnt:36
20:55:00:866 idle dma_cnt:37
20:55:01:131 idle dma_cnt:38
20:55:01:381 idle dma_cnt:39
20:55:01:630 idle dma_cnt:3a
20:55:01:895 idle dma_cnt:3b
20:55:02:145 idle dma_cnt:3c
20:55:02:395 idle dma_cnt:3d
20:55:02:644 idle dma_cnt:3e
20:55:02:909 idle dma_cnt:3f
20:55:03:159 idle dma_cnt:40
20:55:03:409 idle dma_cnt:41

具体打印内容请看文件;《https://download.csdn.net/download/chengdong1314/10564274

   然后使用逻辑分析仪可看到如下波形:

具体的逻辑分析仪数据请看文件:《https://download.csdn.net/download/chengdong1314/10564309

注意这里因为是先出R再出L,所以数据分布和数组是不一样的,先出第一个16BIT,然后再出第二个16BIT!

这里上传本博客最后播放出来的音乐:《https://download.csdn.net/download/chengdong1314/10573643中的《I2S录音.m4a

这里上传本博客的源码:https://download.csdn.net/download/chengdong1314/10564315工程在:\Source Code\SYD8821\iis\Keil

有一个地方要注意的是buf_const数据的生成,这里专门做了一个tool来生成这个数组:

这里上传该工具:《https://download.csdn.net/download/chengdong1314/10573643中的《syd_arr_release

关于WAV的知识请看:《https://blog.csdn.net/chengdong1314/article/details/54171667

最后上传wifi开发板的硬件资料:《https://download.csdn.net/download/chengdong1314/10564336

猜你喜欢

转载自blog.csdn.net/chengdong1314/article/details/81210103
今日推荐