STM32 HALを使ってPWM出力してみる

  • 2020.08.01
  • HAL
STM32 HALを使ってPWM出力してみる

今回はPWM出力を確認してみます。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Configurator: STM32CubeMX Version5.6.0
Board: STM32Nucleo-F401RE

PWMとは?

PWMとは、Pulse Width Modulation の略です。日本語ではパルス幅変調といいます。
I/Oポートからパルスを出力する機能です。
パルス幅を変えることでモーターを制御したり、LEDの明るさ調節を行ったりすることができます。

今回はボードに載っている緑色のLED(LD2)がたまたまPWM出力ポートにつながっているので、それを使ってみます。

プロジェクトを作成する

IDEを起動し、File- New – STM32 Project を選択し、Target Selection ウィンドウが出たら Board Selector タブを選択し Boards List から NUCLEO-F401RE を選択し Next ボタンを押します。

Project 名に F401PWmHAL と入力し、Finishボタンを押します。
Initialize all peripherals with their default Mode ? と聞いてくるので Yesを押します。
This kind of project is associated with the STM32CubeMx perspective. Do you want to open this perspective now ? と聞いてくるので Yesを押します。

コードジェネレーターでPWM出力を設定する

今回設定をする端子は下側の PA5 です。
PA5を右クリックし、リストから TIM2_CH1 を選択します。

そして Pinout & Configuration – Categories – Timers – TIM2 を選択し、
TIM2 Mode and Configuration – Mode – Channel1 のリストから PWM Generation CH1 を選択します。

TIM2 Mode and Configuration – Configuration – Parameter Settings を以下のように設定します。

HCLK が 84MHz なので

84MHz / ((83 + 1) * (999 + 1)) = 84 * 10^6 Hz / (84 * 10^3) = 10^3 Hz = 1 kHz

この設定で周期が 1kHz の PWM出力になります。

Project Explorer で F401PWmHAL を選択し、Project – Build Project でビルドします。

コードを追加する

main()の while()ループの部分を以下の通りにコーディングします。

/* USER CODE BEGIN WHILE */
  HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
  while (1)
  {
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 250);
    HAL_Delay(100);
    __HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 500);
    HAL_Delay(100);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

ビルドして実行する

ビルドしてエラーがないことを確認してプログラムを実行します。

Run – Resume

緑色のLEDが明るくなったり暗くなったりすれば成功です。

確認のためにオシロスコープで波形を観測してみました。

周波数は約 1kHz になっていることが確認できました。

コードの概要

HAL_TIM_PWM_Start() でPWM出力を開始します。

__HAL_TIM_SET_COMPARE はレジスタ CCR の値を変更するマクロです。

__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_1, 250);

で TIM2 , CH1 のデューティ比を変えることができます。

CCRは32ビットのレジスタですが、そんなに大きな値は必要ありません。

第3引数の値が 500 でデューティ比が 50% になりました。(上の波形の左側の部分)
250 の時に H レベルの期間が 1/4 になっています。(上の波形の右側の部分)

これらの値はカット&トライで確認して決めました。

( CCRにいくつ値を書いたらデューティ比が50%になるなんて説明はどこにも書いていないからです)

補足します。
リファレンスマニュアルに以下の記述がありました。

パルス幅変調(PWM)モードでは、TIMx_ARR レジスタの値によって決められた周波数と TIMx_CCRx
レジスタの値によって決められたデューティサイクルで信号を生成できます。

設定画面の Counter Period ( == 999 ) が TIM2_ARR の値になります。
アップカウンタでは1カウント目が0になる仕様なので、分母は 1000 です。

PWM出力の信号がLEDのアノードにつながっているので、__HAL_TIM_SET_COMPARE()の第3引数の値を n とすると

n / 1000 の期間だけ LED が点灯することになります。( n が TIM2_CCRx の値 です )

デューティ比を確認するとなると、さすがにオシロスコープが必要ですね。

秋月電子で ADALM2000 というものが売っています。

本格的なオシロには及びませんが、ちょっと波形を確認したい場合には便利ですし、その他の機能もついています。

ちょっと脱線しましたが、決して秋月電子のスパイではありません^^

自宅で仕事することが多くなった時に、耐え切れずにネット購入しました^^

さていかがでしたか、皆さまはうまく PWM 出力できましたか?

LLを使ったPWM出力の記事は以下をご覧になってください。

STM32 LLでPWM出力してみる

HALカテゴリの最新記事