你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

在CUBEMX生成的STM32F407VET6的I2S主机接收模式与I2S主机发送模式能正常运行,如何进行动态调整或者如何实现主机全双工?

[复制链接]
黄叙鹏 提问时间:2025-6-11 15:53 / 未解决

在CUBEMX生成的STM32F407VET6的I2S主机接收模式与I2S主机发送模式 如何进行动态调整 或者如何实现主机全双工?

初始化如下:

I2S_HandleTypeDef hi2s2;

DMA_HandleTypeDef hdma_spi2_tx;

/ I2S2 init function /

void MX_I2S2_Init(void)

{

/ USER CODE BEGIN I2S2_Init 0 /

/ USER CODE END I2S2_Init 0 /

/ USER CODE BEGIN I2S2_Init 1 /

/ USER CODE END I2S2_Init 1 /

hi2s2.Instance = SPI2;

hi2s2.Init.Mode = I2S_MODE_MASTER_TX;

hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;

hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;

hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;

hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;

hi2s2.Init.CPOL = I2S_CPOL_LOW;

hi2s2.Init.ClockSource = I2S_CLOCK_PLL;

hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;

if (HAL_I2S_Init(&hi2s2) != HAL_OK)

{

Error_Handler(); }

/ USER CODE BEGIN I2S2_Init 2 /

/ USER CODE END I2S2_Init 2 /

}

void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

if(i2sHandle->Instance==SPI2)

{

/ USER CODE BEGIN SPI2_MspInit 0 /

/ USER CODE END SPI2_MspInit 0 /

/** Initializes the peripherals clock

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;

PeriphClkInitStruct.PLLI2S.PLLI2SN = 72;

PeriphClkInitStruct.PLLI2S.PLLI2SR = 3;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

/ I2S2 clock enable /

__HAL_RCC_SPI2_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/**I2S2 GPIO Configuration

PC3 ------> I2S2_SD

PB12 ------> I2S2_WS

PB13 ------> I2S2_CK

PC6 ------> I2S2_MCK

*/

GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_6;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/ I2S2 DMA Init /

/ SPI2_TX Init /

hdma_spi2_tx.Instance = DMA1_Stream4;

hdma_spi2_tx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_spi2_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

hdma_spi2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;

hdma_spi2_tx.Init.Priority = DMA_PRIORITY_LOW;

hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;

hdma_spi2_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;

hdma_spi2_tx.Init.MemBurst = DMA_MBURST_SINGLE;

hdma_spi2_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;

if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)

{

Error_Handler();

}

__HAL_LINKDMA(i2sHandle,hdmatx,hdma_spi2_tx); / USER CODE BEGIN SPI2_MspInit 1 /

// hdma_spi2_rx.Instance->CR |= (DMA_IT_HT | DMA_IT_TC); // 或通过HAL_DMA_Init()

// __HAL_DMA_ENABLE_IT(&hdma_spi2_rx,DMA_IT_TC|DMA_IT_HT);

/ USER CODE END SPI2_MspInit 1 /

}

}

void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)

{

if(i2sHandle->Instance==SPI2)

{

/ USER CODE BEGIN SPI2_MspDeInit 0 /

/ USER CODE END SPI2_MspDeInit 0 /

/ Peripheral clock disable /

__HAL_RCC_SPI2_CLK_DISABLE();

/**I2S2 GPIO Configuration

PC3 ------> I2S2_SD

PB12 ------> I2S2_WS

PB13 ------> I2S2_CK

PC6 ------> I2S2_MCK

*/

HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3|GPIO_PIN_6);

HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);

/ I2S2 DMA DeInit /

HAL_DMA_DeInit(i2sHandle->hdmatx); / USER CODE BEGIN SPI2_MspDeInit 1 /

/ USER CODE END SPI2_MspDeInit 1 /

}

}

接收配置

I2S_HandleTypeDef hi2s2;

DMA_HandleTypeDef hdma_spi2_rx;

/ I2S2 init function /

void MX_I2S2_Init(void)

{

/ USER CODE BEGIN I2S2_Init 0 /

/ USER CODE END I2S2_Init 0 /

/ USER CODE BEGIN I2S2_Init 1 /

/ USER CODE END I2S2_Init 1 /

hi2s2.Instance = SPI2;

hi2s2.Init.Mode = I2S_MODE_MASTER_RX;

hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;

hi2s2.Init.DataFormat = I2S_DATAFORMAT_16B;

hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;

hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;

hi2s2.Init.CPOL = I2S_CPOL_LOW;

hi2s2.Init.ClockSource = I2S_CLOCK_PLL;

hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;

if (HAL_I2S_Init(&hi2s2) != HAL_OK)

{

Error_Handler(); }

/ USER CODE BEGIN I2S2_Init 2 /

/ USER CODE END I2S2_Init 2 /

}

