開発する環境
DCブラシレスモーターを駆動するため、3つのチャンネルをPWMに設定して使います。
マイコンボードはNUCLEO-F302R8、モータドライバ用基板はX-NUCLEOIHM07M1を使います。
CQ出版のサイトから購入しました。
モータードライバICはSTのL6230が搭載されています。
基板、ボリュームのホルダーは3Dプリンタで作りました。
L6230で矩形波駆動する場合に必要なPWM信号
下記のように駆動時はPWM波形、非駆動時はLを出す制御が必要です。
簡単に出せそうですが、非駆動時にLを出すことが容易ではありませんでした。
普通にPWMを設定してみる
PWM信号の生成はSTM32F302のTIM1を使用します。
CH1〜3を使って、3相分の信号を作ります。
CH Idle Stateという設定があり、これがきっとPWMを使ってない時の端子の論理なんだろう...と思い、L(Reset)にしました。デフォルトでL(Reset)になってました。
この設定でPWMを動作させるため、HALで定義されている関数を利用します。
CH1を動かすなら下記の通りです。
HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1);
HAL_TIM_PWM_Stop(&htim1, TIM_CHANNEL_1);
そう、CH Idle StateをL(Reset)にしても、非駆動時はLになりません。
CH1ではなく、CH1Nを使えば非駆動時はLになりますが、相補PWM用に用意されている端子機能です。
X-NUCLEOIHM07M1ではモータードライバICにはCH1/2/3が接続されているため、改造して相補PWM用の反転端子を接続する手段もあります。
が、できれば手を加えたくない...ということで、モータードライバICにあったPWMを作る方法を調べました。
PWM出力端子を非駆動時は強制的にLにする!
PWM用のタイマーを停止すると端子状態はH(Set)になるのは、HALの仕様なのでやむなし。
そこで、タイマーのレジスタを調べると、出力端子を強制的にH、Lにする機能がありました。
CH1とCH2はCCMR1レジスタに、CH3はCCMR2レジスタに端子機能の設定ビットがあります。
これをタイマーを動作させたまま、PWMと強制Lを切り替えれば実現できます。
相切り替えのタイミングで端子機能を変更してみる
無事実現できました!
タイマーは動作させたままでOKです。
CCMRレジスタの変更だとマイコンが変わった時に移植性が悪いので、専用の関数を作った方が良さそうです。
参考になるサイト
このサイトで同じ話題が出ていました。
"Idle State" Not Respected after PWM on STM32