北の国から

忘れたことを思い出す為の記録

STM32F303k8+HALで相補PWM生成を試す(Qiita修正版)

内容

  • CubeMXでの設定
  • 生成されたプログラムへの追加点

CubeMxでの設定

まず,303k8用にprojectを作成します.

今回はnucleo-303k8を使っていきます.

初期状態はこんな感じです。

first.png

pinoutタブ

ツリーのPeripheralsからTIM1を展開し,Channel1の設定を PWM Generation CH1 CH1N にします.

すると, 18pin → TIM1_CH1 13pin → TIM1_CH1N と設定されます。

second.png

注意してほしい点として,303k8では相補PWMはAdvanced timerであるTIM1しか使えません.

TIM15,16,17にも相補のチャンネルがあります.

TIM2やTIM3などのGeneral-purpose timerでは相補PWMはサポートされていないので気を付けましょう.

configurationタブ

ピンの設定が完了後,configurationタブに移動し,TIM1の各値を設定していきます.

third.png

値を設定するタブは - Counter Settings - PWM Generation Channel 1 and 1N の2つです.

まずCounter SettingsタブでPWMの周波数を設定します.

今回は20kHzでPWMを出力するようにPrescalerとCounter Periodを決めます。

動作クロックは内部の8MHzを使うので Prescaler:0 Counter Period:400-1 (カウントは0からなので1引いた399を設定する) とします.

PWM Generation Channel 1 and 1Nタブでは Mode: Assymetric PWM1 とします.

次にデッドタイムの設定を行います.

Break And Dead Time managementタブの一番下の欄に Dead Time:10 (0-255で任意の値) と設定します.

このように設定できるのは見やすくて良いですね.

無題.png

ここまで設定したら,コードを生成します.

fourth.png

プログラムへの追加

私が作成したソースはこちらに上がっています。Src/main.cが本体です。

自動生成されたソースに追加した関数について解説します.

user関数の追加

PWMを扱いやすくするために以下の関数を定義します. プロトタイプ宣言は適宜お願いします.

void user_tim1_pwm_setvalue(float value)
{
   TIM_OC_InitTypeDef sConfigOC;
   sConfigOC.OCMode = TIM_OCMODE_ASSYMETRIC_PWM1;
   sConfigOC.Pulse = (uint32_t)((400)*value);
   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
   sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
   sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
   sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
   HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);
   HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
   HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);
}

この関数が相補で出力する際のポイントとなります.

出力する値を決めます. sConfigOC.Pulse = (uint32_t)((400)*value);

設定値を反映します. HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1);

CH1へ出力します. HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); CH1Nへ出力します. HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);

一番最後のHAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_1);がないと,CH1Nからは出力されません.

できたらビルドして書き込んで動かしてオシロで見ると以下のような波形が得られると思います.

image