1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

STM32F3のDACで正弦波を出す

Posted at

Nucleo-F303REを買ってみました。とりあえず動作確認用にDACで正弦波を出してみます。

今回はLチカのちょっと高度版、くらいの位置づけなので、割り込みでデータを更新して、というような事は扱いません。固定波形をひたすら出し続けるだけです。

C++のコードなので、C++が動く環境で動かしてください(あるいは、使用したい言語に書き直してください)。

__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_DAC1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
__HAL_RCC_TIM3_CLK_ENABLE();

GPIO_InitTypeDef gpio_dac1_1 = {
    .Pin = GPIO_PIN_4,
    .Mode = GPIO_MODE_ANALOG,
};
HAL_GPIO_Init(GPIOA, &gpio_dac1_1);

DAC_HandleTypeDef hdac = {
    .Instance = DAC1,
};
HAL_DAC_Init(&hdac);

DAC_ChannelConfTypeDef dac_conf = {
    .DAC_Trigger = DAC_TRIGGER_T3_TRGO,
    .DAC_OutputBuffer = DAC_OUTPUTBUFFER_ENABLE,
};
HAL_DAC_ConfigChannel(&hdac, &dac_conf, DAC_CHANNEL_1);

TIM_HandleTypeDef htim = {
    .Instance = TIM3,
    .Init = TIM_Base_InitTypeDef{
        .Prescaler = 0,
        .CounterMode = TIM_COUNTERMODE_UP,
        .Period = 72 - 1,
    },
};
HAL_TIM_Base_Init(&htim);

TIM_MasterConfigTypeDef tim_master = {
    .MasterOutputTrigger = TIM_TRGO_UPDATE,
};
HAL_TIMEx_MasterConfigSynchronization(&htim, &tim_master);

DMA_HandleTypeDef hdma_dac1_1 = {
    .Instance = DMA1_Channel3,
    .Init = DMA_InitTypeDef{
        .Direction = DMA_MEMORY_TO_PERIPH,
        .PeriphInc = DMA_PINC_DISABLE,
        .MemInc = DMA_MINC_ENABLE,
        .PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD,
        .MemDataAlignment = DMA_MDATAALIGN_HALFWORD,
        .Mode = DMA_CIRCULAR,
        .Priority = DMA_PRIORITY_MEDIUM,
    },
};
HAL_DMA_Init(&hdma_dac1_1);
hdac.DMA_Handle1 = &hdma_dac1_1;

constexpr uint16_t N = 1000;
static uint16_t buff[N] = {};

for (uint16_t i = 0; i < N; i++)
{
    buff[i] = static_cast<uint16_t>(
        sinf(i * 2 * 3.1416f / N) * 1024 + 2048);
}

__HAL_RCC_SYSCFG_CLK_ENABLE();
SYSCFG->CFGR1 |= SYSCFG_CFGR1_DAC1_TRIG1_RMP | SYSCFG_CFGR1_TIM6DAC1Ch1_DMA_RMP;

HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, reinterpret_cast<uint32_t *>(buff), N, DAC_ALIGN_12B_R);

HAL_TIM_Base_Start(&htim);

特に面倒な点はありません。F4等と同じような手順で使えます。
1点、SYSCFGの設定に気がづかず、ハマりました。リファレンスマニュアルちゃんと読めって話ですね。。。
DAC1とDMAの組み合わせ、DAC1とTIM3の組み合わせの際は、それぞれSYSCFGの設定が必要です。


SDS00008.png

72MHzをタイマで72分の1にして、1周期1000ポイントなので、1kHzの正弦波となります。
実際には1.00324kHzとカウントされていますが、これはNucleoにはHSEが未実装のため、HSIを使っていることによると思われます。データシートによるとHSIは25℃時で1%のエラーらしいので、0.3%程度の誤差は仕様の範囲内です。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?