STM32F303k8+HALで相補PWM生成を試す(Qiita修正版)
内容
- CubeMXでの設定
- 生成されたプログラムへの追加点
CubeMxでの設定
まず,303k8用にprojectを作成します.
今回はnucleo-303k8を使っていきます.
初期状態はこんな感じです。
pinoutタブ
ツリーのPeripheralsからTIM1を展開し,Channel1の設定を
PWM Generation CH1 CH1N
にします.
すると, 18pin → TIM1_CH1 13pin → TIM1_CH1N と設定されます。
注意してほしい点として,303k8では相補PWMはAdvanced timerであるTIM1しか使えません.
TIM15,16,17にも相補のチャンネルがあります.
TIM2やTIM3などのGeneral-purpose timerでは相補PWMはサポートされていないので気を付けましょう.
configurationタブ
ピンの設定が完了後,configurationタブに移動し,TIM1の各値を設定していきます.
値を設定するタブは - 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で任意の値) と設定します.
このように設定できるのは見やすくて良いですね.
ここまで設定したら,コードを生成します.
プログラムへの追加
私が作成したソースはこちらに上がっています。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からは出力されません.
できたらビルドして書き込んで動かしてオシロで見ると以下のような波形が得られると思います.