2021年2月7日日曜日

STM32CubeIDE: I2SをDMAで使う

DMA経由でI2S通信を行います。48kHz/16bitでLch、Rchそれぞれ16bit値をインクリメント、デクリメントして送信します。DACに入力するとL/Rで逆位相のノコギリ波が出力されます。

STM32CubeIDE: Version 1.5.1
Target board: Nucleo-F446RE

MXの設定



Real Audio Frequencyが47.619kHzとなっていますがI2SのクロックがMCUの内部クロックに依存しているためで、正確に48kHzにするためには元になるClockをうまく調整する必要があります。


Addボタンを押してSPI2_TXを選択するとDMA Request Settingsを設定できるようになります。SPI2_TXとなっているのは、I2SはSPIと同じハードウェアを利用しているためです。

メモリの値を連続して送信するため、ModeはCiruclarにします。Data WidthをHalf Wordに設定します。

Multimedia
  I2S2
    Mode
      Mode: Half-Duplex Master
  Configuration
    Parameter Settings
      Generic Parameters
        Selected Audio Frequency: 48KHz
    DMA Settings
      SPI2_TX
        DMA Request Settings
          Mode: Circular
          Peripheral: Data Width: Half Word
          Memory   : Data Width: Half Word

Pinout



main.cにコードを追加


/* USER CODE BEGIN PV */
uint16_t tx_buffer[2] = { 0, 0 };
/* USER CODE END PV */

割り込みで処理するため、送信するデータを大域変数で定義します。

  /* USER CODE BEGIN 2 */
  HAL_I2S_Transmit_DMA(&hi2s2, tx_buffer, 2);
  /* USER CODE END 2 */

DMAをCircularモードにしているので、1度だけI2S送信を開始します。DMAを使う場合はHAL_I2S_Transmit_DMA()を使います。

/* USER CODE BEGIN 4 */
void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
	tx_buffer[0] ++;
}

void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
{
	tx_buffer[1] --;
}
/* USER CODE END 4 */

割り込みハンドラを定義します。Lch/Rchそれぞれ送信が完了した時点でインクリメント/デクリメントしています。

I2S出力信号


出力信号をAnalog Discovery 2のScope機能とLogic機能で観測しました。


上側のScopeはC1がWS、C2がBCLKで、WSが47.634kHz、BCKが1.5244MHzとなっています。

下側のLogicを見るとLchがインクリメント、Rchがデクリメントされています。

0 件のコメント:

コメントを投稿