前回の続き。
STM32マイコン STM32L010F4P6 で
マイクロサーボ SG92R を動かした。
データシートを確認する
STM32マイコン STM32L010F4P6のデータシートは前回と同じなので省略。
マイクロサーボSG92Rのデータシートそのものが見つからなかったので,
マイクロサーボ9g SG-90 のデータシートを参照する。
Specifications
- Operating voltage: 3.3V(~6V)
- 20ms(50Hz) PWM Period
- 0.5 ~ 2.4ms Duty Cycle
- 4.8V(~5V) Power and Signal
とのこと。
つまりサーボコネクタの赤色線を電源の+に, 茶色線をGNDに接続して橙色線に図に書かれている信号を入力すると動く。
STM32とSG92Rサーボを接続
前回の回路にSG92Rサーボを追加した。
STM32CubeIDEでプロジェクトを開く
前回のプロジェクトを再利用する。
CubeIDEをアップデートしたので Version: 1.8.0。
なんとC++17を選択できるようになっていたので選んでみた。
(前から選べたかも知れない。)
STM32L010F4P6のタイマ設定
PWM信号はSTM32L010F4P6のGeneral-purpose timerである TIM2 を PWM mode に設定して作ることにする。
タイマ割り込みを使わないのでTIM2 global interruptはデフォルト設定。
Application note AN4013 - st.com
STM32 cross-series timer overviewより引用。
PA0をTIM2_CH1に割り当ててPWM出力ピンにする。
(このピンにSG92Rの橙色線を接続する。)
とりあえずクロックは4MHzに設定する。
TIM2の設定。
- Clock Source(クロック源): Internal Clock
- Channel1: PWM Generation CH1
- Prescaler(プリスケーラ) : 1
- Counter Period (周期) : 39999
- auto-reload preload: Enable
- Output compare preload: Enable
Prescaler (PSC - 16 bits value)
Prescaler (PSC - 16 bits value) must be between 0 and 65 535.
Counter Period (AutoReload Register - 16 bits value )
Counter Period (AutoReload Register - 16 bits value ) must be between 0 and 65 535.
タイマ周期は50Hzになるように, 以下の計算式より算出した。
$$ Update_event = \frac{TIM\_ CLK}{(PSC+1) \times (ARR+1) \times (RCR+1)} $$ より
ほしい値は各レジスタの設定値なので
右辺の分母を両辺に掛けて, Update_event を両辺から割ると
$$ (PSC+1) \times (ARR+1) \times (RCR+1) = \frac{TIM\_ CLK}{Update\_ event} $$ となって
ここに
- TIM_CLK = 4 MHz つまり $4 \times 10 ^ 6$ Hz
- Update_event = 50 Hz
- RCR(16-bit repetition counter)は無いので RCR = 0 を代入して
$$ \begin{aligned} (PSC+1) \times (ARR+1) &= \frac{4 \times 10^6}{50} \\ &= \frac{4 \times 10^2 \times 10^4}{50} \\ &= \frac{400 \times 10^4}{50} \\ &= 8 \times 10^4 \\ &= 80000 \end{aligned} $$
STM32L010F4P6マイコンの ARRレジスタは16ビットレジスタなので, そのレジスタに設定できる最大値は $2^{16} - 1 = 65535$
計算で得られた値 80000 は ARRレジスタの最大値を超える値なので設定できない。
なのでプリスケーラでクロック源から1/2にする設定(PSC=1)にする。
$$ \begin{aligned} (1+1) \times (ARR+1) & = 80000 \\ 2 \times (ARR+1) & = 80000 \\ ARR+1 &= \frac{80000}{2} \\ ARR &= \frac{80000}{2} - 1 \\ &= 39999 \end{aligned} $$
結果
Prescaler (PSC - 16 bits value) には 1を
Counter Period (AutoReload Register - 16 bits value ) には 39999を
設定する。
SG92Rを動かすプログラム
SG92Rを0°から45°づつ180°まで繰り返し動くプログラムを書いてみた。
|
|
プロジェクトのビルド
Ctrl + B でビルド。
|
|
はい、エラー。
|
|
FLASH領域から溢れた。
あふれたのは仕方がないのでReleaseビルドにする。
|
|
デバッグ関連のコードが無くなるので、収まった。
ST-Linkでプログラミング
前回と同じなので省略。
実行
サーボ角度 0 度
- サーボに供給している電圧: 5.07 V
- PWM信号周期: $19.946 \mathrm{ms} \approx 20 \mathrm{ms}$
- Duty Cycle: $499 \mathrm{\mu s} \approx 0.5 \mathrm{ms}$
- PWM信号電圧: $3.28 \mathrm{V}$
周波数と周期の関係は $f = \frac{1}{T}$ なので $\frac{1}{19.946 \times 10 ^{-3}} = 50.135 \mathrm{Hz}$
サーボ角度 45 度
- Duty Cycle: $974 \mathrm{\mu s} \approx 0.97 \mathrm{ms}$
サーボ角度 90 度
- Duty Cycle: $1.446 \mathrm{ms} \approx 1.45 \mathrm{ms}$
サーボ角度 135 度
- Duty Cycle: $1.919 \mathrm{ms} \approx 1.92 \mathrm{ms}$
サーボ角度 180 度
- Duty Cycle: $2.393 \mathrm{ms} \approx 2.4 \mathrm{ms}$
ここでもう一度マイクロサーボSG-90のデータシートを確認すると
データシートに書かれたとおりの信号を与えている。
Position “0” (1.45 ms pulse) is middle, “90” (~2.4 ms pulse) is all the way to the right, “-90” (~ 0.5 ms pulse) is all the way left.
データシートには
- 1.45 ms pulse の時に「中心」
- 2.4 ms pulse の時に「右端」
- 0.5 ms pulse の時に「左端」 となっているが, 今回は時計回りいっぱいを角度0, 反時計回りいっぱいを角度180にした。