こんにちは、ショウです。
前回PCとシリアル通信ができるようになりました。
今回はモータを動かすためのPWMをタイマー機能を使ってPWMを出力してみたいと思います。
CubeMXの設定
今回はPB10のピンを出力ピンにしてPWMを生成したいと思います。
PB10のピンに設定できるPWMを出力できるタイマーはTIM2_CH3です。
PB10 にTIM2_CH3をクリックして設定すると黄色になります。
これはTIM2のどの機能を使うか設定されていない状態になります。
Categoriesの中のTimersからTIM2を選択してModeを決めます。
Channel3をPWM_Generation CH3を選びます。
PWM_GenerationがPWMを出力するモードになります。
ここまで設定したらマイコンのクロックの設定をします。
Clock Configurationのダブに移動します。
HCLKのところに最大周波数が書いてあるので書いてある最大周波数を入力します。最大周波数を入力すると生成できる最大クロックに変換してくれます。
今回は最大周波数の170MHzを生成できるので170MHzになります。
TIM2に使うクロックはAPB1_TimerClocksなので確認するとHCLKと同じ170MHzに設定されています。
ここからPWMを出力するための周期を設定するPrescalerとAutoReloadRegisterの値を設定します。
Pinout&ConfigurationタブのTIM2のConfigurationに設定箇所があるので移動します。
今回は1kHzのPWMを生成することにします。
Prescalerは何クロックごとにタイマーのCNTをカウントアップするかを設定し、AutoReloadRegisterはCNTがいくつになったらクリアするかを設定しています。これを使って周波数を設定します。
1kHzを生成するにはPrescalerを1699、AutoReloadRegisterを99に設定しました。
これでHCLKが(1699+1)クロックでCNTを1カウントアップし、CNTが99回カウントアップするとクリアされて0に戻るようになります。
これで1kHzのPWMが生成されます。
モータ制御にPWMを使う時はDuty比を設定します。
Duty比はCCRレジスタに書き込んだ値に応じて設定されます。CCRレジスタはARRレジスタの値をDuty100%とするので今回は99になったときが100%になります。
CCRはPWMを出力する時に設定します。
LLライブラリを使ったPWM出力設定
ここからPWMを出力するために使うLLライブラリの関数を確認します。
まずはタイマーを起動しPWMを出力するピンを指定します。
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3); LL_TIM_EnableCounter(TIM2); cen を変更
この2つの関数を使ってタイマーを起動します。
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);
これはTIMxキャプチャ/比較有効レジスタというレジスタでピンの出力設定をしています。今回はCH3を選択してPB10からPWMを出力できるようにしています。
LL_TIM_EnableCounter(TIM2);
これはTIMx制御レジスタ1の中のCENというビットを設定しています。このビットが1になるとタイマーのカウントが開始されます。
これを設定するとタイマーがスタートしてPWMを出力できるようになります。
PWMのDuty比はCCRレジスタで設定します。
LL_TIM_OC_SetCompareCH3(TIM2,pwm);
これがCCRレジスタを設定する関数です。CH3はチャンネルを指しています。この関数でCCRの値を第2引数に設定すると、設定したCCRの値に対応したDuty比でPWM出力がされます。
関数化する時にはCCRの値がARRの値を超えないようにガードしています。
モータ回してみた
家にあったモータドライバTA7291Pを使ってモータを回してみました。
PA9とPC7を回転方向のGPIOに設定して設定したDuty比に応じて回転するか確認しました。
簡単にDutyを0から100に、100から0にするプログラムを用意して動作させました。
参考URL