我使用的是 STM32F446 Nucleo 开发板和 STM32CubeIDE,编写了一段回环测试代码:通过 I2S 接口接收 PCM1808PWR(ADC 芯片)的数据,再传输到 MCU 内部的 DAC。
MCU 配置为 I2S 从模式,外部时钟输入至 I2S_CKIN 引脚,正常运行时一切正常。
当我 “Pause DMA” 再 “Resume DMA” 后,MCU 的 I2S 接口无法与 PCM1808PWR 同步。
具体现象:
偶尔能恢复同步;但大多数情况下,两者无法同步,导致传输的数据错乱。
参考手册(HAL_I2S_Receive_DMA 相关章节)说明:"The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization between Master and Slave(example: audio streaming)."
我认为DMA 暂停期间,MCU 能保持与 PCM1808PWR 的同步状态;至少在 DMA 恢复时,MCU 能重新与 PCM1808PWR 同步。
// in main().c
****
HAL_TIM_Base_Start(&htim2) ; // 48kHz timer for DAC start
// Start DAC
if (HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *) DAC_In, (uint32_t) BLK_SZ*2, DAC_ALIGN_12B_R) != HAL_OK) {
Error_Handler() ;
}
// Start I2S as Slave Receive @48kHz, 24bit in 32bit frame, stereo
if (((I2S_HandleTypeDef *)&hi2s2)->State == HAL_I2S_STATE_READY) {
if (HAL_I2S_Receive_DMA(&hi2s2, (uint16_t*) I2S_ADC_data, (uint16_t) BLK_SZ_IQ_DBL) != HAL_OK) {
// 3rd parameter Size is number of 16bit data in ADC_data even in format 24bit data in 32bit frame (=16bit*2)
Error_Handler();
}
}
HAL_Delay(2000) ;
// above code works well.
while (1) {
if (HAL_I2S_DMAPause(&hi2s2) != HAL_OK) {
Error_Handler();
}
HAL_Delay(5000) ;
if (HAL_I2S_DMAResume(&hi2s2) != HAL_OK) {
Error_Handler();
}
// There is no ERROR, but data is not correct in most of time. (sometimes, it sync and works.)
HAL_Delay(5000) ;
}
|
|