[STM32F7] STM32F767 DMA 传输错误问题

[复制链接]
 楼主| 旧年胶片 发表于 2025-7-14 10:53 | 显示全部楼层 |阅读模式
使用 STM32F767 的 DMA 进行 I2S 音频数据传输,但发现偶尔会出现数据丢失和音频爆音的问题。
发现
使用逻辑分析仪监测 I2S 和 DMA 信号,发现 DMA 传输完成中断有时会延迟
检查 DMA 配置,发现没有启用错误中断和传输完成中断
分析代码,发现 DMA 传输缓冲区管理不完善

需要修改软件
1启用 DMA 错误中断和传输完成中断
2优化 DMA 缓冲区管理,使用双缓冲技术
3增加 DMA 传输错误处理机制


// DMA和I2S初始化I2S_HandleTypeDef hi2s3;DMA_HandleTypeDef hdma_spi3_tx;DMA_HandleTypeDef hdma_spi3_rx;#define AUDIO_BUFFER_SIZE  1024uint16_t audio_tx_buffer[AUDIO_BUFFER_SIZE];uint16_t audio_rx_buffer[AUDIO_BUFFER_SIZE];void MX_DMA_Init(void){    // DMA控制器时钟使能    __HAL_RCC_DMA1_CLK_ENABLE();        // DMA中断配置    HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);    HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);    HAL_NVIC_SetPriority(DMA1_Stream7_IRQn, 0, 0);    HAL_NVIC_EnableIRQ(DMA1_Stream7_IRQn);}void MX_I2S3_Init(void){    hi2s3.Instance = SPI3;    hi2s3.Init.Mode = I2S_MODE_MASTER_TX;    hi2s3.Init.Standard = I2S_STANDARD_PHILIPS;    hi2s3.Init.DataFormat = I2S_DATAFORMAT_16B;    hi2s3.Init.MCLKOutput = I2S_MCLKOUTPUT_ENABLE;    hi2s3.Init.AudioFreq = I2S_AUDIOFREQ_48K;    hi2s3.Init.CPOL = I2S_CPOL_LOW;    hi2s3.Init.ClockSource = I2S_CLOCK_PLL;    hi2s3.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_ENABLE;        if (HAL_I2S_Init(&hi2s3) != HAL_OK)    {        Error_Handler();    }}// 启动I2S DMA传输void Start_I2S_DMA_Transfer(void){    // 初始化音频缓冲区    memset(audio_tx_buffer, 0, sizeof(audio_tx_buffer));    memset(audio_rx_buffer, 0, sizeof(audio_rx_buffer));        // 启动I2S DMA全双工传输    if (HAL_I2S_TransmitReceive_DMA(&hi2s3, (uint16_t*)audio_tx_buffer,                                      (uint16_t*)audio_rx_buffer, AUDIO_BUFFER_SIZE/2) != HAL_OK)    {        Error_Handler();    }}// DMA传输完成回调函数void HAL_I2S_TxRxCpltCallback(I2S_HandleTypeDef *hi2s){    if(hi2s->Instance == SPI3)    {        // 处理接收到的音频数据        Process_Audio_Data(audio_rx_buffer, AUDIO_BUFFER_SIZE/2);                // 准备下一次发送的音频数据        Prepare_Audio_Data(audio_tx_buffer, AUDIO_BUFFER_SIZE/2);    }}// DMA传输错误回调函数void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s){    if(hi2s->Instance == SPI3)    {        // 记录错误信息        printf("I2S DMA Error!\r\n");                // 停止I2S DMA传输        HAL_I2S_DMAStop(&hi2s3);                // 重新启动I2S DMA传输        Start_I2S_DMA_Transfer();    }}
小小蚂蚁举千斤 发表于 2025-7-28 23:26 | 显示全部楼层
DMA 传输错误问题看一下啊
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

29

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

8

主题

29

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部