今回は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出力の記事は以下をご覧になってください。
コメントを書く