硬汉嵌入式论坛

 找回密码
 立即注册
查看: 946|回复: 1
收起左侧

[有问必答] I2S音频传输频率不匹配

[复制链接]

16

主题

58

回帖

106

积分

初级会员

积分
106
发表于 2024-7-10 18:30:01 | 显示全部楼层 |阅读模式
使用stm32F7的I2S发送1kHz正弦波给DSP芯片并输出,结果DSP输出频率变成了2kHz,查找半天没发现原因,请教哪里有问题,I2S代码如下

[C] 纯文本查看 复制代码
int16_t Sin1648[]=
{
	1,	1,
	1074,	1074,
	2130,	2130,
	3151,	3151,
	4116,	4116,
	5010,	5010,
	5820,	5820,
	6530,	6530,
	7129,	7129,
	7604,	7604,
	7950,	7950,
	8160,	8160,
	8231,	8231,
	8161,	8161,
	7951,	7951,
	7604,	7604,
	7128,	7128,
	6531,	6531,
	5820,	5820,
	5011,	5011,
	4116,	4116,
	3151,	3151,
	2131,	2131,
	1074,	1074,
	0,	0,
	64462,	64462,
	63406,	63406,
	62386,	62386,
	61421,	61421,
	60525,	60525,
	59716,	59716,
	59006,	59006,
	58408,	58408,
	57932,	57932,
	57586,	57586,
	57375,	57375,
	57305,	57305,
	57375,	57375,
	57586,	57586,
	57932,	57932,
	58408,	58408,
	59006,	59006,
	59716,	59716,
	60525,	60525,
	61420,	61420,
	62386,	62386,
	63406,	63406,
	64462,	64462,
	
	1,	1,
	1074,	1074,
	2130,	2130,
	3151,	3151,
	4116,	4116,
	5010,	5010,
	5820,	5820,
	6530,	6530,
	7129,	7129,
	7604,	7604,
	7950,	7950,
	8160,	8160,
	8231,	8231,
	8161,	8161,
	7951,	7951,
	7604,	7604,
	7128,	7128,
	6531,	6531,
	5820,	5820,
	5011,	5011,
	4116,	4116,
	3151,	3151,
	2131,	2131,
	1074,	1074,
	0,	0,
	64462,	64462,
	63406,	63406,
	62386,	62386,
	61421,	61421,
	60525,	60525,
	59716,	59716,
	59006,	59006,
	58408,	58408,
	57932,	57932,
	57586,	57586,
	57375,	57375,
	57305,	57305,
	57375,	57375,
	57586,	57586,
	57932,	57932,
	58408,	58408,
	59006,	59006,
	59716,	59716,
	60525,	60525,
	61420,	61420,
	62386,	62386,
	63406,	63406,
	64462,	64462

};

/* 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_24B;
  hi2s2.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  hi2s2.Init.AudioFreq = I2S_AUDIOFREQ_48K;
  hi2s2.Init.CPOL = I2S_CPOL_LOW;
  hi2s2.Init.ClockSource = I2S_CLOCK_PLL;
  if (HAL_I2S_Init(&hi2s2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S2_Init 2 */
  SPI2->CR2|=1<<1;							//SPI2 TX DMA请求使能
  __HAL_I2S_ENABLE(&hi2s2);					//使能I2S2	  

  /* USER CODE END I2S2_Init 2 */

}
const u16 I2S_PSC_TBL[][5]=
{
	/*Fs, PLLI2S_N, PLLI2S_Q, PLLI2S_DivQ, MCKDIV*/
	{800 ,	256,		5,		12,			1},		//8Khz采样率
	{1102,	429,		4,		19,			0},		//11.025Khz采样率 
	{1600,	213,		2,		13,			0},		//16Khz采样率
	{2205,	429,		4, 		9,			1},		//22.05Khz采样率
	{3200,	213,		2, 		6,			1},		//32Khz采样率
	{4410,	271,		2, 		6,			0},		//44.1Khz采样率
	{4800,	258,		3, 		3,			1},		//48Khz采样率
	{8820,	316,		2, 		3,			1},		//88.2Khz采样率
	{9600,	344,		2, 		3,			1},  	//96Khz采样率
	{17640,	361,		2,		2,			0},  	//176.4Khz采样率 
	{19200,	393,		2,		2,			0},  	//192Khz采样率
};
/*
HSE_VALUE = 25MHz, PLL_M = 25
PLLI2SCLK = (HSE_VALUE / PLL_M)*PLLI2S_N/PLLI2S_Q  
MCLK时钟禁止输出, 24位深采样率计算:
FS = PLLI2SCLK/[(24*2)*((2*I2SDIV)+ODD))]

*/


