CN / EN
文档反馈
感谢关注汇顶文档,期待您的宝贵建议!
感谢您的反馈,祝您愉快!

I2S Master & Slave

I2S Master & Slave示例用于验证I2S的数据传输功能,通过宏MASTER_BOARD确定为Master或Slave。

该示例需要两块开发板,一块作为Master,一块作为Slave。

I2S Master & Slave示例的源代码和工程文件位于SDK_Folder\projects\peripheral\i2s\i2s_master_salve\,其中工程文件在文件夹Keil_5下。

代码理解

示例工程流程图如图 20所示:

图 20 I2S Master & Slave示例工程流程图
  1. 配置I2S模块。

    I2S详细配置参数请参考I2S Master Audio

    #ifdef MASTER_BOARD
        g_i2s_handle.p_instance  = I2S_M;
        g_i2s_handle.init.audio_freq  = 48000;
    #else
        g_i2s_handle.p_instance  = I2S_S;
    #endif  /* MASTER_BOARD */
        g_i2s_handle.init.data_size   = I2S_DATASIZE_32BIT;
        g_i2s_handle.init.clock_source = I2S_CLOCK_SRC_96M;
        hal_i2s_init(&g_i2s_handle);
    
  2. Master分别使用DMA、中断、轮询方式和Slave进行数据交互。
    • 因I2S目前采用用户控制时钟开关状态,故为了防止接收或者发送不必要的数据,需调用i2s_flush_rx_fifo()或者i2s_flush_tx_fifo()接口,清除RX/TX FIFO中的数据。
    • Master在操作完成后调用__HAL_I2S_DISABLE_CLOCK()关闭时钟或者重新初始化I2S,防止时钟使能设备一直处于收发阶段。
    • 采用非阻塞方式的接口,需在后续步骤中用while判断是否收发完成。代码如下:
      i2s_flush_rx_fifo(&g_i2s_handle);
      hal_i2s_transmit_receive_dma(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2);
      while (!tx_rx_flag);
      while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
      sys_delay_ms(1);
      hal_i2s_deinit(&g_i2s_handle);
      hal_i2s_init(&g_i2s_handle);
      hal_i2s_transmit_receive_it(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2);
      while (!tx_rx_flag);
      while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
      sys_delay_ms(1);
      hal_i2s_deinit(&g_i2s_handle);
      hal_i2s_init(&g_i2s_handle);
      
      i2s_flush_rx_fifo(&g_i2s_handle);
      hal_i2s_transmit_receive(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2, 2000);
      while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
      sys_delay_ms(1);
      hal_i2s_deinit(&g_i2s_handle);
      hal_i2s_init(&g_i2s_handle);
      
      i2s_flush_rx_fifo(&g_i2s_handle);
      hal_i2s_transmit_it(&g_i2s_handle, wdata, sizeof(wdata) >> 2);
      while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
      sys_delay_ms(1);
      hal_i2s_deinit(&g_i2s_handle);
      hal_i2s_init(&g_i2s_handle);
      sys_delay_ms(10);
      i2s_flush_rx_fifo(&g_i2s_handle);
      hal_i2s_receive_it(&g_i2s_handle, rdata, sizeof(rdata) >> 2);
      while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
      sys_delay_ms(1);
      hal_i2s_deinit(&g_i2s_handle);
      hal_i2s_init(&g_i2s_handle);
      
  3. Slave分别使用DMA,中断,轮询方式和Master进行数据交互。

    为了防止接收或者发送不必要的数据,需调用i2s_flush_rx_fifo()或者i2s_flush_tx_fifo()接口,清除RX/TX FIFO中的数据。代码如下:

    i2s_flush_rx_fifo(&g_i2s_handle);
    hal_i2s_transmit_receive_dma(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2);
    while (!tx_rx_flag);
    while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
    hal_i2s_deinit(&g_i2s_handle);
    hal_i2s_init(&g_i2s_handle);
    
    i2s_flush_rx_fifo(&g_i2s_handle);
    hal_i2s_transmit_receive_it(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2);
    while (!tx_rx_flag);
    while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
    hal_i2s_deinit(&g_i2s_handle);
    hal_i2s_init(&g_i2s_handle);
    
    i2s_flush_rx_fifo(&g_i2s_handle);
    hal_i2s_transmit_receive(&g_i2s_handle, wdata, rdata, sizeof(wdata) >> 2, 2000);
    while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
    hal_i2s_deinit(&g_i2s_handle);
    hal_i2s_init(&g_i2s_handle);
    
    i2s_flush_rx_fifo(&g_i2s_handle);
    hal_i2s_receive_it(&g_i2s_handle, rdata, sizeof(rdata) >> 2);
    while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
    hal_i2s_deinit(&g_i2s_handle);
    hal_i2s_init(&g_i2s_handle);
    
    i2s_flush_rx_fifo(&g_i2s_handle);
    hal_i2s_transmit_it(&g_i2s_handle, wdata, sizeof(wdata) >> 2);
    while (hal_i2s_get_state(&g_i2s_handle) != HAL_I2S_STATE_READY);
    sys_delay_ms(2);
    hal_i2s_deinit(&g_i2s_handle);
    

测试验证

  1. 在工程配置中定义宏MASTER_BOARD,编译并下载至主设备开发板;工程配置中取消宏定义MASTER_BOARD,编译并下载至从设备开发板。
  2. 连接主从设备开发板的对应IO引脚。
  3. 将主从设备开发板的串口分别连接至PC端,打开并配置GRUart。
  4. 在GRUart的Receive Data窗口中将会显示I2S的数据传输结果。

扫描关注

打开微信,使用“扫一扫”即可关注。