LoginSignup
3
4

More than 5 years have passed since last update.

STM32CubeMX:DACをTIMで駆動する

Posted at

目標

 STM32F4のDACから2chの正弦波をTIMのタイミングで出す。

CubeMXの設定

Pinoutタブ

 DACからOUT1 ConfigurationとOUT2 Configurationのチェックを入れる。

 TIM4のInternal Clockにチェックを入れる。

Configurationタブ

 AnalogのDACボタンをクリック、DAC Configurationウインドウを開く。

 Parameter SettingsタブでDAC Out1 SettingsとDAC Out2 SettingsのTriggerをTimer 4 Trigger Out eventにする。
 DMA SettingsタブでAddをクリックしDMA RequestをDAC1にする。同じ手順でDAC2のDMAも作る。

 OkでDAC Configurationウインドウを閉じる。


 ControlのTIM4ボタンをクリック、TIM4 Configurationウインドウを開く。

 Prescalerに84-1、Counter Periodに1000-1にする。
 Trigger Event SelectionでUpdate Eventを選択する。

 OkでTIM4 Configurationウインドウを閉じる。


 コードを書き出す。

ソースコード

constexpr size_t len(1000);
static int16_t DAC1_buff[len];
static int16_t DAC2_buff[len];

for (size_t i(0); i < len; ++i)
{
    const float s(sinf((float)i / len * pi * 2));
    DAC1_buff[i] = (int16_t)(+s * 1800 + 2048);
    DAC2_buff[i] = (int16_t)(-s * 1800 + 2048);
}

HAL_TIM_GenerateEvent(&htim4, TIM_EVENTSOURCE_UPDATE);

HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)DAC1_buff, len, DAC_ALIGN_12B_R);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)DAC2_buff, len, DAC_ALIGN_12B_R);

HAL_TIM_Base_Start(&htim4);

while (__HAL_DMA_GET_COUNTER(hdac.DMA_Handle1) > 0 &&
       __HAL_DMA_GET_COUNTER(hdac.DMA_Handle2) > 0)
{
    osDelay(1);
}

HAL_TIM_Base_Stop(&htim4);

HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_1);
HAL_DAC_Stop_DMA(&hdac, DAC_CHANNEL_2);

結果

2018-06-19_10-39.png

 DAC1とDAC2をオシロで見てみた。
 1000ポイントで正弦波1周期を1kSPSで出力しているので、1secで1周期の正弦波となるが、正しくそのように出力されている。

その他

 今回はNormalモードだが、CircularにすればDACバッファを延々と送信し続けることができる。今回の例をCircularにすると1Hzの正弦波が延々と送信されることになる。
 また、今回は12bitモードだが、8bitモードにすることもできる。その場合、使用するメモリが半分で済むので、電圧分解能がそれほど高くなくていいなら8bitモードは良い選択肢になる。また、バス使用率が半分になるのも利点。

3
4
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
3
4