[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 */
}
}