LoginSignup
1
0

More than 5 years have passed since last update.

STM32CubeMX:DACとADCを同期する

Last updated at Posted at 2018-06-19

 前回(ADC編)前々回(DAC編)で、決まった周期でDACあるいはADCを駆動する方法を紹介しました。また、ADC編の最後にはDACで出力した正弦波をADCで測定したグラフも紹介しました。ただ、その時はDACとADCの同期が取れていないため、ADCの結果は位相ずれが発生していました。
 ということで、今回はDACとADCの同期を行いたいと思います。

CubeMXの設定

 ADCに使っているTIM(今回はTIM3)のSlave ModeをTrigger Modeにします。
 Trigger Sourceを適切な値に設定します。今回はマスタがTIM4でスレーブがTIM3なので、ITR3を選択します。詳しくは各MCUのリファレンスマニュアル(STM32F4:RM0090, STM32F1:RM0008 等)の"汎用タイマ→レジスタ→スレーブモード制御レジスタ(SMCR)"を参照してください。

 CubeMXの設定はこれだけです。コードを生成してソースコードの変更に移ります。

ソースコード

constexpr size_t DAC_len(1000);
constexpr size_t ADC_len(1000);
static uint8_t DAC1_buff[DAC_len];
static uint8_t DAC2_buff[DAC_len];
static uint16_t ADC_buff[ADC_len];

for (size_t i(0); i < DAC_len; ++i)
{
    const float s(sinf((float)i / DAC_len * pi * 2));
    DAC1_buff[i] = (uint8_t)(+s * 110 + 128);
    DAC2_buff[i] = (uint8_t)(-s * 110 + 128);
}

memset(ADC_buff, 0, sizeof(ADC_buff));

HAL_TIM_GenerateEvent(&htim4, TIM_EVENTSOURCE_UPDATE);
HAL_TIM_Base_Stop(&htim3);
HAL_TIM_GenerateEvent(&htim3, TIM_EVENTSOURCE_UPDATE);

HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, (uint32_t *)DAC1_buff, DAC_len, DAC_ALIGN_8B_R);
HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_2, (uint32_t *)DAC2_buff, DAC_len, DAC_ALIGN_8B_R);
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)ADC_buff, ADC_len);

HAL_TIM_Base_Start(&htim4);

while (__HAL_DMA_GET_COUNTER(hdac.DMA_Handle1) > 0 ||
       __HAL_DMA_GET_COUNTER(hdac.DMA_Handle2) > 0 ||
       __HAL_DMA_GET_COUNTER(hadc1.DMA_Handle) > 0)
{
    osDelay(1);
}

HAL_TIM_Base_Stop(&htim4);
HAL_TIM_Base_Stop(&htim3);

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

for (size_t i(0); i < ADC_len; ++i)
{
    printf("%u %hu\n", i, ADC_buff[i]);
}

 DACのバッファ初期化やADCのバッファ出力等が近い場所にあるため、少し複雑です。が、処理としてはDAC単体、ADC単体のときとほとんど同じです。
 唯一違うのは、TIM3(ADCトリガ)をソフトウェアで開始しない点と、TIM4/TIM3のカウンタクリアの順番に注意する必要がある点です。
 TIM3はTIM4のアップデートで開始しますが、TIM4をクリアするためにソフトウェアでアップデートイベントを発生させます。この際にTIM3が開始してしまうので、先にTIM3をクリアしてしまっても意味がありません。そのため、先にマスタ側をクリアし、またスレーブ側をクリアする前にスレーブを停止させる必要があります。

結果

2018-06-19_12-00.png

 前回のグラフと比べて、確かに位相ずれが減っているのがわかります。厳密に位相ずれがゼロになるわけではありませんが、ジッターを大幅に減らすことが可能になります。

履歴

2018-06-19

  • 転送終了待ちwhileの条件を修正
1
0
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
0