//设置SAIA的采样率(@MCKEN)
//samplerate:采样率,单位:Hz
//返回值:0,设置成功;1,无法设置.
u8 I2S2_SampleRate_Set(u32 samplerate)
{   
    u8 i=0; 
	u32 tempreg=0;
    RCC_PeriphCLKInitTypeDef RCCI2S2_ClkInitSture;  
	
	for(i=0;i<(sizeof(I2S_PSC_TBL)/10);i++)//看看改采样率是否可以支持
	{
		if((samplerate/10)==I2S_PSC_TBL[i][0])break;
	}
    if(i==(sizeof(I2S_PSC_TBL)/10))return 1;//搜遍了也找不到
	
    RCCI2S2_ClkInitSture.PeriphClockSelection=RCC_PERIPHCLK_I2S;	//外设时钟源选择 
    RCCI2S2_ClkInitSture.PLLI2S.PLLI2SN=(u32)I2S_PSC_TBL[i][1];    	//设置PLLI2SN
    RCCI2S2_ClkInitSture.PLLI2S.PLLI2SR=(u32)I2S_PSC_TBL[i][2];    	//设置PLLI2SR
    HAL_RCCEx_PeriphCLKConfig(&RCCI2S2_ClkInitSture);             	//设置时钟
	
	RCC->CR|=1<<26;					//开启I2S时钟
	while((RCC->CR&1<<27)==0);		//等待I2S时钟开启成功. 
	tempreg=I2S_PSC_TBL[i][3]<<0;	//设置I2SDIV
	tempreg|=I2S_PSC_TBL[i][4]<<8;	//设置ODD位
	tempreg|=0<<9;					//使能MCKOE位,输出MCK
	SPI2->I2SPR=tempreg;			//设置I2SPR寄存器 
	return 0;
} 

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.PLLI2S.PLLI2SN = 224;
    PeriphClkInitStruct.PLLI2S.PLLI2SP = RCC_PLLP_DIV2;
    PeriphClkInitStruct.PLLI2S.PLLI2SR = 4;
    PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2;
    PeriphClkInitStruct.PLLI2SDivQ = 1;
    PeriphClkInitStruct.I2sClockSelection = RCC_I2SCLKSOURCE_PLLI2S;
    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
    {
      Error_Handler();
    }
*/
  //PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2|RCC_PERIPHCLK_I2S
   //                           |RCC_PERIPHCLK_CLK48;
  //PeriphClkInitStruct.PLLI2S.PLLI2SN = 224;//
  //PeriphClkInitStruct.PLLI2S.PLLI2SP = RCC_PLLP_DIV2;
  //PeriphClkInitStruct.PLLI2S.PLLI2SR = 4;//
  //PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2;
  //PeriphClkInitStruct.PLLI2SDivQ = 1;
  //PeriphClkInitStruct.I2sClockSelection = RCC_I2SCLKSOURCE_PLLI2S;
  I2S2_SampleRate_Set(48000);
  //PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  //PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLL;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
    /* I2S2 clock enable */
    __HAL_RCC_SPI2_CLK_ENABLE();

    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();
    /**I2S2 GPIO Configuration
    PB15     ------> I2S2_SD
    PD3     ------> I2S2_CK
    PB4     ------> I2S2_WS
    */
    GPIO_InitStruct.Pin = GPIO_PIN_15;
    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);

    GPIO_InitStruct.Pin = GPIO_PIN_3;
    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(GPIOD, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF7_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_PDATAALIGN_HALFWORD;
    hdma_spi2_tx.Init.Mode = DMA_CIRCULAR;
    hdma_spi2_tx.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_spi2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
	hdma_spi2_tx.Init.MemBurst         = DMA_MBURST_SINGLE;//
	hdma_spi2_tx.Init.PeriphBurst      = DMA_PBURST_SINGLE;//
	//HAL_DMA_DeInit(&hdma_spi2_tx);                       //先清除以前的设置
    if (HAL_DMA_Init(&hdma_spi2_tx) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(i2sHandle,hdmatx,hdma_spi2_tx);

    /* I2S2 interrupt Init */
	__HAL_DMA_DISABLE(&hdma_spi2_tx); 								//先关闭DMA 
	//HAL_DMAEx_MultiBufferStart_IT(&hdma_spi2_tx,(u32)Sin481,(u32)&hi2s2.Instance->DR,(u32)Sin48,96);//开启双缓冲
	//HAL_DMAEx_MultiBufferStart_IT(&hdma_spi2_tx, (uint32_t)sinTable2, (uint32_t)&hi2s2.Instance->DR, (uint32_t)(sinTable2 + 12), 11);	  
	//HAL_DMAEx_MultiBufferStart_IT(&hdma_spi2_tx, (uint32_t)audio_sin241, (uint32_t)&hi2s2.Instance->DR, (uint32_t)audio_sin241, 48*4);	  	   
	HAL_DMAEx_MultiBufferStart_IT(&hdma_spi2_tx, (uint32_t)Sin1648, (uint32_t)&hi2s2.Instance->DR, (uint32_t)(Sin1648 + 48), 48);	 

	bsp_DelayUS(10);												//10us延时,防止-O2优化出问题 	
	__HAL_DMA_ENABLE_IT(&hdma_spi2_tx,DMA_IT_TC); 					//开启传输完成中断
	__HAL_DMA_CLEAR_FLAG(&hdma_spi2_tx,DMA_FLAG_TCIF0_4); 			//清除DMA传输完成中断标志位
	HAL_NVIC_SetPriority(DMA1_Stream4_IRQn,0,0);					//DMA中断优先级
	HAL_NVIC_EnableIRQ(DMA1_Stream4_IRQn); 

  /* USER CODE BEGIN SPI2_MspInit 1 */


  /* USER CODE END SPI2_MspInit 1 */
  }
}

回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117546
QQ
发表于 2024-7-11 08:47:52 | 显示全部楼层
帮顶。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-14 07:49 , Processed in 0.050482 second(s), 24 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表