STM32のPWMの使い方まとめ
目次
基本的な PWM 出力
まずは CubeMX の設定変更やコードを最小限にした基本的な PWM 出力について説明します。
CubeMX で新規プロジェクトを作成し、CubeMx GUI で下記の設定を変更してください。
- Pinout and Configuration
- Timers
- TIM1
- Mode
- Clock Source : Internal Clock
- Channed1 : PWM Generation CH1
- Configuration
- Parameter Settings
- Counter Settings
- Prescaler : 15
- Counter Period(Auto Reload Register) : 999
コード生成をした後、Cube IDE で main.c に下記を追加してください。
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 699);
/* USER CODE END 2 */
PWM の周期は下記計算で導けます。HCLK は CubeMX の GUI 上で確認できますが、Nucleo STM32F4 評価ボードでは 16[MHz]でした。
初期状態では波形はのこぎり波となり、Counter Period(Auto Reload Register)に 999 が設定されているので、999 の次は 0 にリセットされる波形になります。
つまり、周期が 1ms、High 時間が 0.7ms の PWM 出力が行われることになります。
PWM 出力の論理を反転させる
PWM モードという設定があり、これを変更することで PWM の初期出力を High にするか Low にするか設定できます。
CubeMX で変更可能です。
- Pinout and Configuration
- Timers
- TIM1
- Configuration
- Parameter Settings
- PWM Generation Channel 1
- Mode : PWM mode 1 OR PWM mode 2
- PWM mode 1
- CCR 以下の時は High, CCR を超えると Low
- PWM mode 2
- CCR 以下の時は Low, CCR を超えると High
波形の種類(のこぎり波や三角波)を設定する
Counter モードの設定で波形の種類を変更できます。
Center Aligned Mode には 1-3 と種類がありますが、これはレジスタの更新イベントタイミングが異なるのみですので、波形の種類は同じです。
- Pinout and Configuration
- Timers
- TIM1
- Configuration
- Parameter Settings
- Counter Settings
- Counter Mode : Up OR Down OR Cennter Aligned Mode 1-3
レジスタの更新イベントタイミングを設定する
PWM の Duty や周期を更新するタイミング(UEV: Update EVent)は波形によって異なります。また、三角波の場合は更新しタイミングを設定することが可能です。
- Pinout and Configuration
- Timers
- TIM1
- Configuration
- Counter Settings
- auto reload preload : Enable
- Parameter Settings
- Counter Settings
- Counter Mode : Up OR Down OR Cennter Aligned Mode 1-3
加えて、auto reload preload 機能を有効に変更します。
auto reload preload は ARR(Auto Reload Resister)の値を変更する際のバッファーのようなもので、バッファーの値を変更しておけば Update Event のタイミングで自動的に ARR の値が更新されるというものです。
STMicro 公式のレファレンスマニュアルの図が分かりやすいのでこれで詳しく説明します。
- ARPE(Auto Reload Preload)が無効の場合
ARR(自動再ロードレジスタ)の値をプログラムで変更すると、当たり前ですがその変更が即時反映されます。
- ARPE(Auto Reload Preload)が無効の場合
ARR 値をプログラムで変更すると、まずは ARPE レジスタの値が更新されます。
そして、UEV のタイミングで自動的に ARR の値が ARPE レジスタの値で更新されるという処理になります。
この場合、ARR 値変更が実際に変更されるのはプログラムによる値の変更時ではなく、UEV のタイミングになることがポイントです。
組み合わせ PWM
組み合わせ PWM は 2CH の波形の組み合わせ(AND OR)てより複雑な PWM 波形を出力することができます。
- AND の場合
例として TIM1 の CH1 と CH2 を組み合わせて、三角波の途中で立ち下がる Duty50%の PWM 出力させます。
組み合わせた PWM 波形は CH1 の出力ポートから出力されます。
CubeIDE GUI による設定は下記のようにして下さい。
- Pinout and Configuration
- Timers
- TIM1
- Mode
- Clock Source : Internal Clock
- Channed1 : PWM Generation CH1
- Channed2 : PWM Generation CH2
- Configuration
- Parameter Settings
- Counter Settings
- Prescaler : 15
- Counter Period(Auto Reload Register) : 999
- PWM Generation Channel1
- Mode : Combined PWM2
- PWM Generation Channel2
- Mode : PWM mode 1
コード生成後、main.c に下記を追記して下さい。
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 299);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 799);
/* USER CODE END 2 */
- OR の場合
例として TIM1 の CH1 と CH2 を組み合わせて、三角波の途中で立ち下がる Duty50%の PWM 出力させます。
組み合わせた PWM 波形は CH1 の出力ポートから出力されます。
CubeIDE GUI による設定は下記のようにして下さい。
- Pinout and Configuration
- Timers
- TIM1
- Mode
- Clock Source : Internal Clock
- Channed1 : PWM Generation CH1
- Channed2 : PWM Generation CH2
- Configuration
- Parameter Settings
- Counter Settings
- Prescaler : 15
- Counter Period(Auto Reload Register) : 999
- PWM Generation Channel1
- Mode : Combined PWM1
- PWM Generation Channel2
- Mode : PWM mode 2
コード生成後、main.c に下記を追記して下さい。
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, 299);
__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 799);
/* USER CODE END 2 */
Discussion