void HAL_I2S_MspInit(I2S_HandleTypeDef* i2sHandle)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};

if(i2sHandle->Instance==SPI2)

{

/ USER CODE BEGIN SPI2_MspInit 0 /

/ USER CODE END SPI2_MspInit 0 /

/** Initializes the peripherals clock

*/

PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2S;

PeriphClkInitStruct.PLLI2S.PLLI2SN = 72;

PeriphClkInitStruct.PLLI2S.PLLI2SR = 3;

if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)

{

Error_Handler();

}

/ I2S2 clock enable /

__HAL_RCC_SPI2_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();

__HAL_RCC_GPIOB_CLK_ENABLE();

/**I2S2 GPIO Configuration

PC3 ------> I2S2_SD

PB12 ------> I2S2_WS

PB13 ------> I2S2_CK

PC6 ------> I2S2_MCK

*/

GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_6;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;

GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

/ I2S2 DMA Init /

/ SPI2_RX Init /

hdma_spi2_rx.Instance = DMA1_Stream3;

hdma_spi2_rx.Init.Channel = DMA_CHANNEL_0;

hdma_spi2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;

hdma_spi2_rx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi2_rx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;

hdma_spi2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;

hdma_spi2_rx.Init.Mode = DMA_CIRCULAR;

hdma_spi2_rx.Init.Priority = DMA_PRIORITY_MEDIUM;

hdma_spi2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;

if (HAL_DMA_Init(&hdma_spi2_rx) != HAL_OK)

{

Error_Handler();

}

__HAL_LINKDMA(i2sHandle,hdmarx,hdma_spi2_rx); / USER CODE BEGIN SPI2_MspInit 1 /

// hdma_spi2_rx.Instance->CR |= (DMA_IT_HT | DMA_IT_TC); // 或通过HAL_DMA_Init()

// __HAL_DMA_ENABLE_IT(&hdma_spi2_rx,DMA_IT_TC|DMA_IT_HT);

/ USER CODE END SPI2_MspInit 1 /

}

}

void HAL_I2S_MspDeInit(I2S_HandleTypeDef* i2sHandle)

{

if(i2sHandle->Instance==SPI2)

{

/ USER CODE BEGIN SPI2_MspDeInit 0 /

/ USER CODE END SPI2_MspDeInit 0 /

/ Peripheral clock disable /

__HAL_RCC_SPI2_CLK_DISABLE();

/**I2S2 GPIO Configuration

PC3 ------> I2S2_SD

PB12 ------> I2S2_WS

PB13 ------> I2S2_CK

PC6 ------> I2S2_MCK

*/

HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3|GPIO_PIN_6);

HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);

/ I2S2 DMA DeInit /

HAL_DMA_DeInit(i2sHandle->hdmarx); / USER CODE BEGIN SPI2_MspDeInit 1 /

/ USER CODE END SPI2_MspDeInit 1 /

}

}

收藏 评论3 发布时间:2025-6-11 15:53

举报

3个回答
xmshao 回答时间:7 天前
我看你配置的代码都禁用了全双工,其实STM32F407的I2S是完全支持全双工的。


比方:


rrrr.png



static void MX_I2S2_Init(void)
{


  hi2s2.Instance = SPI2;
  hi2s2.Init.Mode = I2S_MODE_MASTER_RX;
  hi2s2.Init.Standard = I2S_STANDARD_PHILIPS;
  hi2s2.Init.DataFormat = I2S_DATAFORMAT_24B;
  hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;
  hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
  hi2s2.Init.CPOL = I2S_CPOL_LOW;
  hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
  hi2s2.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;
  if (HAL_I2S_Init(&hi2s2) != HAL_OK)
  {
    Error_Handler();
  }
}
rrrr.png
黄叙鹏 回答时间:7 天前

xmshao 发表于 2025-6-12 11:35
我看你配置的代码都禁用了全双工,其实STM32F407的I2S是完全支持全双工的。</p>
<p>

我按这个配置后发现主时钟输出是不对,采用HAL_I2S_Receive_DMA(&hi2s2,(uint16_t*)adc_buf,2048);也无法接收到数据

xmshao 回答时间:6 天前

黄叙鹏 发表于 2025-6-12 14:31
我按这个配置后发现主时钟输出是不对,采用HAL_I2S_Receive_DMA(&amp;hi2s2,(uint16_t*)adc_buf,2048);也 ...

[md]如果你要做全双工,配置就是这样的。

至于你说的时钟问题,那就看你的具体设计了。

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版