職業訓練44日目 H8マイコン入門(アセンブラ言語による実習)

パルスモータの制御

パルスモータとは

パルス電力を入力として回転する(→マイコン制御と相性が良い)
長所:正確な回転(位置決め)を制御できる。

N極とS極をもつロータ(回転子)の周囲に電磁石(固定子)を配置した構造になっていて、
電磁石を磁化するパルスデータによって正確な位置決め制御ができる。

制御方式

  • 1相励磁方式:1相のみに電流を流す
  • 2相励磁方式:2相に電流を流す、1相励磁の2倍のトルクが得られる
  • 1-2相励磁方式:1相励磁と2相励磁を交互に行う、移動角度が1相励磁の半分になる
パルスモータの回転制御

面倒なので回路図は割愛…。

回路の特徴としては、

といったあたりかな。

  • 1相励磁方式
	.CPU 300HA
	.SECTION PROG6, CODE, LOCATE=H'000000

P1DR	.EQU	H'FFFFC2
P1DDR	.EQU	H'FFFFC0
P6DR	.EQU	H'FFFFCB
P6DDR	.EQU	H'FFFFC9

	.SECTION ROM, CODE, LOCATE=H'000100

	MOV.L	#H'FFFF00, ER7

	MOV.B	#H'FF, R0L
	MOV.B	R0L, @P1DDR
	MOV.B	R0L, @P6DDR
	MOV.B	#B'10001000, R0H		; 回転データ

LOOP:	MOV.B	R0H, @P6DR
	MOV.B	R0H, R1H
	NOT.B	R1H
	MOV.B	R1H, @P1DR			; 回転データをLEDに出力
	JSR	@TIM2
	ROTR.B	R0H				; 右に1ビットローテイト
	JMP	@LOOP

TIM2:	MOV.W	#D'30, E5			; 0.3秒のタイマサブルーチン
L2:	JSR	@TIM1
	DEC.W	#1, E5
	BNE	L2
	RTS

TIM1:	MOV.L	#D'20000, ER6			; 10msのタイマサブルーチン
L1:	DEC.L	#1, ER6
	NOP
	BNE	L1
	RTS

	.END
  • 2相励磁方式

上記コードの回転データを"1100"に変更する。

;	MOV.B	#B'10001000, R0H		; 回転データ
	MOV.B	#B'11001100, R0H		; 回転データ
  • 1-2相励磁方式

1相励磁と2相励磁を交互に出力する。
実行すると、1相励磁に比べてステップ角が半分になる。

	.CPU 300HA
	.SECTION PROG7, CODE, LOCATE=H'000000

P1DR	.EQU	H'FFFFC2
P1DDR	.EQU	H'FFFFC0
P6DR	.EQU	H'FFFFCB
P6DDR	.EQU	H'FFFFC9

	.SECTION ROM, CODE, LOCATE=H'000100

	MOV.L	#H'FFFF00, ER7

	MOV.B	#H'FF, R0L
	MOV.B	R0L, @P1DDR
	MOV.B	R0L, @P6DDR
	MOV.B	#B'10001000, R0L		; 回転データ1
	MOV.B	#B'11001100, R0H		; 回転データ2

LOOP:	MOV.B	R0L, @P6DR			; 回転データ1を出力
	MOV.B	R0L, R1H
	NOT.B	R1H
	MOV.B	R1H, @P1DR
	JSR	@TIM2
	MOV.B	R0H, @P6DR			; 回転データ2を出力
	MOV.B	R0H, R1H
	NOT.B	R1H
	MOV.B	R1H, @P1DR
	JSR	@TIM2
	
	ROTR.B	R0L
	ROTR.B	R0H

; 0.3秒のタイマサブルーチン
TIM2:	MOV.W	#D'30, E5
L2:	JSR	@TIM1
	DEC.W	#1, E5
	BNE	L2
	RTS

; 10msのタイマサブルーチン
TIM1:	MOV.L	#D'20000, ER6
L1:	DEC.L	#1, ER6
	NOP
	BNE	L1
	RTS

	.END

DCモータの制御

ドライバICによる回転方向制御

使用したドライブIC:TA7257P
→DCモータの回転を、正転、逆転、ストップ、ブレーキの4パターンを制御できる。

TA7257Pの動作

IN1 IN2 OUT1 OUT2 動作
0 0 Z Z ストップ
0 1 L H 正転
1 0 H L 逆転
1 1 L L ブレーキ

※Zはハイインピーダンス(ってWikipediaに書いてあった…

回路図はサックリと割愛…。

	.CPU 300HA
	.SECTION PROG8, CODE, LOCATE=H'000000

P5DR	.EQU	H'FFFFCA
P5DDR	.EQU	H'FFFFC8
P2DR	.EQU	H'FFFFC3
P2DDR	.EQU	H'FFFFC1
P1PCR	.EQU	H'FFFFD8

	.SECTION ROM, CODE, LOCATE=H'000100

	MOV.L	#H'FFFF00, ER7

	MOV.B	#H'00, R0L
	MOV.B	#H'FF, R0H
	MOV.B	R0L, @P2DDR
	MOV.B	R0H, @P2PCR		; ポート2のプルアップを有効
	MOV.B	R0H, @P5DDR

LOOP:	MOV.B	@P2DR, R0L		; ポート2のDIPスイッチからデータを入力
	NOT.B	R0L			; ONで"1"とするため反転
	BTST	#0, R0L			; DIPスイッチ1をチェック
	BEQ	L1			; スイッチがOFFの場合、L1へ
	BSET	#0, R1L			; ビット0のLED点灯
	BSET	#2, R1L			; モータICの1ピンを"1"
	JMP	@B1
L1:	BCLR	#0, R1L			; ビット0のLED消灯
	BCLR	#2, R1L			; モータICの1ピンを"0"

B1:	BTST	#1, R0L			; DIPスイッチ2をチェック
	BEQ	L2			; スイッチがOFFの場合、L2へ
	BSET	#1, R1L			; ビット1のLED点灯
	BSET	#3, R1L			; モータICの2ピンを"1"
	JMP	@B2
L2:	BCLR	#1, R1L			; ビット1のLED消灯
	BCLR	#3, R1L			; モータICの2ピンを"0"

B2:	MOV.B	R1L, @P5DR		; ポート5へ点灯、回転データを出力

	JMP	@LOOP
	.END

上記のプログラムを実行すると、

  • DIPスイッチ1がOFF、DIPスイッチ2がONの場合、正転
  • DIPスイッチ1がON、DIPスイッチ2がOFFの場合、逆転

となるはず。

テキストには、
「モータの回転軸に触れながら制御を行えば、ストップとブレーキの違いを体感できる」
とありましたが、鈍感な自分には残念ながら…。

PWM機能による速度制御

ITUのPWMモードでDCモータを動作させる。

  1. カウンタクロックの設定(クロックの分周を設定する)
  2. カウンタクリア条件の設定(GRAまたはGRBでクリアする、今回はGRBでクリアとする)
  3. PWMモードの設定
  4. GRAの設定(PWM波形が"1"に立ち上がるタイミングを設定する)
  5. GRBの設定(PWM波形が"0"に立ち上がるタイミングを設定する)
  6. カウント開始

例)出力周波数が10kHz(周期10^-4 = 0.0001s)として、
  クロックが0.625μsで、分周を1/8に設定すると、以下の式でGRAが割り出せる。
  →0.0001s / (0.0625μs * 8) = 0.0001s / 0.0000005s = 200 = C8
  デューティー比50%のPWM波形を発生させるなら、
  GRAには"C8"を設定し、GRBにはC8 * 50% = 100なので"64"を設定する。

と、ここでPWM波形をオシロスコープで確認するプログラムを書くところですが、
だんだん面倒になってきたので割愛…。

PWM機能を使ってDCモータを動作する回路ですが、回路図はやっぱり割愛するとして、
回路の主なパーツは以下の通り。

	.CPU 300HA
	.SECTION PROG10, CODE, LOCATE=H'000000

TSTR	.EQU	H'FFFF60		; タイマスタートレジスタ
TMDR	.EQU	H'FFFF62		; タイマモードレジスタ
TCR0	.EQU	H'FFFF64		; タイマコントロールレジスタ
GRA0	.EQU	H'FFFF6A		; ジェネラルレジスタGRA0
GRB0	.EQU	H'FFFF6CA		; ジェネラルレジスタGRB0
P4DR	.EQU	H'FFFFC7
P4DDR	.EQU	H'FFFFC5
P4PCR	.EQU	H'FFFFDA

	.SECTION ROM, CODE, LOCATE=H'000100

	MOV.L	#H'FFFF00, ER7

	MOV.B	#H'00, R0L
	MOV.B	#H'FF, R0H
	MOV.B	R0L, @P4DDR
	MOV.B	R0H, @P4PCR

	MOV.B	#B'00100011, R0H	; GRAによりクリア、1/8分周データ
	MOV.B	R0H, @TCR0
	BSET	#0, @TMDR		; PMWモード設定

	MOV.W	#H'00C8, E1
	MOV.W	E1, @GRA0		; GRA0設定

LOOP:	BTST	#4, @P4DR		; ポート4のスイッチをチェック
	BEQ	D50			; スイッチがONならD50へ
	MOV.W	#H'00C8, E1		; GRB0データ(デューティー比100%)
	MOV.W	E1, @GRB0		; GRB0設定
	JMP	@D100

D50:	MOV.W	#H'0064, E1		; GRB0データ(デューティー比50%)
	MOV.W	E1, @GRB0		; GRB0設定

D100:	BSET	#0, @TSTR		; ITUカウンタスタート

	JMP	@LOOP

	.END

上記のプログラムを実行すると、
スイッチ1を押すとモーターがゆっくり(デューティー比50%)で回転し、
スイッチ1を離すとモーターが速く(デューティー比100%)で回転するはず。

以上、モーターの制御でした!
あー、まとめるのに何日かかったのだろうか…orz