SSブログ

STM32 TIM17とDMA Channel1でDACを駆動する [電子工作]

STM32でDACをDMAで駆動する場合、通常はTIM6/7の出力をトリガイベントとしてDACに繋げるかと思います(リファレンスにもそう書いてあるし)。

が、

STM32F051ではDAC, USARTx_RX, SPI1_TX, I2Cx_RXでChannel3を取り合っているので
あまりChannel3を使いたくない気がします。

stm32f0x1_dma_mappiing.png

USARTのRXはDMA使わなくてもいーんじゃね?というとそのような気もしますが、
Channel1がなんとなくヒマそうなので、Channel1にリクエストできるTIM17を使ってやってみます。

CubeMXでの設定

TIM17

Prescaler (PSC - 16 bits value) : 0
Counter Mode : Up
Counter Period (AutoReload Register - 16 bits value ) : 3000-1 * (48MHz / 16KHz = 3000)
Internal Clock Division (CKD) : No Division
Repetition Counter (RCR - 8 bits value) : 0
auto-reload preload : Disable

DMA request : TIM17_CH1/UP
Stream : DMA1_Channel1
Direction : Memory To Peripheral
Priority : Low

TIM17_CH1/UP: DMA1_Channel1 DMA request Settings:
Mode: Circular *
Peripheral Increment: Disable
Memory Increment: Enable *
Peripheral Data Width: Half Word
Memory Data Width: Half Word

DAC Out1 Settings:
Output Buffer : Enable
Trigger : None

DACのTriggerをNoneにしておくのがミソです。

Code Generateして、main.cに以下を追記

Private Variables (16KHzサンプリングでの440Hzのサイン波)
const uint16_t sine_440[] = {
  0x003, 0x022, 0x07E, 0x115, 0x1E1, 0x2DD, 0x401, 0x545,
  0x69D, 0x800, 0x964, 0xABC, 0xC00, 0xD24, 0xE20, 0xEEC,
  0xF83, 0xFDF, 0xFFF, 0xFDF, 0xF83, 0xEEC, 0xE20, 0xD24,
  0xBFF, 0xABC, 0x964, 0x801, 0x69D, 0x545, 0x402, 0x2DD,
  0x1E1, 0x115, 0x07E, 0x022
  };


デバイス初期化の後で
(DMAをCircularモードにしているので、止めない限り出力しっぱなし)
  /* Enable DAC */
  HAL_DAC_Start(&hdac1, DAC_CHANNEL_1);

  /* Enable the DMA channel */
  HAL_DMA_Start_IT(htim17.hdma[TIM_DMA_ID_UPDATE],
                   (uint32_t)sine_440, (uint32_t)&(hdac1.Instance->DHR12R1), 36);
  
  /* Enable the TIM Update DMA request */
  __HAL_TIM_ENABLE_DMA(&htim17, TIM_DMA_UPDATE);

  /* Enable the Peripheral (Start Timer) */
  __HAL_TIM_ENABLE(&htim17);  


HAL_TIM_Base_Start_DMA()は、なぜかDMAの転送先をタイマのARRレジスタにしてしまうので、
参考にして開始処理を書いてみました。
nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:パソコン・インターネット

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。