Cherryusb UAC例程对接STM32 SAI播放音乐和录音(上)=>SAI+TX+RX+DMA的配置与音频回环测试

发布于:2025-08-15 ⋅ 阅读:(11) ⋅ 点赞:(0)

0. 概述

  • 文本目标基于Cherryusb官方例程audio_v1_mic_speaker_multichan_template.c,底层对接STM32的SAI驱动wm8978音频模块, 实现录音和播放。
  • SAI的配置比较复杂, WM8978的配置更为复杂, 需要注意的点较多. 我们需要把这个过程进行分解,一步一步来。
  • 为了达到这个目标,首先需要在STM32上调通SAI+DMA的收发测试, 比如输出单音信号(do 293Hz, so 440Hz), 然后将SD_A与SD_B短接, 将音频回环到输入, 通过DMA采集后打印出来。通过这种方式可以不依赖于任何设备(逻辑分析仪, 音频模块), 测试SAI的基本收发功能。类似的SPI/UART也可以这么测试。
  • 当然,我们手头有几个不需要配置, 拿来即用, 直接可以接收标准i2s信号的音频模块(PCM1808 ADC, PCM5102A DAC), 可以方便的用来测试SAI的输入输出功能。这样可以通过听音和录音来测试。
  • 逻辑分析仪抓一下波形,可以核对数据收发是否正确,MCLK/BCLK/FS频率是否正确
  • 我们的开发板是STM32H750-ARTPI,环境是rt-thread+cherryusb

在这里插入图片描述

1. SAI+DMA的CubeMX配置

  • STM32H750-ARTPI的SAI接口通过P1排针引出, 使用的是SAI2

  • 开启SAI2,配置A通道为TX(带MCLK输出),B通道为同步RX。所谓同步的意思是B通道自己不产生时钟, 而是来自A通道的时钟, 与A通道同步。

  • 勾选I2S/PCM模式
    在这里插入图片描述

  • 配置A通道,每一项要仔细检查。A通道为异步,因为它是要输出时钟源的,它是发起者,不需要与其它时钟同步。

  • 基本参数是:16kHz采样率,2个slot(左右声道),每个slot 16bits。Mclk不要分频,不要过采样。

  • 对于这样一个配置,FS=16kHz, MCLK=256FS=4.096MHz,BCLK=2x16x16kHz=512kHz
    在这里插入图片描述

  • 配置B通道,每一项要仔细检查。B通道为同步,它采用与A通道相同的时钟,因此是同步的。

  • B通道的参数配置简单一些,与A通道基本相同
    在这里插入图片描述

  • 配置A通道的DMA,有了之前的经验,很容易配置这里的参数。因为A通道为TX,所以Burst设置在Memory侧。
    在这里插入图片描述

  • 配置B通道的DMA,有了之前的经验,很容易配置这里的参数。因为B通道为RX,所以Burst设置在Peripheral侧。
    在这里插入图片描述

  • SAI2的全局中断勾选上,不清楚是否需要,后面通过trace分析一下。(大部分外设使用DMA的时候,只使用DMA的中断,不使用外设的中断,但也有少数的情况。比如STM32H7 ADC需要通过ADC自身中断服务函数清楚过载中断标志)
    在这里插入图片描述

  • 引脚配置,与ART-PI保持一致
    在这里插入图片描述

  • SAI2时钟的配置,这里需要比较精细。目标4.096MHz
    在这里插入图片描述

2. main.c程序关键点说明

  • 先用293Hz (D调的do) 的标准正弦波测试
  • 我们先创建sin_table数组作为音源,由于我们定义的sine_table是uint16_t类型,因此满量程范围是0-65535范围, 幅度取0.95FullScale
  • 因为有左右声道,所以每个点需要重复两次, 填入dac_buffer
#define TONE_FREQ (293)
#define SIN_TABLE_SIZE (16000 / TONE_FREQ)  /*16kHz/293Hz=55 pts*/

// Add before ADC_DAC_DMA_Init function
static void generate_sin_table(void)
{
  for (int i = 0; i < SIN_TABLE_SIZE; i++)
  {
      float angle = 2 * M_PI * i / SIN_TABLE_SIZE;
      sin_table[i] = (uint16_t)((sin(angle)*0.95 + 1.0f) *32767.5f); // 16bits, 0-65535 range
  }
}

static void fill_dac_buffer(void)
{
  for (int i = 0; i < SIN_TABLE_SIZE; i++)
  {
      dac_buffer[2*i] = sin_table[i];
      dac_buffer[2*i + 1] = sin_table[i]; /*repeat填充*/
  }
}
  • SAI2的初始化
/**
* @brief SAI2 Initialization Function
* @param None
* @retval None
*/
static void MX_SAI2_Init(void)
{

  /* USER CODE BEGIN SAI2_Init 0 */

  /* USER CODE END SAI2_Init 0 */

  /* USER CODE BEGIN SAI2_Init 1 */

  /* USER CODE END SAI2_Init 1 */
  hsai_BlockA2.Instance = SAI2_Block_A;
  hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
  hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS; /*主机异步模式*/
  hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
  hsai_BlockA2.Init.NoDivider = SAI_MCK_OVERSAMPLING_DISABLE; /*MCK不要分频*/
  hsai_BlockA2.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE; /*MCK不要过采样*/ 
  hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;
  hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_16K;
  hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockA2, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }
  hsai_BlockB2.Instance = SAI2_Block_B;
  hsai_BlockB2.Init.AudioMode = SAI_MODESLAVE_RX;
  hsai_BlockB2.Init.Synchro = SAI_SYNCHRONOUS; /*从机同步模式*/
  hsai_BlockB2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
  hsai_BlockB2.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
  hsai_BlockB2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;
  hsai_BlockB2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockB2.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockB2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockB2, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SAI2_Init 2 */

  /* USER CODE END SAI2_Init 2 */

}
  • 初始化函数
  • 初始化SAI和DMA,生成sin_table数组,填充dac_buffer数组
  • 以DMA的方式启动SAI2_A和SAI2_B通道,即录音和播放同时进行
  • 将SD_A与SD_B引脚短接起来,形成音频回环。程序设计的是,Rx DMA接收一轮后就停止工作,然后打印数据,将数据导入excel表绘图
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  PeriphCommonClock_Config();

  mpu_init();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_UART4_Init();
  MX_SAI2_Init();

  generate_sin_table();
  fill_dac_buffer();

  HAL_SAI_Receive_DMA(&hsai_BlockB2, (uint8_t *)adc_buffer, ADC_BUFFER_SIZE * 2);  
  HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)dac_buffer, SIN_TABLE_SIZE * 2);

  printf("hello world!\n");
  while (1)
  {
    if(RxCplt)
    {
      RxCplt = 0;
      for(int i=0;i< ADC_BUFFER_SIZE*2; i++)
      {
        printf("adc_buffer[%d] = %d\n", i, adc_buffer[i]);
      }
    }
  }
}
  • TX和RX的回调函数
  • Rx DMA接收一轮后就停止工作
void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_A)
  {
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_11);
    TxCplt = 1;
  }
}


void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_A)
  {
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_11);
  }
}

void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_B)
  {
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_11);
    RxCplt = 1;
    HAL_SAI_DMAStop(&hsai_BlockB2);    
  }
}


void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_B)
  {
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_11);
  }
}

3. 测试效果

  • 293Hz正弦波,逻辑分析仪抓到的I2S波形。可见一个完整的293Hz数据周期是3.387ms,基本符合预期(1/293Hz=3.413ms)

  • 我们可以看到左右声道的数据是一致的
    在这里插入图片描述

  • FS信号的频率16kHz
    在这里插入图片描述

  • BCLK信号的频率512kHz
    在这里插入图片描述

  • MCLK信号的频率4.096MHz
    在这里插入图片描述

  • 将音频回环的数据(也就是录音的数据)通过串口发送出来,并plot,可见是一个完美的正弦波
    在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • PCM5102A DAC播放293Hz频率ok(对应D调的do音)
  • PCM5102A DAC播放440Hz频率ok(对应D调的so音)

4. 总结

  • SAI + DMA的播放音乐的方案,是最正宗,最标准的方案。音质最好。
  • 这种方案,SAI的配置是难点。通过CubeMX配置,仔细检查每一项。尤其是MCLK的生成,典型MCLK=256FS。
  • 先播放标准正弦波,通过逻辑分析仪抓波形,确认MCLK/FS/BCLK/DATA都符合预期
  • 然后通过听音测试。推荐使用不要配置的I2S音频模块,比如PCM5102A模块,方便测试。

5. 附录1:sai_dma.c (移植到rt-thread中的完整代码)

#include <drv_common.h>

#define USB_NOCACHE_RAM_SECTION __attribute__((section(".noncacheable")))
#define USB_MEM_ALIGNX __attribute__((aligned(32)))

SAI_HandleTypeDef hsai_BlockA2;
SAI_HandleTypeDef hsai_BlockB2;
DMA_HandleTypeDef hdma_sai2_a;
DMA_HandleTypeDef hdma_sai2_b;

static rt_sem_t adc_sem = RT_NULL;
static rt_thread_t adc_thread = RT_NULL;

#define TONE_FREQ (293)
#define SIN_TABLE_SIZE (16000 / TONE_FREQ)  /*16kHz/293Hz=55 pts*/
#define ADC_BUFFER_SIZE 1024
#define ADC_BIG_BUFFER_SIZE (ADC_BUFFER_SIZE * 16)
#define M_PI 3.14159265358979323846

uint16_t sin_table[SIN_TABLE_SIZE];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint16_t dac_buffer[SIN_TABLE_SIZE * 2]; // Double buffer for DMA
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint16_t adc_buffer[ADC_BUFFER_SIZE * 2]; // Double buffer for DMA
uint16_t adc_big_buffer[ADC_BIG_BUFFER_SIZE];
volatile uint16_t adc_buffer_index = 0;

static void MX_SAI2_Init(void);
static void MX_DMA_Init(void);


// Add before ADC_DAC_DMA_Init function
static void generate_sin_table(void)
{
  for (int i = 0; i < SIN_TABLE_SIZE; i++)
  {
      float angle = 2 * M_PI * i / SIN_TABLE_SIZE;
      sin_table[i] = (uint16_t)((sin(angle)*0.95 + 1.0f) *32767.5f); // 16bits, 0-65535 range
  }
}

static void fill_dac_buffer(void)
{
  for (int i = 0; i < SIN_TABLE_SIZE; i++)
  {
      dac_buffer[2*i] = sin_table[i];
      dac_buffer[2*i + 1] = sin_table[i];
  }
}

// Add after DMA interrupt handlers
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_B)
  {
      rt_enter_critical();
      Process first half of ADC buffer
      for (int i = 0; i < ADC_BUFFER_SIZE; i++)
      {
          adc_big_buffer[adc_buffer_index++] = adc_buffer[i];
          if (adc_buffer_index >= ADC_BIG_BUFFER_SIZE)
          {
              adc_buffer_index = 0;
              rt_sem_release(adc_sem); // 释放信号量通知线程
          }
      }
      rt_exit_critical();
  }
}

void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_B)
  {
      rt_enter_critical();
      Process second half of ADC buffer
      for (int i = ADC_BUFFER_SIZE; i < ADC_BUFFER_SIZE * 2; i++)
      {
          adc_big_buffer[adc_buffer_index++] = adc_buffer[i];
          if (adc_buffer_index >= ADC_BIG_BUFFER_SIZE)
          {
              adc_buffer_index = 0;
              rt_sem_release(adc_sem); // 释放信号量通知线程
          }
      }
      rt_exit_critical();
  }
}

void HAL_SAI_TxCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_A)
  {
  }
}


void HAL_SAI_TxHalfCpltCallback(SAI_HandleTypeDef *hsai)
{
  if(hsai->Instance == SAI2_Block_A)
  {
  }
}

static void adc_data_thread_entry(void *parameter)
{
  while (1)
  {
      if (rt_sem_take(adc_sem, RT_WAITING_FOREVER) == RT_EOK)
      {
          rt_enter_critical();
          rt_kprintf("ADC Big Buffer Full! Printing first 1024 samples:\n");
          for (int i = 0; i < 1024; i++)
          {
              rt_kprintf("%d ", adc_big_buffer[i]);
              if ((i + 1) % 16 == 0) rt_kprintf("\n");
          }
          rt_kprintf("\nEnd of 1024 samples\n");
          rt_exit_critical();
      }
  }
}


int SAI_DMA_Init(void)
{
  MX_DMA_Init();
  MX_SAI2_Init();


  generate_sin_table();
  fill_dac_buffer();

  adc_sem = rt_sem_create("adc_sem", 0, RT_IPC_FLAG_FIFO);
  adc_thread = rt_thread_create("adc_thread", 
                              adc_data_thread_entry, 
                              RT_NULL,
                              4096,
                              20,
                              10);
  rt_thread_startup(adc_thread);
  
  HAL_SAI_Receive_DMA(&hsai_BlockB2, (uint8_t *)adc_buffer, ADC_BUFFER_SIZE * 2);  
  HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)dac_buffer, SIN_TABLE_SIZE * 2);

  return 0;
}

INIT_APP_EXPORT(SAI_DMA_Init);


/**
* @brief SAI2 Initialization Function
* @param None
* @retval None
*/
static void MX_SAI2_Init(void)
{

  /* USER CODE BEGIN SAI2_Init 0 */

  /* USER CODE END SAI2_Init 0 */

  /* USER CODE BEGIN SAI2_Init 1 */

  /* USER CODE END SAI2_Init 1 */
  hsai_BlockA2.Instance = SAI2_Block_A;
  hsai_BlockA2.Init.AudioMode = SAI_MODEMASTER_TX;
  hsai_BlockA2.Init.Synchro = SAI_ASYNCHRONOUS; /*主机异步模式*/
  hsai_BlockA2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
  hsai_BlockA2.Init.NoDivider = SAI_MCK_OVERSAMPLING_DISABLE; /*MCK不要分频*/
  hsai_BlockA2.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE; /*MCK不要过采样*/ 
  hsai_BlockA2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;
  hsai_BlockA2.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_16K;
  hsai_BlockA2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockA2.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA2.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockA2, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }
  hsai_BlockB2.Instance = SAI2_Block_B;
  hsai_BlockB2.Init.AudioMode = SAI_MODESLAVE_RX;
  hsai_BlockB2.Init.Synchro = SAI_SYNCHRONOUS; /*从机同步模式*/
  hsai_BlockB2.Init.OutputDrive = SAI_OUTPUTDRIVE_ENABLE;
  hsai_BlockB2.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
  hsai_BlockB2.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_HF;
  hsai_BlockB2.Init.SynchroExt = SAI_SYNCEXT_DISABLE;
  hsai_BlockB2.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockB2.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockB2.Init.TriState = SAI_OUTPUT_NOTRELEASED;
  if (HAL_SAI_InitProtocol(&hsai_BlockB2, SAI_I2S_STANDARD, SAI_PROTOCOL_DATASIZE_16BIT, 2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SAI2_Init 2 */

  /* USER CODE END SAI2_Init 2 */

}

static uint32_t SAI2_client =0;

void HAL_SAI_MspInit(SAI_HandleTypeDef* hsai)
{

  GPIO_InitTypeDef GPIO_InitStruct;
/* SAI2 */
    if(hsai->Instance==SAI2_Block_A)
    {
    /* Peripheral clock enable */
    if (SAI2_client == 0)
    {
      __HAL_RCC_SAI2_CLK_ENABLE();

    /* Peripheral interrupt init*/
    HAL_NVIC_SetPriority(SAI2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(SAI2_IRQn);
    }
    SAI2_client ++;

    /**SAI2_A_Block_A GPIO Configuration
   PI6     ------> SAI2_SD_A
    PI5     ------> SAI2_SCK_A
    PI4     ------> SAI2_MCLK_A
    PI7     ------> SAI2_FS_A
    */
    GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
    HAL_GPIO_Init(GPIOI, &GPIO_InitStruct);

    /* Peripheral DMA init*/
    hdma_sai2_a.Instance = DMA1_Stream2;
    hdma_sai2_a.Init.Request = DMA_REQUEST_SAI2_A;
    hdma_sai2_a.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_sai2_a.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sai2_a.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sai2_a.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_sai2_a.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_sai2_a.Init.Mode = DMA_CIRCULAR;
    hdma_sai2_a.Init.Priority = DMA_PRIORITY_LOW;
    hdma_sai2_a.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_sai2_a.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
    hdma_sai2_a.Init.MemBurst = DMA_MBURST_INC4;
    hdma_sai2_a.Init.PeriphBurst = DMA_PBURST_SINGLE;
    if (HAL_DMA_Init(&hdma_sai2_a) != HAL_OK)
    {
      Error_Handler();
    }

    /* Several peripheral DMA handle pointers point to the same DMA handle.
    Be aware that there is only one channel to perform all the requested DMAs. */
    __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_a);

    __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_a);

    }
    if(hsai->Instance==SAI2_Block_B)
    {
      /* Peripheral clock enable */
      if (SAI2_client == 0)
      {
      __HAL_RCC_SAI2_CLK_ENABLE();

      /* Peripheral interrupt init*/
      HAL_NVIC_SetPriority(SAI2_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(SAI2_IRQn);
      }
    SAI2_client ++;

    /**SAI2_B_Block_B GPIO Configuration
   PG10     ------> SAI2_SD_B
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Alternate = GPIO_AF10_SAI2;
    HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);

      /* Peripheral DMA init*/

    hdma_sai2_b.Instance = DMA1_Stream3;
    hdma_sai2_b.Init.Request = DMA_REQUEST_SAI2_B;
    hdma_sai2_b.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_sai2_b.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_sai2_b.Init.MemInc = DMA_MINC_ENABLE;
    hdma_sai2_b.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_sai2_b.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_sai2_b.Init.Mode = DMA_CIRCULAR;
    hdma_sai2_b.Init.Priority = DMA_PRIORITY_LOW;
    hdma_sai2_b.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
    hdma_sai2_b.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
    hdma_sai2_b.Init.MemBurst = DMA_MBURST_SINGLE;
    hdma_sai2_b.Init.PeriphBurst = DMA_PBURST_INC4;
    if (HAL_DMA_Init(&hdma_sai2_b) != HAL_OK)
    {
      Error_Handler();
    }

    /* Several peripheral DMA handle pointers point to the same DMA handle.
    Be aware that there is only one channel to perform all the requested DMAs. */
    __HAL_LINKDMA(hsai,hdmarx,hdma_sai2_b);
    __HAL_LINKDMA(hsai,hdmatx,hdma_sai2_b);
    }
}

void HAL_SAI_MspDeInit(SAI_HandleTypeDef* hsai)
{
/* SAI2 */
    if(hsai->Instance==SAI2_Block_A)
    {
    SAI2_client --;
    if (SAI2_client == 0)
      {
      /* Peripheral clock disable */
      __HAL_RCC_SAI2_CLK_DISABLE();
      /* SAI2 interrupt DeInit */
      HAL_NVIC_DisableIRQ(SAI2_IRQn);
      }

    /**SAI2_A_Block_A GPIO Configuration
   PI6     ------> SAI2_SD_A
    PI5     ------> SAI2_SCK_A
    PI4     ------> SAI2_MCLK_A
    PI7     ------> SAI2_FS_A
    */
    HAL_GPIO_DeInit(GPIOI, GPIO_PIN_6|GPIO_PIN_5|GPIO_PIN_4|GPIO_PIN_7);

    /* SAI2 DMA Deinit */
    HAL_DMA_DeInit(hsai->hdmarx);
    HAL_DMA_DeInit(hsai->hdmatx);
    }
    if(hsai->Instance==SAI2_Block_B)
    {
    SAI2_client --;
      if (SAI2_client == 0)
      {
      /* Peripheral clock disable */
      __HAL_RCC_SAI2_CLK_DISABLE();
    /* SAI2 interrupt DeInit */
      HAL_NVIC_DisableIRQ(SAI2_IRQn);
      }

    /**SAI2_B_Block_B GPIO Configuration
   PG10     ------> SAI2_SD_B
    */
    HAL_GPIO_DeInit(GPIOG, GPIO_PIN_10);

    /* SAI2 DMA Deinit */
    HAL_DMA_DeInit(hsai->hdmarx);
    HAL_DMA_DeInit(hsai->hdmatx);
    }
}

/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Stream2_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
  /* DMA1_Stream3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Stream3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Stream3_IRQn);

}

/**
* @brief This function handles DMA1 stream2 global interrupt.
*/
void DMA1_Stream2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */

  /* USER CODE END DMA1_Stream2_IRQn 0 */
  rt_base_t level = rt_hw_interrupt_disable();
  HAL_DMA_IRQHandler(&hdma_sai2_a);
  rt_hw_interrupt_enable(level);
  /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */

  /* USER CODE END DMA1_Stream2_IRQn 1 */
}

/**
 * @brief This function handles DMA1 stream3 global interrupt.
 */
void DMA1_Stream3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */

  /* USER CODE END DMA1_Stream3_IRQn 0 */
  rt_base_t level = rt_hw_interrupt_disable();
  HAL_DMA_IRQHandler(&hdma_sai2_b);
  rt_hw_interrupt_enable(level);
  /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */

  /* USER CODE END DMA1_Stream3_IRQn 1 */
}

/**
* @brief This function handles SAI2 global interrupt.
*/
void SAI2_IRQHandler(void)
{
  /* USER CODE BEGIN SAI2_IRQn 0 */

  /* USER CODE END SAI2_IRQn 0 */
  HAL_SAI_IRQHandler(&hsai_BlockA2);
  HAL_SAI_IRQHandler(&hsai_BlockB2);
  /* USER CODE BEGIN SAI2_IRQn 1 */

  /* USER CODE END SAI2_IRQn 1 */
}

6. 附录2: CubeMX_Config.ioc

#MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_1
ADC1.ContinuousConvMode=DISABLE
ADC1.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR
ADC1.ExternalTrigConv=ADC_EXTERNALTRIG_T2_TRGO
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,OffsetNumber-0\#ChannelRegularConversion,OffsetSignedSaturation-0\#ChannelRegularConversion,NbrOfConversionFlag,master,ContinuousConvMode,ExternalTrigConv,ConversionDataManagement
ADC1.NbrOfConversionFlag=1
ADC1.OffsetNumber-0\#ChannelRegularConversion=ADC_OFFSET_NONE
ADC1.OffsetSignedSaturation-0\#ChannelRegularConversion=DISABLE
ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_8CYCLES_5
ADC1.master=1
CAD.formats=
CAD.pinconfig=
CAD.provider=
CORTEX_M7.CPU_DCache=Disabled
CORTEX_M7.CPU_ICache=Disabled
CORTEX_M7.IPParameters=CPU_ICache,CPU_DCache
Dma.ADC1.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.0.EventEnable=DISABLE
Dma.ADC1.0.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.ADC1.0.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL
Dma.ADC1.0.Instance=DMA1_Stream0
Dma.ADC1.0.MemBurst=DMA_MBURST_SINGLE
Dma.ADC1.0.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.ADC1.0.MemInc=DMA_MINC_ENABLE
Dma.ADC1.0.Mode=DMA_CIRCULAR
Dma.ADC1.0.PeriphBurst=DMA_PBURST_INC4
Dma.ADC1.0.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.ADC1.0.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.0.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.ADC1.0.Priority=DMA_PRIORITY_LOW
Dma.ADC1.0.RequestNumber=1
Dma.ADC1.0.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.ADC1.0.SignalID=NONE
Dma.ADC1.0.SyncEnable=DISABLE
Dma.ADC1.0.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.ADC1.0.SyncRequestNumber=1
Dma.ADC1.0.SyncSignalID=NONE
Dma.Request0=ADC1
Dma.Request1=TIM5_CH3
Dma.Request2=SAI2_A
Dma.Request3=SAI2_B
Dma.RequestsNb=4
Dma.SAI2_A.2.Direction=DMA_MEMORY_TO_PERIPH
Dma.SAI2_A.2.EventEnable=DISABLE
Dma.SAI2_A.2.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SAI2_A.2.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL
Dma.SAI2_A.2.Instance=DMA1_Stream2
Dma.SAI2_A.2.MemBurst=DMA_MBURST_INC4
Dma.SAI2_A.2.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.SAI2_A.2.MemInc=DMA_MINC_ENABLE
Dma.SAI2_A.2.Mode=DMA_CIRCULAR
Dma.SAI2_A.2.PeriphBurst=DMA_PBURST_SINGLE
Dma.SAI2_A.2.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.SAI2_A.2.PeriphInc=DMA_PINC_DISABLE
Dma.SAI2_A.2.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SAI2_A.2.Priority=DMA_PRIORITY_LOW
Dma.SAI2_A.2.RequestNumber=1
Dma.SAI2_A.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SAI2_A.2.SignalID=NONE
Dma.SAI2_A.2.SyncEnable=DISABLE
Dma.SAI2_A.2.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SAI2_A.2.SyncRequestNumber=1
Dma.SAI2_A.2.SyncSignalID=NONE
Dma.SAI2_B.3.Direction=DMA_PERIPH_TO_MEMORY
Dma.SAI2_B.3.EventEnable=DISABLE
Dma.SAI2_B.3.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.SAI2_B.3.FIFOThreshold=DMA_FIFO_THRESHOLD_HALFFULL
Dma.SAI2_B.3.Instance=DMA1_Stream3
Dma.SAI2_B.3.MemBurst=DMA_MBURST_SINGLE
Dma.SAI2_B.3.MemDataAlignment=DMA_MDATAALIGN_HALFWORD
Dma.SAI2_B.3.MemInc=DMA_MINC_ENABLE
Dma.SAI2_B.3.Mode=DMA_CIRCULAR
Dma.SAI2_B.3.PeriphBurst=DMA_PBURST_INC4
Dma.SAI2_B.3.PeriphDataAlignment=DMA_PDATAALIGN_HALFWORD
Dma.SAI2_B.3.PeriphInc=DMA_PINC_DISABLE
Dma.SAI2_B.3.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.SAI2_B.3.Priority=DMA_PRIORITY_LOW
Dma.SAI2_B.3.RequestNumber=1
Dma.SAI2_B.3.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.SAI2_B.3.SignalID=NONE
Dma.SAI2_B.3.SyncEnable=DISABLE
Dma.SAI2_B.3.SyncPolarity=HAL_DMAMUX_SYNC_NO_EVENT
Dma.SAI2_B.3.SyncRequestNumber=1
Dma.SAI2_B.3.SyncSignalID=NONE
Dma.TIM5_CH3.1.Direction=DMA_MEMORY_TO_PERIPH
Dma.TIM5_CH3.1.EventEnable=DISABLE
Dma.TIM5_CH3.1.FIFOMode=DMA_FIFOMODE_ENABLE
Dma.TIM5_CH3.1.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL
Dma.TIM5_CH3.1.Instance=DMA1_Stream1
Dma.TIM5_CH3.1.MemBurst=DMA_MBURST_INC4
Dma.TIM5_CH3.1.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.TIM5_CH3.1.MemInc=DMA_MINC_ENABLE
Dma.TIM5_CH3.1.Mode=DMA_CIRCULAR
Dma.TIM5_CH3.1.PeriphBurst=DMA_PBURST_SINGLE
Dma.TIM5_CH3.1.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.TIM5_CH3.1.PeriphInc=DMA_PINC_DISABLE
Dma.TIM5_CH3.1.Polarity=HAL_DMAMUX_REQ_GEN_RISING
Dma.TIM5_CH3.1.Priority=DMA_PRIORITY_LOW
Dma.TIM5_CH3.1.RequestNumber=1
Dma.TIM5_CH3.1.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority,FIFOMode,FIFOThreshold,MemBurst,PeriphBurst,SignalID,Polarity,RequestNumber,SyncSignalID,SyncPolarity,SyncEnable,EventEnable,SyncRequestNumber
Dma.TIM5_CH3.1.SignalID=NONE
Dma.TIM5_CH3.1.SyncEnable=ENABLE
Dma.TIM5_CH3.1.SyncPolarity=HAL_DMAMUX_SYNC_RISING
Dma.TIM5_CH3.1.SyncRequestNumber=1
Dma.TIM5_CH3.1.SyncSignalID=HAL_DMAMUX1_SYNC_TIM12_TRGO
File.Version=6
GPIO.groupedBy=Group By Peripherals
I2C4.IPParameters=Timing
I2C4.Timing=0x307075B1
KeepUserPlacement=false
MMTAppRegionsCount=0
MMTConfigApplied=false
Mcu.CPN=STM32H750XBH6
Mcu.Family=STM32H7
Mcu.IP0=ADC1
Mcu.IP1=CORTEX_M7
Mcu.IP10=SAI2
Mcu.IP11=SDMMC1
Mcu.IP12=SDMMC2
Mcu.IP13=SPI2
Mcu.IP14=SPI4
Mcu.IP15=SYS
Mcu.IP16=TIM2
Mcu.IP17=TIM5
Mcu.IP18=TIM12
Mcu.IP19=UART4
Mcu.IP2=DMA
Mcu.IP20=USART3
Mcu.IP21=USB_OTG_FS
Mcu.IP3=FMC
Mcu.IP4=I2C4
Mcu.IP5=IWDG1
Mcu.IP6=LTDC
Mcu.IP7=MEMORYMAP
Mcu.IP8=NVIC
Mcu.IP9=RCC
Mcu.IPNb=22
Mcu.Name=STM32H750XBHx
Mcu.Package=TFBGA240
Mcu.Pin0=PI6
Mcu.Pin1=PI5
Mcu.Pin10=PK4
Mcu.Pin100=PJ3
Mcu.Pin101=PJ4
Mcu.Pin102=PG1
Mcu.Pin103=PE7
Mcu.Pin104=PE14
Mcu.Pin105=PB14
Mcu.Pin106=PD8
Mcu.Pin107=VP_IWDG1_VS_IWDG
Mcu.Pin108=VP_SAI2_VP_$IpInstance_SAIA_SAI_BASIC
Mcu.Pin109=VP_SAI2_VP_$IpInstance_SAIB_SAI_BASIC
Mcu.Pin11=PG11
Mcu.Pin110=VP_SYS_VS_Systick
Mcu.Pin111=VP_TIM2_VS_ClockSourceINT
Mcu.Pin112=VP_TIM5_VS_ClockSourceINT
Mcu.Pin113=VP_TIM12_VS_ClockSourceINT
Mcu.Pin114=VP_MEMORYMAP_VS_MEMORYMAP
Mcu.Pin12=PJ15
Mcu.Pin13=PD6
Mcu.Pin14=PC11
Mcu.Pin15=PI2
Mcu.Pin16=PE2
Mcu.Pin17=PE0
Mcu.Pin18=PB3 (JTDO/TRACESWO)
Mcu.Pin19=PK6
Mcu.Pin2=PI4
Mcu.Pin20=PK3
Mcu.Pin21=PD7
Mcu.Pin22=PC12
Mcu.Pin23=PI3
Mcu.Pin24=PE5
Mcu.Pin25=PG15
Mcu.Pin26=PK7
Mcu.Pin27=PG14
Mcu.Pin28=PJ14
Mcu.Pin29=PJ12
Mcu.Pin3=PK5
Mcu.Pin30=PD2
Mcu.Pin31=PD0
Mcu.Pin32=PI9
Mcu.Pin33=PE6
Mcu.Pin34=PJ13
Mcu.Pin35=PD1
Mcu.Pin36=PC8
Mcu.Pin37=PC9
Mcu.Pin38=PA12
Mcu.Pin39=PA11
Mcu.Pin4=PG10
Mcu.Pin40=PG8
Mcu.Pin41=PF2
Mcu.Pin42=PF1
Mcu.Pin43=PF0
Mcu.Pin44=PG5
Mcu.Pin45=PI12
Mcu.Pin46=PI13
Mcu.Pin47=PI14
Mcu.Pin48=PF3
Mcu.Pin49=PG4
Mcu.Pin5=PC10
Mcu.Pin50=PG2
Mcu.Pin51=PK2
Mcu.Pin52=PH1-OSC_OUT (PH1)
Mcu.Pin53=PH0-OSC_IN (PH0)
Mcu.Pin54=PF5
Mcu.Pin55=PF4
Mcu.Pin56=PK0
Mcu.Pin57=PK1
Mcu.Pin58=PJ11
Mcu.Pin59=PJ10
Mcu.Pin6=PI1
Mcu.Pin60=PC2
Mcu.Pin61=PC3
Mcu.Pin62=PJ9
Mcu.Pin63=PA2
Mcu.Pin64=PA0
Mcu.Pin65=PJ0
Mcu.Pin66=PE10
Mcu.Pin67=PJ8
Mcu.Pin68=PJ7
Mcu.Pin69=PJ6
Mcu.Pin7=PI7
Mcu.Pin70=PH5
Mcu.Pin71=PI15
Mcu.Pin72=PJ1
Mcu.Pin73=PF13
Mcu.Pin74=PF14
Mcu.Pin75=PE9
Mcu.Pin76=PE11
Mcu.Pin77=PB10
Mcu.Pin78=PB11
Mcu.Pin79=PH11
Mcu.Pin8=PE1
Mcu.Pin80=PD15
Mcu.Pin81=PD14
Mcu.Pin82=PF12
Mcu.Pin83=PF15
Mcu.Pin84=PE12
Mcu.Pin85=PE15
Mcu.Pin86=PJ5
Mcu.Pin87=PH12
Mcu.Pin88=PD11
Mcu.Pin89=PD12
Mcu.Pin9=PB4 (NJTRST)
Mcu.Pin90=PA1_C
Mcu.Pin91=PA5
Mcu.Pin92=PJ2
Mcu.Pin93=PF11
Mcu.Pin94=PG0
Mcu.Pin95=PE8
Mcu.Pin96=PE13
Mcu.Pin97=PB15
Mcu.Pin98=PD10
Mcu.Pin99=PD9
Mcu.PinsNb=115
Mcu.ThirdPartyNb=0
Mcu.UserConstants=
Mcu.UserName=STM32H750XBHx
MxCube.Version=6.14.1
MxDb.Version=DB.6.0.141
NVIC.ADC_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DMA1_Stream0_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Stream1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Stream2_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Stream3_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMAMUX1_OVR_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.ForceEnableDMAVector=true
NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.MemoryManagement_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.OTG_FS_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SAI2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SDMMC1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SDMMC2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SPI2_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM5_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA0.Locked=true
PA0.Mode=Asynchronous
PA0.Signal=UART4_TX
PA11.GPIOParameters=GPIO_Speed
PA11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PA11.Mode=Device_Only
PA11.Signal=USB_OTG_FS_DM
PA12.GPIOParameters=GPIO_Speed
PA12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PA12.Mode=Device_Only
PA12.Signal=USB_OTG_FS_DP
PA1_C.Locked=true
PA1_C.Signal=ADCx_INP1
PA2.Locked=true
PA2.Signal=S_TIM5_CH3
PA5.Locked=true
PA5.Signal=COMP_DAC12_group
PB10.Mode=Asynchronous
PB10.Signal=USART3_TX
PB11.Mode=Asynchronous
PB11.Signal=USART3_RX
PB14.Mode=SD_4_bits_Wide_bus
PB14.Signal=SDMMC2_D0
PB15.Mode=SD_4_bits_Wide_bus
PB15.Signal=SDMMC2_D1
PB3\ (JTDO/TRACESWO).Mode=SD_4_bits_Wide_bus
PB3\ (JTDO/TRACESWO).Signal=SDMMC2_D2
PB4\ (NJTRST).Mode=SD_4_bits_Wide_bus
PB4\ (NJTRST).Signal=SDMMC2_D3
PC10.Mode=SD_4_bits_Wide_bus
PC10.Signal=SDMMC1_D2
PC11.Mode=SD_4_bits_Wide_bus
PC11.Signal=SDMMC1_D3
PC12.Mode=SD_4_bits_Wide_bus
PC12.Signal=SDMMC1_CK
PC2.GPIOParameters=GPIO_Speed_High_Default
PC2.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PC2.Mode=SdramChipSelect1_1
PC2.Signal=FMC_SDNE0
PC3.GPIOParameters=GPIO_Speed_High_Default
PC3.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PC3.Mode=SdramChipSelect1_1
PC3.Signal=FMC_SDCKE0
PC8.Mode=SD_4_bits_Wide_bus
PC8.Signal=SDMMC1_D0
PC9.Mode=SD_4_bits_Wide_bus
PC9.Signal=SDMMC1_D1
PD0.GPIOParameters=GPIO_Speed_High_Default
PD0.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD0.Signal=FMC_D2_DA2
PD1.GPIOParameters=GPIO_Speed_High_Default
PD1.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD1.Signal=FMC_D3_DA3
PD10.GPIOParameters=GPIO_Speed_High_Default
PD10.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD10.Signal=FMC_D15_DA15
PD11.Mode=CTS_RTS
PD11.Signal=USART3_CTS
PD12.Mode=CTS_RTS
PD12.Signal=USART3_RTS
PD14.GPIOParameters=GPIO_Speed_High_Default
PD14.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD14.Signal=FMC_D0_DA0
PD15.GPIOParameters=GPIO_Speed_High_Default
PD15.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD15.Signal=FMC_D1_DA1
PD2.Mode=SD_4_bits_Wide_bus
PD2.Signal=SDMMC1_CMD
PD6.Mode=SD_4_bits_Wide_bus
PD6.Signal=SDMMC2_CK
PD7.Mode=SD_4_bits_Wide_bus
PD7.Signal=SDMMC2_CMD
PD8.GPIOParameters=GPIO_Speed_High_Default
PD8.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD8.Signal=FMC_D13_DA13
PD9.GPIOParameters=GPIO_Speed_High_Default
PD9.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PD9.Signal=FMC_D14_DA14
PE0.GPIOParameters=GPIO_Speed_High_Default
PE0.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE0.Signal=FMC_NBL0
PE1.GPIOParameters=GPIO_Speed_High_Default
PE1.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE1.Signal=FMC_NBL1
PE10.GPIOParameters=GPIO_Speed_High_Default
PE10.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE10.Signal=FMC_D7_DA7
PE11.GPIOParameters=GPIO_Speed_High_Default
PE11.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE11.Signal=FMC_D8_DA8
PE12.GPIOParameters=GPIO_Speed_High_Default
PE12.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE12.Signal=FMC_D9_DA9
PE13.GPIOParameters=GPIO_Speed_High_Default
PE13.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE13.Signal=FMC_D10_DA10
PE14.GPIOParameters=GPIO_Speed_High_Default
PE14.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE14.Signal=FMC_D11_DA11
PE15.GPIOParameters=GPIO_Speed_High_Default
PE15.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE15.Signal=FMC_D12_DA12
PE2.GPIOParameters=GPIO_Speed
PE2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE2.Mode=Full_Duplex_Master
PE2.Signal=SPI4_SCK
PE5.GPIOParameters=GPIO_Speed
PE5.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE5.Mode=Full_Duplex_Master
PE5.Signal=SPI4_MISO
PE6.GPIOParameters=GPIO_Speed
PE6.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PE6.Mode=Full_Duplex_Master
PE6.Signal=SPI4_MOSI
PE7.GPIOParameters=GPIO_Speed_High_Default
PE7.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE7.Signal=FMC_D4_DA4
PE8.GPIOParameters=GPIO_Speed_High_Default
PE8.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE8.Signal=FMC_D5_DA5
PE9.GPIOParameters=GPIO_Speed_High_Default
PE9.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PE9.Signal=FMC_D6_DA6
PF0.GPIOParameters=GPIO_Speed_High_Default
PF0.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF0.Signal=FMC_A0
PF1.GPIOParameters=GPIO_Speed_High_Default
PF1.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF1.Signal=FMC_A1
PF11.GPIOParameters=GPIO_Speed_High_Default
PF11.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF11.Signal=FMC_SDNRAS
PF12.GPIOParameters=GPIO_Speed_High_Default
PF12.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF12.Signal=FMC_A6
PF13.GPIOParameters=GPIO_Speed_High_Default
PF13.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF13.Signal=FMC_A7
PF14.GPIOParameters=GPIO_Speed_High_Default
PF14.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF14.Signal=FMC_A8
PF15.GPIOParameters=GPIO_Speed_High_Default
PF15.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF15.Signal=FMC_A9
PF2.GPIOParameters=GPIO_Speed_High_Default
PF2.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF2.Signal=FMC_A2
PF3.GPIOParameters=GPIO_Speed_High_Default
PF3.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF3.Signal=FMC_A3
PF4.GPIOParameters=GPIO_Speed_High_Default
PF4.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF4.Signal=FMC_A4
PF5.GPIOParameters=GPIO_Speed_High_Default
PF5.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PF5.Signal=FMC_A5
PG0.GPIOParameters=GPIO_Speed_High_Default
PG0.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG0.Signal=FMC_A10
PG1.GPIOParameters=GPIO_Speed_High_Default
PG1.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG1.Signal=FMC_A11
PG10.Mode=SAI_B_SyncSlave
PG10.Signal=SAI2_SD_B
PG11.Locked=true
PG11.Signal=GPIO_Output
PG14.Locked=true
PG14.Signal=GPXTI14
PG15.GPIOParameters=GPIO_Speed_High_Default
PG15.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG15.Signal=FMC_SDNCAS
PG2.GPIOParameters=GPIO_Speed_High_Default
PG2.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG2.Signal=FMC_A12
PG4.GPIOParameters=GPIO_Speed_High_Default
PG4.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG4.Signal=FMC_A14_BA0
PG5.GPIOParameters=GPIO_Speed_High_Default
PG5.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG5.Signal=FMC_A15_BA1
PG8.GPIOParameters=GPIO_Speed_High_Default
PG8.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PG8.Signal=FMC_SDCLK
PH0-OSC_IN\ (PH0).Mode=HSE-External-Oscillator
PH0-OSC_IN\ (PH0).Signal=RCC_OSC_IN
PH1-OSC_OUT\ (PH1).Mode=HSE-External-Oscillator
PH1-OSC_OUT\ (PH1).Signal=RCC_OSC_OUT
PH11.GPIOParameters=GPIO_Pu
PH11.GPIO_Pu=GPIO_PULLUP
PH11.Locked=true
PH11.Mode=I2C
PH11.Signal=I2C4_SCL
PH12.GPIOParameters=GPIO_Pu
PH12.GPIO_Pu=GPIO_PULLUP
PH12.Locked=true
PH12.Mode=I2C
PH12.Signal=I2C4_SDA
PH5.GPIOParameters=GPIO_Speed_High_Default
PH5.GPIO_Speed_High_Default=GPIO_SPEED_FREQ_VERY_HIGH
PH5.Locked=true
PH5.Signal=FMC_SDNWE
PI1.GPIOParameters=GPIO_Speed
PI1.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PI1.Mode=Full_Duplex_Master
PI1.Signal=SPI2_SCK
PI12.GPIOParameters=GPIO_Speed
PI12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PI12.Locked=true
PI12.Mode=RGB888
PI12.Signal=LTDC_HSYNC
PI13.GPIOParameters=GPIO_Speed
PI13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PI13.Locked=true
PI13.Mode=RGB888
PI13.Signal=LTDC_VSYNC
PI14.GPIOParameters=GPIO_Speed
PI14.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PI14.Locked=true
PI14.Mode=RGB888
PI14.Signal=LTDC_CLK
PI15.GPIOParameters=GPIO_Speed
PI15.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PI15.Locked=true
PI15.Mode=RGB888
PI15.Signal=LTDC_R0
PI2.GPIOParameters=GPIO_Speed
PI2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PI2.Mode=Full_Duplex_Master
PI2.Signal=SPI2_MISO
PI3.GPIOParameters=GPIO_Speed
PI3.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
PI3.Mode=Full_Duplex_Master
PI3.Signal=SPI2_MOSI
PI4.Mode=SAI_A_MasterWithClock
PI4.Signal=SAI2_MCLK_A
PI5.Mode=SAI_A_MasterWithClock
PI5.Signal=SAI2_SCK_A
PI6.Mode=SAI_A_MasterWithClock
PI6.Signal=SAI2_SD_A
PI7.Mode=SAI_A_MasterWithClock
PI7.Signal=SAI2_FS_A
PI9.Locked=true
PI9.Mode=Asynchronous
PI9.Signal=UART4_RX
PJ0.GPIOParameters=GPIO_Speed
PJ0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ0.Mode=RGB888
PJ0.Signal=LTDC_R1
PJ1.GPIOParameters=GPIO_Speed
PJ1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ1.Mode=RGB888
PJ1.Signal=LTDC_R2
PJ10.GPIOParameters=GPIO_Speed
PJ10.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ10.Locked=true
PJ10.Mode=RGB888
PJ10.Signal=LTDC_G3
PJ11.GPIOParameters=GPIO_Speed
PJ11.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ11.Locked=true
PJ11.Mode=RGB888
PJ11.Signal=LTDC_G4
PJ12.GPIOParameters=GPIO_Speed
PJ12.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ12.Locked=true
PJ12.Mode=RGB888
PJ12.Signal=LTDC_B0
PJ13.GPIOParameters=GPIO_Speed
PJ13.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ13.Locked=true
PJ13.Mode=RGB888
PJ13.Signal=LTDC_B1
PJ14.GPIOParameters=GPIO_Speed
PJ14.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ14.Mode=RGB888
PJ14.Signal=LTDC_B2
PJ15.GPIOParameters=GPIO_Speed
PJ15.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ15.Mode=RGB888
PJ15.Signal=LTDC_B3
PJ2.GPIOParameters=GPIO_Speed
PJ2.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ2.Locked=true
PJ2.Mode=RGB888
PJ2.Signal=LTDC_R3
PJ3.GPIOParameters=GPIO_Speed
PJ3.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ3.Locked=true
PJ3.Mode=RGB888
PJ3.Signal=LTDC_R4
PJ4.GPIOParameters=GPIO_Speed
PJ4.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ4.Locked=true
PJ4.Mode=RGB888
PJ4.Signal=LTDC_R5
PJ5.GPIOParameters=GPIO_Speed
PJ5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ5.Locked=true
PJ5.Mode=RGB888
PJ5.Signal=LTDC_R6
PJ6.GPIOParameters=GPIO_Speed
PJ6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ6.Locked=true
PJ6.Mode=RGB888
PJ6.Signal=LTDC_R7
PJ7.GPIOParameters=GPIO_Speed
PJ7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ7.Mode=RGB888
PJ7.Signal=LTDC_G0
PJ8.GPIOParameters=GPIO_Speed
PJ8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ8.Mode=RGB888
PJ8.Signal=LTDC_G1
PJ9.GPIOParameters=GPIO_Speed
PJ9.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PJ9.Locked=true
PJ9.Mode=RGB888
PJ9.Signal=LTDC_G2
PK0.GPIOParameters=GPIO_Speed
PK0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK0.Locked=true
PK0.Mode=RGB888
PK0.Signal=LTDC_G5
PK1.GPIOParameters=GPIO_Speed
PK1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK1.Locked=true
PK1.Mode=RGB888
PK1.Signal=LTDC_G6
PK2.GPIOParameters=GPIO_Speed
PK2.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK2.Locked=true
PK2.Mode=RGB888
PK2.Signal=LTDC_G7
PK3.GPIOParameters=GPIO_Speed
PK3.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK3.Locked=true
PK3.Mode=RGB888
PK3.Signal=LTDC_B4
PK4.GPIOParameters=GPIO_Speed
PK4.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK4.Locked=true
PK4.Mode=RGB888
PK4.Signal=LTDC_B5
PK5.GPIOParameters=GPIO_Speed
PK5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK5.Locked=true
PK5.Mode=RGB888
PK5.Signal=LTDC_B6
PK6.GPIOParameters=GPIO_Speed
PK6.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK6.Locked=true
PK6.Mode=RGB888
PK6.Signal=LTDC_B7
PK7.GPIOParameters=GPIO_Speed
PK7.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
PK7.Mode=RGB888
PK7.Signal=LTDC_DE
PinOutPanel.CurrentBGAView=Top
PinOutPanel.RotationAngle=0
ProjectManager.AskForMigrate=true
ProjectManager.BackupPrevious=false
ProjectManager.CompilerLinker=GCC
ProjectManager.CompilerOptimize=6
ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=false
ProjectManager.CustomerFirmwarePackage=C\:\\Users\\Administrator\\STM32Cube\\Repository\\STM32Cube_FW_H7_V1.9.1
ProjectManager.DefaultFWLocation=false
ProjectManager.DeletePrevious=true
ProjectManager.DeviceId=STM32H750XBHx
ProjectManager.FirmwarePackage=STM32Cube FW_H7 V1.12.1
ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x200
ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=false
ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Core/Src
ProjectManager.NoMain=false
ProjectManager.PreviousToolchain=
ProjectManager.ProjectBuild=false
ProjectManager.ProjectFileName=CubeMX_Config.ioc
ProjectManager.ProjectName=CubeMX_Config
ProjectManager.ProjectStructure=
ProjectManager.RegisterCallBack=
ProjectManager.StackSize=0x400
ProjectManager.TargetToolchain=MDK-ARM V5.27
ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_FMC_Init-FMC-false-HAL-true,5-MX_LTDC_Init-LTDC-false-HAL-true,6-MX_SDMMC1_SD_Init-SDMMC1-false-HAL-true,7-MX_SDMMC2_SD_Init-SDMMC2-false-HAL-true,8-MX_SPI4_Init-SPI4-false-HAL-true,9-MX_UART4_Init-UART4-false-HAL-true,10-MX_USART3_UART_Init-USART3-false-HAL-true,11-MX_USB_OTG_FS_PCD_Init-USB_OTG_FS-false-HAL-true,12-MX_IWDG1_Init-IWDG1-false-HAL-true,13-MX_SPI2_Init-SPI2-false-HAL-true,14-MX_ADC1_Init-ADC1-false-HAL-true,15-MX_TIM2_Init-TIM2-false-HAL-true,16-MX_TIM5_Init-TIM5-false-HAL-true,17-MX_TIM12_Init-TIM12-false-HAL-true,18-MX_I2C4_Init-I2C4-false-HAL-true,19-MX_SAI2_Init-SAI2-false-HAL-true,0-MX_CORTEX_M7_Init-CORTEX_M7-false-HAL-true
RCC.ADCFreq_Value=100000000
RCC.AHB12Freq_Value=240000000
RCC.AHB4Freq_Value=240000000
RCC.APB1Freq_Value=120000000
RCC.APB2Freq_Value=120000000
RCC.APB3Freq_Value=120000000
RCC.APB4Freq_Value=120000000
RCC.AXIClockFreq_Value=240000000
RCC.CECFreq_Value=32000
RCC.CKPERFreq_Value=64000000
RCC.CortexFreq_Value=480000000
RCC.CpuClockFreq_Value=480000000
RCC.D1CPREFreq_Value=480000000
RCC.D1PPRE=RCC_APB3_DIV2
RCC.D2PPRE1=RCC_APB1_DIV2
RCC.D2PPRE2=RCC_APB2_DIV2
RCC.D3PPRE=RCC_APB4_DIV2
RCC.DFSDMACLkFreq_Value=480000000
RCC.DFSDMFreq_Value=120000000
RCC.DIVM1=5
RCC.DIVM2=2
RCC.DIVM3=10
RCC.DIVN1=192
RCC.DIVN2=64
RCC.DIVN3=160
RCC.DIVP1Freq_Value=480000000
RCC.DIVP2=8
RCC.DIVP2Freq_Value=100000000
RCC.DIVP3=98
RCC.DIVP3Freq_Value=4081632.6530612246
RCC.DIVQ1Freq_Value=480000000
RCC.DIVQ2=8
RCC.DIVQ2Freq_Value=100000000
RCC.DIVQ3=8
RCC.DIVQ3Freq_Value=50000000
RCC.DIVR1Freq_Value=480000000
RCC.DIVR2=4
RCC.DIVR2Freq_Value=200000000
RCC.DIVR3=12
RCC.DIVR3Freq_Value=33333333.333333332
RCC.FDCANFreq_Value=480000000
RCC.FMCCLockSelection=RCC_FMCCLKSOURCE_PLL2
RCC.FMCFreq_Value=200000000
RCC.FamilyName=M
RCC.HCLK3ClockFreq_Value=240000000
RCC.HCLKFreq_Value=240000000
RCC.HPRE=RCC_HCLK_DIV2
RCC.HRTIMFreq_Value=240000000
RCC.I2C123Freq_Value=120000000
RCC.I2C4Freq_Value=120000000
RCC.IPParameters=ADCFreq_Value,AHB12Freq_Value,AHB4Freq_Value,APB1Freq_Value,APB2Freq_Value,APB3Freq_Value,APB4Freq_Value,AXIClockFreq_Value,CECFreq_Value,CKPERFreq_Value,CortexFreq_Value,CpuClockFreq_Value,D1CPREFreq_Value,D1PPRE,D2PPRE1,D2PPRE2,D3PPRE,DFSDMACLkFreq_Value,DFSDMFreq_Value,DIVM1,DIVM2,DIVM3,DIVN1,DIVN2,DIVN3,DIVP1Freq_Value,DIVP2,DIVP2Freq_Value,DIVP3,DIVP3Freq_Value,DIVQ1Freq_Value,DIVQ2,DIVQ2Freq_Value,DIVQ3,DIVQ3Freq_Value,DIVR1Freq_Value,DIVR2,DIVR2Freq_Value,DIVR3,DIVR3Freq_Value,FDCANFreq_Value,FMCCLockSelection,FMCFreq_Value,FamilyName,HCLK3ClockFreq_Value,HCLKFreq_Value,HPRE,HRTIMFreq_Value,I2C123Freq_Value,I2C4Freq_Value,LPTIM1Freq_Value,LPTIM2Freq_Value,LPTIM345Freq_Value,LPUART1Freq_Value,LTDCFreq_Value,MCO1PinFreq_Value,MCO2PinFreq_Value,PLL2FRACN,PLL3FRACN,PLLFRACN,PLLSourceVirtual,QSPIFreq_Value,RNGFreq_Value,RTCFreq_Value,SAI1Freq_Value,SAI23CLockSelection,SAI23Freq_Value,SAI4AFreq_Value,SAI4BFreq_Value,SDMMC1CLockSelection,SDMMCFreq_Value,SPDIFRXFreq_Value,SPI123CLockSelection,SPI123Freq_Value,SPI45Freq_Value,SPI6Freq_Value,SWPMI1Freq_Value,SYSCLKFreq_VALUE,SYSCLKSource,Spi45ClockSelection,Tim1OutputFreq_Value,Tim2OutputFreq_Value,TraceFreq_Value,USART16Freq_Value,USART234578Freq_Value,USBCLockSelection,USBFreq_Value,VCO1OutputFreq_Value,VCO2OutputFreq_Value,VCO3OutputFreq_Value,VCOInput1Freq_Value,VCOInput2Freq_Value,VCOInput3Freq_Value
RCC.LPTIM1Freq_Value=120000000
RCC.LPTIM2Freq_Value=120000000
RCC.LPTIM345Freq_Value=120000000
RCC.LPUART1Freq_Value=120000000
RCC.LTDCFreq_Value=33333333.333333332
RCC.MCO1PinFreq_Value=64000000
RCC.MCO2PinFreq_Value=480000000
RCC.PLL2FRACN=0
RCC.PLL3FRACN=0
RCC.PLLFRACN=0
RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE
RCC.QSPIFreq_Value=240000000
RCC.RNGFreq_Value=48000000
RCC.RTCFreq_Value=32000
RCC.SAI1Freq_Value=480000000
RCC.SAI23CLockSelection=RCC_SAI23CLKSOURCE_PLL3
RCC.SAI23Freq_Value=4081632.6530612246
RCC.SAI4AFreq_Value=480000000
RCC.SAI4BFreq_Value=480000000
RCC.SDMMC1CLockSelection=RCC_SDMMCCLKSOURCE_PLL2
RCC.SDMMCFreq_Value=200000000
RCC.SPDIFRXFreq_Value=480000000
RCC.SPI123CLockSelection=RCC_SPI123CLKSOURCE_PLL2
RCC.SPI123Freq_Value=100000000
RCC.SPI45Freq_Value=100000000
RCC.SPI6Freq_Value=120000000
RCC.SWPMI1Freq_Value=120000000
RCC.SYSCLKFreq_VALUE=480000000
RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK
RCC.Spi45ClockSelection=RCC_SPI45CLKSOURCE_PLL2
RCC.Tim1OutputFreq_Value=240000000
RCC.Tim2OutputFreq_Value=240000000
RCC.TraceFreq_Value=64000000
RCC.USART16Freq_Value=120000000
RCC.USART234578Freq_Value=120000000
RCC.USBCLockSelection=RCC_USBCLKSOURCE_HSI48
RCC.USBFreq_Value=48000000
RCC.VCO1OutputFreq_Value=960000000
RCC.VCO2OutputFreq_Value=800000000
RCC.VCO3OutputFreq_Value=400000000
RCC.VCOInput1Freq_Value=5000000
RCC.VCOInput2Freq_Value=12500000
RCC.VCOInput3Freq_Value=2500000
SAI2.AudioFrequency-SAI_A_MasterWithClock=SAI_AUDIO_FREQUENCY_16K
SAI2.ErrorAudioFreq-SAI_A_MasterWithClock=-0.35 %
SAI2.FIFOThreshold-SAI_A_MasterWithClock=SAI_FIFOTHRESHOLD_HF
SAI2.FIFOThreshold-SAI_B_SyncSlave=SAI_FIFOTHRESHOLD_HF
SAI2.IPParameters=Instance-SAI_B_SyncSlave,VirtualMode-SAI_B_SyncSlave,VirtualProtocol-SAI_A_BASIC,InitProtocol-SAI_B_SyncSlave,VirtualProtocol-SAI_B_BASIC,FIFOThreshold-SAI_B_SyncSlave,Instance-SAI_A_MasterWithClock,VirtualMode-SAI_A_MasterWithClock,MClockEnable-SAI_A_MasterWithClock,InitProtocol-SAI_A_MasterWithClock,RealAudioFreq-SAI_A_MasterWithClock,ErrorAudioFreq-SAI_A_MasterWithClock,OutputDrive-SAI_B_SyncSlave,OutputDrive-SAI_A_MasterWithClock,FIFOThreshold-SAI_A_MasterWithClock,AudioFrequency-SAI_A_MasterWithClock,NoDivider-SAI_A_MasterWithClock,MckOverSampling-SAI_A_MasterWithClock,MckOverSampling-SAI_B_SyncSlave
SAI2.InitProtocol-SAI_A_MasterWithClock=Enable
SAI2.InitProtocol-SAI_B_SyncSlave=Enable
SAI2.Instance-SAI_A_MasterWithClock=SAI$Index_Block_A
SAI2.Instance-SAI_B_SyncSlave=SAI$Index_Block_B
SAI2.MClockEnable-SAI_A_MasterWithClock=SAI_MASTERCLOCK_ENABLE
SAI2.MckOverSampling-SAI_A_MasterWithClock=SAI_MCK_OVERSAMPLING_ENABLE
SAI2.MckOverSampling-SAI_B_SyncSlave=SAI_MCK_OVERSAMPLING_ENABLE
SAI2.NoDivider-SAI_A_MasterWithClock=SAI_MCK_OVERSAMPLING_DISABLE
SAI2.OutputDrive-SAI_A_MasterWithClock=SAI_OUTPUTDRIVE_ENABLE
SAI2.OutputDrive-SAI_B_SyncSlave=SAI_OUTPUTDRIVE_ENABLE
SAI2.RealAudioFreq-SAI_A_MasterWithClock=15.943 KHz
SAI2.VirtualMode-SAI_A_MasterWithClock=VM_MASTER
SAI2.VirtualMode-SAI_B_SyncSlave=VM_SLAVE
SAI2.VirtualProtocol-SAI_A_BASIC=VM_BASIC_PROTOCOL
SAI2.VirtualProtocol-SAI_B_BASIC=VM_BASIC_PROTOCOL
SH.ADCx_INP1.0=ADC1_INP1,IN1-Single-Ended
SH.ADCx_INP1.ConfNb=1
SH.COMP_DAC12_group.0=DAC1_OUT2
SH.COMP_DAC12_group.ConfNb=1
SH.FMC_A0.0=FMC_A0,13b-sda1
SH.FMC_A0.ConfNb=1
SH.FMC_A1.0=FMC_A1,13b-sda1
SH.FMC_A1.ConfNb=1
SH.FMC_A10.0=FMC_A10,13b-sda1
SH.FMC_A10.ConfNb=1
SH.FMC_A11.0=FMC_A11,13b-sda1
SH.FMC_A11.ConfNb=1
SH.FMC_A12.0=FMC_A12,13b-sda1
SH.FMC_A12.ConfNb=1
SH.FMC_A14_BA0.0=FMC_BA0,FourSdramBanks1
SH.FMC_A14_BA0.ConfNb=1
SH.FMC_A15_BA1.0=FMC_BA1,FourSdramBanks1
SH.FMC_A15_BA1.ConfNb=1
SH.FMC_A2.0=FMC_A2,13b-sda1
SH.FMC_A2.ConfNb=1
SH.FMC_A3.0=FMC_A3,13b-sda1
SH.FMC_A3.ConfNb=1
SH.FMC_A4.0=FMC_A4,13b-sda1
SH.FMC_A4.ConfNb=1
SH.FMC_A5.0=FMC_A5,13b-sda1
SH.FMC_A5.ConfNb=1
SH.FMC_A6.0=FMC_A6,13b-sda1
SH.FMC_A6.ConfNb=1
SH.FMC_A7.0=FMC_A7,13b-sda1
SH.FMC_A7.ConfNb=1
SH.FMC_A8.0=FMC_A8,13b-sda1
SH.FMC_A8.ConfNb=1
SH.FMC_A9.0=FMC_A9,13b-sda1
SH.FMC_A9.ConfNb=1
SH.FMC_D0_DA0.0=FMC_D0,sd-16b-d1
SH.FMC_D0_DA0.ConfNb=1
SH.FMC_D10_DA10.0=FMC_D10,sd-16b-d1
SH.FMC_D10_DA10.ConfNb=1
SH.FMC_D11_DA11.0=FMC_D11,sd-16b-d1
SH.FMC_D11_DA11.ConfNb=1
SH.FMC_D12_DA12.0=FMC_D12,sd-16b-d1
SH.FMC_D12_DA12.ConfNb=1
SH.FMC_D13_DA13.0=FMC_D13,sd-16b-d1
SH.FMC_D13_DA13.ConfNb=1
SH.FMC_D14_DA14.0=FMC_D14,sd-16b-d1
SH.FMC_D14_DA14.ConfNb=1
SH.FMC_D15_DA15.0=FMC_D15,sd-16b-d1
SH.FMC_D15_DA15.ConfNb=1
SH.FMC_D1_DA1.0=FMC_D1,sd-16b-d1
SH.FMC_D1_DA1.ConfNb=1
SH.FMC_D2_DA2.0=FMC_D2,sd-16b-d1
SH.FMC_D2_DA2.ConfNb=1
SH.FMC_D3_DA3.0=FMC_D3,sd-16b-d1
SH.FMC_D3_DA3.ConfNb=1
SH.FMC_D4_DA4.0=FMC_D4,sd-16b-d1
SH.FMC_D4_DA4.ConfNb=1
SH.FMC_D5_DA5.0=FMC_D5,sd-16b-d1
SH.FMC_D5_DA5.ConfNb=1
SH.FMC_D6_DA6.0=FMC_D6,sd-16b-d1
SH.FMC_D6_DA6.ConfNb=1
SH.FMC_D7_DA7.0=FMC_D7,sd-16b-d1
SH.FMC_D7_DA7.ConfNb=1
SH.FMC_D8_DA8.0=FMC_D8,sd-16b-d1
SH.FMC_D8_DA8.ConfNb=1
SH.FMC_D9_DA9.0=FMC_D9,sd-16b-d1
SH.FMC_D9_DA9.ConfNb=1
SH.FMC_NBL0.0=FMC_NBL0,Sd2ByteEnable1
SH.FMC_NBL0.ConfNb=1
SH.FMC_NBL1.0=FMC_NBL1,Sd2ByteEnable1
SH.FMC_NBL1.ConfNb=1
SH.FMC_SDCLK.0=FMC_SDCLK,13b-sda1
SH.FMC_SDCLK.ConfNb=1
SH.FMC_SDNCAS.0=FMC_SDNCAS,13b-sda1
SH.FMC_SDNCAS.ConfNb=1
SH.FMC_SDNRAS.0=FMC_SDNRAS,13b-sda1
SH.FMC_SDNRAS.ConfNb=1
SH.FMC_SDNWE.0=FMC_SDNWE,13b-sda1
SH.FMC_SDNWE.ConfNb=1
SH.GPXTI14.0=GPIO_EXTI14
SH.GPXTI14.ConfNb=1
SH.S_TIM5_CH3.0=TIM5_CH3,PWM Generation3 CH3
SH.S_TIM5_CH3.ConfNb=1
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2
SPI2.CLKPolarity=SPI_POLARITY_LOW
SPI2.CalculateBaudRate=50.0 MBits/s
SPI2.Direction=SPI_DIRECTION_2LINES
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler,CLKPolarity
SPI2.Mode=SPI_MODE_MASTER
SPI2.VirtualType=VM_MASTER
SPI4.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2
SPI4.CalculateBaudRate=50.0 MBits/s
SPI4.Direction=SPI_DIRECTION_2LINES
SPI4.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
SPI4.Mode=SPI_MODE_MASTER
SPI4.VirtualType=VM_MASTER
TIM12.IPParameters=Period,TIM_MasterOutputTrigger
TIM12.Period=14999
TIM12.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
TIM2.IPParameters=TIM_MasterOutputTrigger,Prescaler,Period
TIM2.Period=14999
TIM2.Prescaler=0
TIM2.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
TIM5.AutoReloadPreload=TIM_AUTORELOAD_PRELOAD_ENABLE
TIM5.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3
TIM5.IPParameters=Channel-PWM Generation3 CH3,Prescaler,Period,TIM_MasterOutputTrigger,Pulse-PWM Generation3 CH3,AutoReloadPreload
TIM5.Period=1499
TIM5.Prescaler=0
TIM5.Pulse-PWM\ Generation3\ CH3=749
TIM5.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
USART3.IPParameters=VirtualMode-Asynchronous
USART3.VirtualMode-Asynchronous=VM_ASYNC
USB_OTG_FS.IPParameters=VirtualMode
USB_OTG_FS.VirtualMode=Device_Only
VP_IWDG1_VS_IWDG.Mode=IWDG_Activate
VP_IWDG1_VS_IWDG.Signal=IWDG1_VS_IWDG
VP_MEMORYMAP_VS_MEMORYMAP.Mode=CurAppReg
VP_MEMORYMAP_VS_MEMORYMAP.Signal=MEMORYMAP_VS_MEMORYMAP
VP_SAI2_VP_$IpInstance_SAIA_SAI_BASIC.Mode=SAI_A_BASIC
VP_SAI2_VP_$IpInstance_SAIA_SAI_BASIC.Signal=SAI2_VP_$IpInstance_SAIA_SAI_BASIC
VP_SAI2_VP_$IpInstance_SAIB_SAI_BASIC.Mode=SAI_B_BASIC
VP_SAI2_VP_$IpInstance_SAIB_SAI_BASIC.Signal=SAI2_VP_$IpInstance_SAIB_SAI_BASIC
VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM12_VS_ClockSourceINT.Mode=Internal
VP_TIM12_VS_ClockSourceINT.Signal=TIM12_VS_ClockSourceINT
VP_TIM2_VS_ClockSourceINT.Mode=Internal
VP_TIM2_VS_ClockSourceINT.Signal=TIM2_VS_ClockSourceINT
VP_TIM5_VS_ClockSourceINT.Mode=Internal
VP_TIM5_VS_ClockSourceINT.Signal=TIM5_VS_ClockSourceINT
board=custom

7. 附录3:SAI + TX + RX + DMA关键函数Trace分析(jlink trace)

  • 对如下4个关键函数进行Trace分析
HAL_SAI_Receive_DMA(&hsai_BlockB2, (uint8_t *)adc_buffer, ADC_BUFFER_SIZE * 2);  
HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)dac_buffer, SIN_TABLE_SIZE * 2);

/**
* @brief This function handles DMA1 stream2 global interrupt.
*/
void DMA1_Stream2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream2_IRQn 0 */

  /* USER CODE END DMA1_Stream2_IRQn 0 */
  rt_base_t level = rt_hw_interrupt_disable();
  HAL_DMA_IRQHandler(&hdma_sai2_a);
  rt_hw_interrupt_enable(level);
  /* USER CODE BEGIN DMA1_Stream2_IRQn 1 */

  /* USER CODE END DMA1_Stream2_IRQn 1 */
}

/**
 * @brief This function handles DMA1 stream3 global interrupt.
 */
void DMA1_Stream3_IRQHandler(void)
{
  /* USER CODE BEGIN DMA1_Stream3_IRQn 0 */

  /* USER CODE END DMA1_Stream3_IRQn 0 */
  rt_base_t level = rt_hw_interrupt_disable();
  HAL_DMA_IRQHandler(&hdma_sai2_b);
  rt_hw_interrupt_enable(level);
  /* USER CODE BEGIN DMA1_Stream3_IRQn 1 */

  /* USER CODE END DMA1_Stream3_IRQn 1 */
}
  • HAL_SAI_Transmit_DMA
  • 从这个函数看, 配置DMA并开启DMA中断
  • 另外, 它开启了SAI的中断__HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)), 最终开启了SAI_IT_OVRUDR(溢出中断)和SAI_IT_WCKCFG(时钟配置错误中断)。这说明, SAI在CubeMX配置的时候,确实应该打开SAI全局中断。
Continuing.

Breakpoint 2, HAL_SAI_Transmit_DMA (hsai=0x24000ee4 <hsai_BlockA2>, pData=0x24070000 <dac_buffer> "\377\177\377\177\035\216\035\216\n\234\n����\251��������(\316(�r�r؈��N�N���|�|�����c�c�c�c\371\277���|�|����N�N���r�r\330(\316(����’������\251\n\234\n\234\035\216\035\216\377\177\377\177�q�q�c�chVhVlIlI-=-=\326\061\326\061\214'\214'v\036v\036\260\026\260\026X\020X\020\202\v\202\v?\b?\b\233\006\233\006\233\006\233\006?\b?\b\202\v\202\vX\020X\020\260\026\260\026v\036v\036\214'\214'\326\061\326\061-=-="..., Size=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1648
1648	  uint32_t tickstart = HAL_GetTick();
HAL_GetTick () at libraries\HAL_Drivers\drv_common.c:77
77	    if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)
80	    return uwTick;
81	}
HAL_SAI_Transmit_DMA (hsai=0x24000ee4 <hsai_BlockA2>, pData=0x24070000 <dac_buffer> "\377\177\377\177\035\216\035\216\n\234\n����\251��������(\316(�r�r؈��N�N���|�|�����c�c�c�c\371\277���|�|����N�N���r�r\330(\316(����’������\251\n\234\n\234\035\216\035\216\377\177\377\177�q�q�c�chVhVlIlI-=-=\326\061\326\061\214'\214'v\036v\036\260\026\260\026X\020X\020\202\v\202\v?\b?\b\233\006\233\006\233\006\233\006?\b?\b\202\v\202\vX\020X\020\260\026\260\026v\036v\036\214'\214'\326\061\326\061-=-="..., Size=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1650
1650	  if ((pData == NULL) || (Size == 0U))
1655	  if (hsai->State == HAL_SAI_STATE_READY)
1658	    __HAL_LOCK(hsai);
1660	    hsai->pBuffPtr = pData;
1661	    hsai->XferSize = Size;
1662	    hsai->XferCount = Size;
1663	    hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1664	    hsai->State = HAL_SAI_STATE_BUSY_TX;
1667	    hsai->hdmatx->XferHalfCpltCallback = SAI_DMATxHalfCplt;
1670	    hsai->hdmatx->XferCpltCallback = SAI_DMATxCplt;
1673	    hsai->hdmatx->XferErrorCallback = SAI_DMAError;
1676	    hsai->hdmatx->XferAbortCallback = NULL;
1679	    if (HAL_DMA_Start_IT(hsai->hdmatx, (uint32_t)hsai->pBuffPtr, (uint32_t)&hsai->Instance->DR, hsai->XferSize) != HAL_OK)
HAL_DMA_Start_IT (hdma=0x24001014 <hdma_sai2_a>, SrcAddress=604438528, DstAddress=1073830944, DataLength=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:683
683	  HAL_StatusTypeDef status = HAL_OK;
689	  if(hdma == NULL)
695	  __HAL_LOCK(hdma);
697	  if(HAL_DMA_STATE_READY == hdma->State)
700	    hdma->State = HAL_DMA_STATE_BUSY;
703	    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
706	    __HAL_DMA_DISABLE(hdma);
709	    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
DMA_SetConfig (hdma=0x24001014 <hdma_sai2_a>, SrcAddress=604438528, DstAddress=1073830944, DataLength=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1776
1776	  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1777	  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1779	  if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1782	    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1784	    if(hdma->DMAmuxRequestGen != 0U)
1791	  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1794	    regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1797	    ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
1800	    ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
1803	    if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1806	      ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
1809	      ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
1852	}
HAL_DMA_Start_IT (hdma=0x24001014 <hdma_sai2_a>, SrcAddress=604438528, DstAddress=1073830944, DataLength=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:711
711	    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
714	      MODIFY_REG(((DMA_Stream_TypeDef   *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME));
716	      if(hdma->XferHalfCpltCallback != NULL)
719	        ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
734	    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
737	      if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
743	      if(hdma->DMAmuxRequestGen != 0U)
752	    __HAL_DMA_ENABLE(hdma);
766	  return status;
767	}
HAL_SAI_Transmit_DMA (hsai=0x24000ee4 <hsai_BlockA2>, pData=0x24070000 <dac_buffer> "\377\177\377\177\035\216\035\216\n\234\n����\251��������(\316(�r�r؈��N�N���|�|�����c�c�c�c\371\277���|�|����N�N���r�r\330(\316(����’������\251\n\234\n\234\035\216\035\216\377\177\377\177�q�q�c�chVhVlIlI-=-=\326\061\326\061\214'\214'v\036v\036\260\026\260\026X\020X\020\202\v\202\v?\b?\b\233\006\233\006\233\006\233\006?\b?\b\202\v\202\vX\020X\020\260\026\260\026v\036v\036\214'\214'\326\061\326\061-=-="..., Size=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1686
1686	    __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
SAI_InterruptFlag (hsai=0x24000ee4 <hsai_BlockA2>, mode=SAI_MODE_DMA) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2503
2503	  uint32_t tmpIT = SAI_IT_OVRUDR;
2505	  if (mode == SAI_MODE_IT)
2510	  if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
2516	  if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2523	    tmpIT |= SAI_IT_WCKCFG;
2525	  return tmpIT;
2526	}
HAL_SAI_Transmit_DMA (hsai=0x24000ee4 <hsai_BlockA2>, pData=0x24070000 <dac_buffer> "\377\177\377\177\035\216\035\216\n\234\n����\251��������(\316(�r�r؈��N�N���|�|�����c�c�c�c\371\277���|�|����N�N���r�r\330(\316(����’������\251\n\234\n\234\035\216\035\216\377\177\377\177�q�q�c�chVhVlIlI-=-=\326\061\326\061\214'\214'v\036v\036\260\026\260\026X\020X\020\202\v\202\v?\b?\b\233\006\233\006\233\006\233\006?\b?\b\202\v\202\vX\020X\020\260\026\260\026v\036v\036\214'\214'\326\061\326\061-=-="..., Size=108) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1689
1689	    hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1692	    while ((hsai->Instance->SR & SAI_xSR_FLVL) == SAI_FIFOSTATUS_EMPTY)
1708	    if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1711	      __HAL_SAI_ENABLE(hsai);
1715	    __HAL_UNLOCK(hsai);
1717	    return HAL_OK;
1723	}
SAI_DMA_Init () at applications\sai_dma.c:144
144	  return 0;

  • HAL_SAI_Receive_DMA
  • 从这个函数看, 配置DMA并开启DMA中断
  • 另外, 它开启了SAI的中断__HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA)), 最终开启了SAI_IT_OVRUDR(溢出中断), SAI_IT_AFSDET(音频帧同步检测中断)和SAI_IT_LFSDET(长帧同步检测中断)中断。这说明, SAI在CubeMX配置的时候,确实应该打开SAI全局中断。
Continuing.

Breakpoint 1, HAL_SAI_Receive_DMA (hsai=0x24000f7c <hsai_BlockB2>, pData=0x240700e0 <adc_buffer> '\377' <repeats 200 times>..., Size=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1736
1736	  if ((pData == NULL) || (Size == 0U))
1741	  if (hsai->State == HAL_SAI_STATE_READY)
1744	    __HAL_LOCK(hsai);
1746	    hsai->pBuffPtr = pData;
1747	    hsai->XferSize = Size;
1748	    hsai->XferCount = Size;
1749	    hsai->ErrorCode = HAL_SAI_ERROR_NONE;
1750	    hsai->State = HAL_SAI_STATE_BUSY_RX;
1753	    hsai->hdmarx->XferHalfCpltCallback = SAI_DMARxHalfCplt;
1756	    hsai->hdmarx->XferCpltCallback = SAI_DMARxCplt;
1759	    hsai->hdmarx->XferErrorCallback = SAI_DMAError;
1762	    hsai->hdmarx->XferAbortCallback = NULL;
1765	    if (HAL_DMA_Start_IT(hsai->hdmarx, (uint32_t)&hsai->Instance->DR, (uint32_t)hsai->pBuffPtr, hsai->XferSize) != HAL_OK)
HAL_DMA_Start_IT (hdma=0x2400108c <hdma_sai2_b>, SrcAddress=1073830976, DstAddress=604438752, DataLength=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:683
683	  HAL_StatusTypeDef status = HAL_OK;
689	  if(hdma == NULL)
695	  __HAL_LOCK(hdma);
697	  if(HAL_DMA_STATE_READY == hdma->State)
700	    hdma->State = HAL_DMA_STATE_BUSY;
703	    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
706	    __HAL_DMA_DISABLE(hdma);
709	    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
DMA_SetConfig (hdma=0x2400108c <hdma_sai2_b>, SrcAddress=1073830976, DstAddress=604438752, DataLength=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1776
1776	  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1777	  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1779	  if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
1782	    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
1784	    if(hdma->DMAmuxRequestGen != 0U)
1791	  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
1794	    regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
1797	    ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
1800	    ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
1803	    if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
1815	      ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
1818	      ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
1852	}
HAL_DMA_Start_IT (hdma=0x2400108c <hdma_sai2_b>, SrcAddress=1073830976, DstAddress=604438752, DataLength=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:711
711	    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
714	      MODIFY_REG(((DMA_Stream_TypeDef   *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME));
716	      if(hdma->XferHalfCpltCallback != NULL)
719	        ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
734	    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
737	      if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
743	      if(hdma->DMAmuxRequestGen != 0U)
752	    __HAL_DMA_ENABLE(hdma);
766	  return status;
767	}
HAL_SAI_Receive_DMA (hsai=0x24000f7c <hsai_BlockB2>, pData=0x240700e0 <adc_buffer> '\377' <repeats 200 times>..., Size=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1772
1772	    __HAL_SAI_ENABLE_IT(hsai, SAI_InterruptFlag(hsai, SAI_MODE_DMA));
SAI_InterruptFlag (hsai=0x24000f7c <hsai_BlockB2>, mode=SAI_MODE_DMA) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2503
2503	  uint32_t tmpIT = SAI_IT_OVRUDR;
2505	  if (mode == SAI_MODE_IT)
2510	  if ((hsai->Init.Protocol == SAI_AC97_PROTOCOL) &&
2516	  if ((hsai->Init.AudioMode == SAI_MODESLAVE_RX) || (hsai->Init.AudioMode == SAI_MODESLAVE_TX))
2518	    tmpIT |= SAI_IT_AFSDET | SAI_IT_LFSDET;
2525	  return tmpIT;
2526	}
HAL_SAI_Receive_DMA (hsai=0x24000f7c <hsai_BlockB2>, pData=0x240700e0 <adc_buffer> '\377' <repeats 200 times>..., Size=2048) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:1775
1775	    hsai->Instance->CR1 |= SAI_xCR1_DMAEN;
1778	    if ((hsai->Instance->CR1 & SAI_xCR1_SAIEN) == 0U)
1781	      __HAL_SAI_ENABLE(hsai);
1785	    __HAL_UNLOCK(hsai);
1787	    return HAL_OK;
1793	}
SAI_DMA_Init () at applications\sai_dma.c:142
142	  HAL_SAI_Transmit_DMA(&hsai_BlockA2, (uint8_t *)dac_buffer, SIN_TABLE_SIZE * 2);

  • DMA1_Stream2_IRQHandler(tx)
  • 可见最终调用了HAL_SAI_TxHalfCpltCallback和HAL_SAI_TxCpltCallback
Continuing.

Breakpoint 4, DMA1_Stream2_IRQHandler () at applications\sai_dma.c:385
385	  rt_base_t level = rt_hw_interrupt_disable();
rt_hw_interrupt_disable () at rt-thread\libcpu\arm\cortex-m7/context_gcc.S:39
39	    MRS     r0, PRIMASK
40	    CPSID   I
41	    BX      LR
DMA1_Stream2_IRQHandler () at applications\sai_dma.c:386
386	  HAL_DMA_IRQHandler(&hdma_sai2_a);
HAL_DMA_IRQHandler (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1212
1212	  __IO uint32_t count = 0U;
1213	  uint32_t timeout = SystemCoreClock / 9600U;
1216	  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1217	  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1219	  tmpisr_dma  = regs_dma->ISR;
1220	  tmpisr_bdma = regs_bdma->ISR;
1222	  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
1225	    if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1240	    if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1252	    if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1264	    if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1266	      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
1269	        regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1272	        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1296	          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1302	          if(hdma->XferHalfCpltCallback != NULL)
1305	            hdma->XferHalfCpltCallback(hdma);
SAI_DMATxHalfCplt (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2802
2802	  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2807	  HAL_SAI_TxHalfCpltCallback(hsai);
HAL_SAI_TxHalfCpltCallback (hsai=0x24000ee4 <hsai_BlockA2>) at applications\sai_dma.c:101
101	}
SAI_DMATxHalfCplt (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2809
2809	}
HAL_DMA_IRQHandler (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1311
1311	    if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1313	      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1316	        regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1318	        if(HAL_DMA_STATE_ABORT == hdma->State)
1345	        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1369	          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1381	          if(hdma->XferCpltCallback != NULL)
1384	            hdma->XferCpltCallback(hdma);
SAI_DMATxCplt (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2773
2773	  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2775	  if (hdma->Init.Mode != DMA_CIRCULAR)
2790	  HAL_SAI_TxCpltCallback(hsai);
HAL_SAI_TxCpltCallback (hsai=0x24000ee4 <hsai_BlockA2>) at applications\sai_dma.c:93
93	}
SAI_DMATxCplt (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2792
2792	}
HAL_DMA_IRQHandler (hdma=0x24001014 <hdma_sai2_a>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1391
1391	    if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1566	}
DMA1_Stream2_IRQHandler () at applications\sai_dma.c:387
387	  rt_hw_interrupt_enable(level);
rt_hw_interrupt_enable () at rt-thread\libcpu\arm\cortex-m7/context_gcc.S:49
49	    MSR     PRIMASK, r0
50	    BX      LR
DMA1_Stream2_IRQHandler () at applications\sai_dma.c:391
391	}
stm32_putc (serial=0x2400a498 <uart_obj+400>, c=111 'o') at libraries\HAL_Drivers\drivers\drv_usart_v2.c:317
317	    return 1;

  • DMA1_Stream3_IRQHandler(rx)
  • 可见最终调用了HAL_SAI_RxHalfCpltCallback和HAL_SAI_RxCpltCallback
Continuing.

Breakpoint 3, DMA1_Stream3_IRQHandler () at applications\sai_dma.c:401
401	  rt_base_t level = rt_hw_interrupt_disable();
rt_hw_interrupt_disable () at rt-thread\libcpu\arm\cortex-m7/context_gcc.S:39
39	    MRS     r0, PRIMASK
40	    CPSID   I
41	    BX      LR
DMA1_Stream3_IRQHandler () at applications\sai_dma.c:402
402	  HAL_DMA_IRQHandler(&hdma_sai2_b);
HAL_DMA_IRQHandler (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1212
1212	  __IO uint32_t count = 0U;
1213	  uint32_t timeout = SystemCoreClock / 9600U;
1216	  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
1217	  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
1219	  tmpisr_dma  = regs_dma->ISR;
1220	  tmpisr_bdma = regs_bdma->ISR;
1222	  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
1225	    if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1240	    if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1252	    if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1264	    if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1266	      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
1269	        regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
1272	        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1296	          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1302	          if(hdma->XferHalfCpltCallback != NULL)
1305	            hdma->XferHalfCpltCallback(hdma);
SAI_DMARxHalfCplt (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2847
2847	  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2852	  HAL_SAI_RxHalfCpltCallback(hsai);
HAL_SAI_RxHalfCpltCallback (hsai=0x24000f7c <hsai_BlockB2>) at applications\sai_dma.c:67
67	}
SAI_DMARxHalfCplt (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2854
2854	}
HAL_DMA_IRQHandler (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1311
1311	    if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
1313	      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
1316	        regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
1318	        if(HAL_DMA_STATE_ABORT == hdma->State)
1345	        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
1369	          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
1381	          if(hdma->XferCpltCallback != NULL)
1384	            hdma->XferCpltCallback(hdma);
SAI_DMARxCplt (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2819
2819	  SAI_HandleTypeDef *hsai = (SAI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2821	  if (hdma->Init.Mode != DMA_CIRCULAR)
2835	  HAL_SAI_RxCpltCallback(hsai);
HAL_SAI_RxCpltCallback (hsai=0x24000f7c <hsai_BlockB2>) at applications\sai_dma.c:86
86	}
SAI_DMARxCplt (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_sai.c:2837
2837	}
HAL_DMA_IRQHandler (hdma=0x2400108c <hdma_sai2_b>) at libraries\STM32H7xx_HAL\STM32H7xx_HAL_Driver\Src\stm32h7xx_hal_dma.c:1391
1391	    if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
1566	}
DMA1_Stream3_IRQHandler () at applications\sai_dma.c:403
403	  rt_hw_interrupt_enable(level);
rt_hw_interrupt_enable () at rt-thread\libcpu\arm\cortex-m7/context_gcc.S:49
49	    MSR     PRIMASK, r0
50	    BX      LR
DMA1_Stream3_IRQHandler () at applications\sai_dma.c:407
407	}
stm32_putc (serial=0x2400a498 <uart_obj+400>, c=99 'c') at libraries\HAL_Drivers\drivers\drv_usart_v2.c:317
317	    return 1;


网站公告

今日签到

点亮在社区的每一天
去签到