第9週 ステッピングモータを動かす 自力でプログラムを書く
田舎住まいですから東京で呑むのもたいへんです。遠路はるばる特急電車に乗って出かけなければなりません。
先日、呑んでの帰り、気持ち悪くなって、これは飲み過ぎたかと思いましたが、電車に酔っただけでした。呑んで電車に乗ると、車酔いしがちですから気を付けましょう。
車酔いと酒酔いは相乗で襲ってくることもあり、その区別はなかなか難しいものがあります。ですから、これらの微妙な差はやはり経験を積んで体で覚えるほかありません。んなん覚えなくってもいいか。(^^;
今週は気合い入ってます。いきなり無謀な挑戦です!
やたら長いページでスクロールしまくりを強要してます、すんません。
■宿題提出
コンフィグレーションレジスタについて
疑問のままだったコンフィグレーションレジスタについて参考書とユーザーズガイドで調べるとともに試行錯誤で解決しました。
CPUの特殊機能としてあらかじめPICの機能を設定しておくためのビットがコンフィグレーションビットのようです。
このビットが1か0かでいろいろモードが変わると言うことです、たぶん。
たとえばbit2はウォッチドグタイマを動作させるかさせないかを決める機能を持っています。
このビットの集まり(bit0 - bit13の14個)がコンフィグレーションレジスタ。
とりあえずライタ書き込みの時必要とするのは
発振モード、ウォッチドグタイマ有無、パワーアップタイマ選択
です。よくわからないのでライタ書き込み時に設定していましたが、やはり疑似命令にもありました。
その疑似命令は
__config <expr>
です。参考書ではどう見てもアンダーバーが1個になっていますのでそのまま従って
_config <expr>
とやってみましたがエラーとなってしまいました。何度調べて試してもダメでこんな時には原典をと、ユーザーズガイドで調べると、あれま、アンダーバーは2個あるではないですか。(@_@)
わかりやすく半角スペースを入れて書くと
_ _config <expr>
ということです。もちろん実際はスペース入れずに続けて書きます。(くどい)
<expr>は上記3つの設定については
_HS_OSC (発振モード・HS)
_WDTE_OFF (ウォッチドグタイマOFF)
_PWRTE_ON (電源ONリセットON)
こちらはアンダーバー1個です。書式は&でつないで
__config _HS_OSC & _WDTE_OFF &
_PWRTE_ON
となります。
でも、各BITを数値で書いて
__config H'3FF2'
でも良いようです。
(追記 このあたりのことを第10週 に考察してあります。)
これでライタでの書き込み時にいちいち設定せずに済むようになりました。(^^)
ついでの話ですが INCLUDE の書式が参考書によって
include <file>
include "file"
あるいはCの書き方みたいに
#include <file>
とまちまちですが、やってみるとどれでもOKのようです。
自力でプログラムを書く
ステッピングモータを動かす
ただI/OポートをBITでON/OFFするだけのプログラムから始めます。
恰好のテーマがありました。ステッピングモータを動かしてみます。LED表示をチカチカやらせるだけではなんだか「作った」という実感に乏しいですが、モータがクルクル回れば「おお、オレが回したのだ」と実感できるじゃないですか。(^^)
ステッピングモータの簡単な駆動回路を組むには専用機能IC・PMM8713を使いますがこれが製造中止だそうです。仕方なくPLD(プログラマブルなロジックIC)で置き換えたりしていますが、これをPICでできないかと考えました。
準備:
PIC PIC16F84-10/P
トランジスタアレイ TD62064
ステッピングモータ PX244-03A オリエンタルモータ
パルス発生器 (下記回路図参照)
テーマ:
1.I/Oポートの使い方とアセンブラに慣れる。
2.条件判断、テーブル処理を使ってみる。
一見難しそうですが、割り込みも使わず初歩的なプログラムでいけそうです。
|
集中治療室状態のテスト(^^; |
前回のテスト回路基板をちょっと改造しました。
スイッチ(RA3)は正逆転切り替え用とします。
RA4には矩形波パルス発生回路をつなぎます。
パルス発生回路はシュミットトリガインバータで作った簡単なものです。電源は5vdc、24vdcの2電源用を以前作ってあったのでそれを使いました。(共にボックスに入れてありますが銘版がテプラなのでとっても恰好悪い。)
出力はRB0〜RB3のみを使用します。LEDは前回の痕跡で、実際は使いません。
TD62064はパワー増幅インターフェイス(トランジスタアレイ)です。
ステッピングモータは12V電源用ですので24Vで使用するため40Ω20w外付け抵抗を付けてあります。(本来2個必要らしいですがちょっとチョンボです。) またO1〜O4には逆起電力防止クランプダイオードがついています。
材料は机の引き出しの中のゴミから拾い出し。(お前の机はどらえもんのポケットか>山とんぼ)
パルスに従って以下のように出力変化させます。詳しいことはともかく(自分がわかってない(^^;
)、4極1−2励磁というんだそうで。
|
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
φ1(RB0) |
○ |
○ |
○ |
× |
× |
× |
× |
× |
φ2(RB1) |
× |
× |
○ |
○ |
○ |
× |
× |
× |
φ3(RB2) |
× |
× |
× |
× |
○ |
○ |
○ |
× |
φ4(RB3) |
○ |
× |
× |
× |
× |
× |
○ |
○ |
RA3 ON ------------------->
RA3 OFF<-------------------
初期は1の状態にします。パルスが入力される毎に2,3,4---と遷移していきます。RA3
OFFで逆転の場合は逆に遷移します。
なんだかよくはわかってませんが、とにかく表のように出力すれば動くということだけはPMM8713で経験済み。
テーブル処理の手法がまさにぴったりです。(プログラム参照)
■フローチャート
見よう見まねでフローチャートも書いてみたりしましたが、こんな感じでしょうかね?
■プログラム
お作法知らずの真似しんぼで人様にお見せできるような代物じゃないですけど、とにかく動いたことは動いたということで。(^^;
; PMM8713代替
;*********************************************
LIST P=PIC16F84 ;
INCLUDE "P16f84.inc"
;標準ヘッダ定義ファイル
__CONFIG _HS_OSC & _PWRTE_ON
& _WDT_OFF
;************************
CNT EQU 0CH ;カウンタ
;***********************
; メインルーチン
;***********************
ORG 0 ;Reset Start
MAIN ;Initialize
BSF STATUS,RP0 ;バンク1へ切替
CLRF TRISB ;ポートBを出力モードに設定
MOVLW 018H
MOVWF TRISA ;ポートA
bit3,4入力
BCF STATUS,RP0 ;バンク0に戻す
MOVLW B'11111001' ;ポートB初期出力
MOVWF PORTB
MOVLW B'11111111' ;ポートA初期出力(使わない)
MOVWF PORTA
MOVLW 0H ;COUNTERリセット
MOVWF CNT
LOOP1
BTFSC PORTA,4 ;bit4が0なら進む
GOTO LOOP1
LOOP2
BTFSS PORTA,4 ;bit4が1なら進む
GOTO LOOP2
BTFSS PORTA,3 ;bit3(正逆)チェック
GOTO FWD ;正転
GOTO RVS ;逆転
FWD ;正転カウント処理
MOVF CNT,W
SUBLW 07H
BTFSC STATUS,2
GOTO SET0 ;カウンタ値
7 なら 0 に
INCF CNT,F
GOTO INCED
SET0 MOVLW 0H
MOVWF CNT
INCED GOTO PATTERN
RVS ;逆転カウント処理
MOVF CNT,W
SUBLW 0H
BTFSC STATUS,2
GOTO SET7 ;カウンタ値
0 なら 7 に
DECF CNT,F
GOT DECED
SET7 MOVLW 07H
MOVWF CNT
DECED
PATTERN
MOVF CNT,W
CALL TABLE
MOVWF PORTB ;TABLEから持ち帰ったデータを出力する
GOTO LOOP1
TABLE ;CNT値をPCLに足し込んでジャンプしそこに置いてあるデータを持ってリターンする
ADDWF PCL,F
RETLW B'11111001' ;下位4ビットが有効
RETLW B'11110001'
RETLW B'11110011'
RETLW B'11110010'
RETLW B'11110110'
RETLW B'11110100'
RETLW B'11111100'
RETLW B'11111000'
END
一応それなりの新しい挑戦してます。
◎ __config を使ってみました。
◎ テーブル処理なんかも使ってみました。
◎ MPLABでレジスタ内容変更(Modify)、ブレークポイント設定(Brake)、ストップウォッチなどを使ってみました。
モータPX244(オリエンタル製)
正逆転を瞬時切り替えできる条件で指令周波数1.5KHz、徐々に周波数を上昇させて5.0KHzまで可能。
波形としてはパルス発信器の限界の28KHzでも出力波形にオスロスコープがきれいに同期できる、ということは波形乱れがないとしていいと思われます。。
初めてのプログラムとしてはなかなかでした。自分で誉めてどうする。
と、簡単に動いたように書いてますが、実際はプログラム不慣れですから、書いては消し書いては消し、涙ぐましい努力。(^^;
一応考察として。
MPLABでデバッグかけてサイクルタイムを計ると、デバッグ用に書き換えた部分でわずか誤差はあるもののプログラムを一周舐めて8.8μsecでした。
ただし出力波形の乱れとしてはプログラム内の状況による流れの違いだけが影響するはずで、それは常時入力待ちで回っている
LOOP2
BTFSS PORTA,4 ;bit4が1なら進む
GOTO LOOP2
のどちらの行で指令パルスが来るかの差だけと考えて良いような気がします。つまり最大0.4μsecの誤差。
あとは常に同じ8.8μsecの遅れがあるだけ。
回転数の低いパルスモータでは一様な8.8μsecの遅れは無視できます。
まあ安全見て20μsecくらいとして50kHzくらいまではきれいな波形が出せるでしょうから普通のステッピングモータには使えそうです。
■今週のなるほど
◎こいつには1本とられた、疑似命令の __config はアンダーバー2個
確かにエディタで打つとつながって1個に見えるので誤植になるのもうなずけます。
ちなみにトラ技1999−5月号ピカチューのプログラム例ではアンダーバーがありません。
試してみたらこれもダメでした。
__configを使うと書き込み時の設定がいらず間違いがなくなりました。
◎おまじないのごとく頭にこいつを書いておく
LIST P=PIC16F84 ;
INCLUDE "P16f84.inc"
;標準ヘッダ定義ファイル
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF