LoginSignup
1
1

More than 1 year has passed since last update.

STM32CubeMXで生成したコードのDMAがうまく機能しなかった時の確認と対処

Last updated at Posted at 2021-10-23

UART、ADC諸々のDMAがうまく動かない時の対処法メモ

結論

CubeMX v6.2.1現在の生成コードが間違ってる場合がある。

MCUや使用するペリフェラルによって、イニシャライズの順序が変わる場合があります。
この時DMAのInitの順番が変わると、DMAの動作が正常にならない場合があります。

生成されるダメなInitコードの例

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_DAC1_Init();
  MX_FDCAN1_Init();
  MX_SPI2_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();

  //DMA初期化がペリフェラル初期化の前にいたり後ろにいたりする
  MX_DMA_Init();

  MX_I2C2_Init();
  MX_USART2_UART_Init();

MX_DMA_Init();がDMAを使いたいペリフェラルの初期化よりも後に実行されるとその前に初期化が実行されたペリフェラルでDMAが正常に機能しない
上の場合だとADC~USART1までのDMAが正常に機能しない可能性があります。

修正する

DMAの初期化を、ペリフェラルの前に移動します。

  /* Initialize all configured peripherals */  
  MX_GPIO_Init();

 //DMAを使いたいペリフェラル初期化よりも前に持ってくる
  MX_DMA_Init();

  MX_ADC1_Init();
  MX_DAC1_Init();
  MX_FDCAN1_Init();
  MX_SPI2_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  MX_I2C2_Init();
  MX_USART2_UART_Init();

何が起きてるのか

コードの話

DMA_Initの中には、クロックの設定とNVIC割り込みに関する初期化が入っています。

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

  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);

そのためペリフェラル初期化→DMA初期化の順に行ってしまうと、DMAの各種設定が反映されません。

レジスタの状態

例としてUARTのDMA(DMA1 Ch5)を、サーキュラモード、メモリインクリメントで設定します。

正しい順序で初期化を行った場合

CIRC(Circular)とMINC(Momery increment)の設定が反映されています。

逆の順序で初期化を行った場合


この2つの設定が反映されていないのが見て取れます。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1