CNC用ステッピングモーター制御プログラム PIC-16F88 アセンブリ言語
自作CNCをしていて気になったことがあったんです。
ユニポーラステッピングモーターは
1回転あたり200ステップ
ボールネジが1回転あたり12ミリ
このとき1相と2相励磁の場合
1パルスあたりの移動量
12mm / 200step = 0.06mm
になります。
なんとなく1パルスあたり0.06mm進むっていうのが
割り切れてない感じがして気に入らなかったんです。
1-2相励磁の場合
1パルスあたりの移動量
12mm / 400step = 0.03mm
この場合も1パルスあたり0.03mmです。
なんとなく1パルスあたり0.01mmにしたくなったんです。
そこで登場するのがマイクロステップというもので、一回転200ステップのステッピングモーターをそれ以上のステップで動作させることができます。
1パルスあたり0.01mm移動させるためには
1ステップを6ステップで進むようにする必要があります。
一回転あたり、
200ステップ × 6分割 = 1200ステップ
1パルスあたりの移動量
12mm / 1200step = 0.01mm
1ステップを6分割できるマイクロステップが入手できなかったので、自分で作ることにしました。
マイクロステップの特許を簡単に調べてみたところ、特許に書いてある項目全てを含んでいたらダメだということで、高速と低速で精度を切り替えて運転する機能をつけなければ大丈夫なのかなと思ったんです。
違ってたらごめんなさい。
用件を全て含まなくてもそれのみに使う部品だったら間接侵害になるかも?
公開した後に気づいて調べてびくびくして夜も眠れません。
あ、出願から20年以上経ってるから気にしなくていいのかも。
ステッピングモーターのマイクロステップ駆動方法
特願昭61-174273
特開昭63-265590
特公平08-008796
特許2129809
速度によって精度変えるって自動車の変速みたいですね。
クラッチ使わずにやる感じ。
プログラムできるかな。
うーんいつか挑戦してみたい。
それでいったら今つくったプログラムは1速ギアだけの状態
高速になったらマイクロステップをやめて
1相とか2相励磁にかえてトルクをあげて
速度を上げれるってことだと思う。
常時噛み合い方式ってどこかで聞いたことがあるけれど
これも特許なのか?いつか調べてみる。わかんなかった。
全ての励磁モードでカウントだけはさせておいて
いいタイミングのところで出力だけを選ぶようにしたら
作れそうな気もする。
PICの機能で分周器、プリスケーラーっていうのがあるから
それをうまく組み合わせたらできるかも。
あ、6で分周できるプリスケーラーがなかったです。
作るしかないのかもしれない。
そもそも自作CNCは特許大丈夫なんだろうか、
どうしよう作っちゃったけど。
作ってる人いたから大丈夫だと思ってた。
ちょっと調べてみる。
門型工作機械
特願平09-065060
特開平10-263959
未請求で3年以上経ってるからたぶん使っても良さそうです。
なんか前にも調べたことがあった気がした。
忘れてたかも。
プログラムを作りました
;****************************************************************
;題名 CNC用ステッピングモーター制御プログラム
;オリジナルマインド製サーボリンカーからステッピングモーターへの信号変換基盤用
;作成日 2019年9月28日-2019年12月8日
;修正 2024年9月24日
;作成者 福井彰太郎
;****************************************************************
;エンコード Shift_JIS
;フォント Courier_New 18.0pt.(Windows)
;フォント Monospaced 12(MPLAB X IDE)
;****************************************************************
;コンパイラ MPASMで作成開始。
;コンパイラ MPLAB X IDE v2.00へ変更。
;
;アセンブラ MPASM v5.54
;****************************************************************
;マイコン 16F88 3個
;
;入力 フォトカプラ TLP521-2 4個
;
;出力1段目 トランジスタ C1815 12個
;出力2段目 トランジスタ C3890 12個
;逆流保護ダイオード DD10 12個
;
;モーター IAI ロボシリンダー 3個
;ユニポーラ KH42KM2B042 200ステップ 1.8度
;ボールねじ 1回転12mm
;****************************************************************
;励磁方式(1相励磁、2相励磁)
;1相励磁(フルステップ駆動 200ステップ)
;主にユニポーラモーターで使用する。 6線モーター
;励磁の順序 A,/A,B,/B
;
;配線色 黒 青 黄 茶 赤 橙
;
;2相励磁(フルステップ駆動 200ステップ)
;主にバイポーラモーターで使用する。 4線モーター
;
;1回転あたり200パルスのモーターと1回転12ミリのボールネジを使う。
;1相と2相励磁の場合
;1パルスあたりの移動量 ボールネジ12mm / 200step = 0.06mm
;
;動作確認済み
;****************************************************************
;励磁方式(1-2相励磁)
;1-2相励磁(ハーフステップ駆動 400ステップ)
;
;1-2相励磁の場合
;1パルスあたりの移動量 ボールネジ12mm / 400step = 0.03mm
;
;動作確認済み
;****************************************************************
;PWMステップ駆動
;1-2相ベースでPWMステップの作成
;200分割 1相励磁の1ステップを6ステップで進む
;一回転あたり、200ステップ × 6分割 = 1200ステップ
;
;1パルスあたりの移動量 ボールねじ12mm / 1200step = 0.01mm
;
;動作確認済み
;****************************************************************
;プログラム作成の履歴
;2019/10/05
;MPLABでメインプログラム変数の初期化まで動いた
;
;割り込みは使わずにプログラムから入力を確認しに行くタイプとすることにした。
;動いた。
;
;入力信号のON時間が1μsと短く、時間が短いから割り込みを使うことになった。
;
;2019/10/16
;1-2相の正転まで出力できた。
;
;早く回した時に最高速が遅い感じがするのと、全体的に異音が大きい感じがする。
;磁石がくっついたときの衝撃が大きいからかもしれない
;衝撃を小さくするために出力の時間を半分ほどにしたら、高速で回せる気がした。
;
;そのうち試してみることにする。 トルクが落ちてゆっくりになるだけかもしれない
;
;2019/10/31
;ステッピングモーター用のPWM信号を作りたくなった。
;1-2相励磁だと、PWMするのは同時に1本だけで作れそうだと思った。
;1個目がオン、2個目が上がってくる。2個目がオン、1個目が下がってくる。
;2個目がオン、3個目が上がってくる。3個目がオン、2個目が下がってくる。
;3個目がオン、4個目が上がってくる。4個目がオン、3個目が下がってくる。
;これを出力できるようにしたい。
;
;Stimulus スティミュラス(刺激) 音節 (stim・u・lus)
;Clock Stimulus 1サイクルクロック(8MHz/4=500ns)
;a stimulus to growth [development] 成長への刺激
;
;2019/11/13
;PWMの直線増加減で正転逆転が出力できていそうな感じになった
;曲線の増加減とかオフセットとか 相ごとのオフセットができると便利そう
;
;そのうち試してみることになるかもしれない
;
;全部PWMステップだと高速で動かせないかもしれない
;入力パルスの間隔をはかって 励磁モードを自動で変えれると便利そう
;低速はPWMステップ 高速は1相ステップ
;それだと 1パルスあたり 自動でPWMステップが必要になる
;精度が低くなることになる
;
;パソコンから出せるパルス速度に限界がある
;10パルスは 10ミリ なのか 100 ミリなのか を
;パソコンから指示できる仕組みがひつようになる
;外部出力で選択できるようにできるかもしれない
;
;そのうち試してみることになるかもしれない
;
;2019/11/24
;1相励磁の出力を上げたり下げたりして、次のステップを上げたり下げたりを試してみた。
;100μ秒のタイマーで出力をフリッカさせると、トルクが少なくて動かなくなった。
;モーターへの電流がオフベースで動かしてることになった。
;常時100パーセント電流を流しているところが1本ないと手で押すと動いてしまう。
;モーターに電流が流れていないとき、くっついた山の上からどっちかに転がり落ちそうで
;そのとき次のステップ0パーセントだと が 不安定な動きの原因かもしれない
;
;1-2相ベースの1本PWM仕様が使えなくなってる
;復活させようか そのまま 2本PWM仕様へ変更しようか
;切り替えできるようにするか迷った
;
;2019/11/25
;PWMステップのとき その相の反対側へ誘導されて戻ってきてる気がする
;一回壊れて動かなくなったと思ったことがあった気がした ぜんぶ光ってるし になって
;だめだこりゃ だったかもしれない
;うごいてるか確認もできないになった
;
;2相励磁に戻して一回落ち着くことにした
;動く状態はキープしておくことが重要かもしれない
;
;プログラムを先頭から見直しをすることにした
;部品の仕様がわからなくなってる
;壊れたら再検討でいいかもしれない
;ちょこっと気になることをそのままにしないほうがいいかもしれない
;
;2019年12月2日
;PWMステップがそれっぽく動いた シュミレーションのみ
;1ステップ6分割で、1回転1200ステップになった
;1パルスあたりの移動量12/1200=0.01ミリで動かせそうな感じがしてきた
;
;2019年12月6日
;正転 右移動しかしない 逆転 左移動はリセットがかかるエラーの修正
;PWMステップがシュミレーションでは動いてる感じになった
;
;タイマー0で入力パルス間隔を測って エラーがでるようにしたらいいかもしれない
;最小時間をセットしておいて カウントアップがあれば 入力する
;カウントアップがないときはエラーにする
;モーターの方が先に脱調しそうだから いらないかもしれない
;
;2019年12月8日
;PWMステップが、正転と逆転の両方向動くようになった
;逆転の0だったら1のところを、ムーブだけでZを見ることにしたらうまくいった
;
;2019年12月20日
;一方向にまわしっぱなしで、1メモリ2μ半回転100メモリのμメーターで見ると
;動く量が変化するところがあることがわかった
;常時オンの相に近づいていくときと離れていくときではPWM値が変わるのかもしれない
;どちらかの片側は精度が出てる気がする、どうしよう
;精度は1?2相と、ちょっと上がった部分があって、全体的に音が小さくなった程度になった。
;バックラッシュは手で押すと40μほどあることがわかった
;モーターから動かすと20μほどだった
;前はここでPWM値の真ん中を探そうとして失敗した気がした
;エンコーダーがいるのかもしれない
;負荷をかけて測定しないといけないのかもしれない
;仕上げは無負荷でいいかもしれない
;
;10μステップ(0.01mmステップ)で繰り返し同じところに来る
;たまに1ステップだと動かなくて、2ステップで20μ(0.02mm)動く部分がある
;ボールねじの仕様かもしれない気がした
;わざと制度を落としてあるのかもしれない
;
;いろいろプログラムをいじって、結局元に戻したら調子がよかったような気がした
;
;これ以上精度を上げるときはエンコーダーが必須になるのかもしれない
;エンコーダーも波をうっていたら確認のしようがないになりそうな気がした
;2024/9/24
;プログラムの不要なところの整理
;PSTEPを012321012321じゃなくて
; 012210012210に変更
;実際に動かしながらPWM設定値の修正
;****************************************************************
LIST P=16F88
#INCLUDE P16F88.INC
;****************************************************************
;コンフィグレーションビットの設定。
; Set User ID Memory
__idlocs 0x6585
;CONFIG1
;CP/CCPMX/DEBUG/WRT1/WRT0/CPD/LVP/BOREN/MCLRE/FOSC2/PWRTEN/WDTEN/FOSC1/FOSC0
;CP1 プログラム読み出し許可 ○
;CP0 プログラム読み出し禁止
;CCPMX1 RB0コンパレータ入力
;CCPMX0 RB3コンパレータ入力 ○
;DEBUG1 インサーキットデバッガー禁止 RB6,7は入出力ポート ○
;DEBUG0 インサーキットデバッガー許可 RB6,7はICSPCLK,ICSPDAT
;WRT11 フラッシュプログラムメモリ書き込み防止なし ○
;WRT10 書込み防止00-00FF それ以降0FFFまでEECONで設定
;WRT01 書込み防止00-00FF それ以降0FFFまでEECONで設定
;WRT00 書込み防止00-00FF
;CPD1 EEPROM読み出し許可 ○
;CPD0 EEPROM読み出し禁止
;LVP1 低電圧書き込み許可 RB3をハイレベルにして書き込む
;LVP0 /MCLR端子に高電圧(VPP)を与えて書き込む RB3は通常の入出力 ○
;BOREN1 電圧低下 (>4V)リセット許可 ○
;BOREN0 電圧低下リセット禁止
;MCLRE1 RA5はMCLR機能で、負パルスでリセット ○
;MCLRE0 RA5は通常の入出力ポート
;FOSC111 RA7が外部発振RC端子 RA6がクロック出力
;FOSC110 RA7が外部発振RC端子 RA6は通常の入出力ポート
;FOSC101 内部クロック発振 RA6がクロック出力 RA7は通常の入出力ポート
;FOSC100 内部クロック発振 RA6,7は通常の入出力ポート ○
;FOSC011 外部クロック RA7が外部クロック入力 RA6は通常の入出力ポート
;FOSC010 RA7とRA6に高ゲイン(HS)発振子 4MHz-20MHz
;FOSC001 RA7とRA6に中ゲイン(XT)発振子 4MHz以下
;FOSC000 RA7とRA6に32kHz(LP)発振子
;PWRTEN1 電源立ち上げ時遅延スタートなし
;PWRTEN0 電源立ち上げ時遅延スタートあり ○
;WDTEN1 暴走自動停止あり ○
;WDTEN0 暴走自動停止なし
;(111)10 1111 0111 0100
;0x2F74
__CONFIG _CONFIG1, 0x2F74
;逆転をするとリセットがかかる
;このままで動いた
;ウォッチドッグなしにしてみた 変化なし
;(111)10111 1011 100 00
;0xEF70
; __CONFIG _CONFIG1, 0xEF70
;CONFIG2
;13-2bit機能なし 1として読み出し /IESO/FCMEN
;IESO1 電源立ち上げ時 非常用内臓クロック(FRC)使用許可
;IESO0 電源立ち上げ時 非常用内蔵クロック(FRC)使用禁止 ○
;FCMEN1 非常用内臓クロック(FRC)使用許可
;FCMEN0 非常用内臓クロック(FRC)使用禁止 ○
;(111)11 1111 1111 1100
;0x3FFC
__CONFIG _CONFIG2, 0x3FFC
;****************************************************************
;アセンブラプログラムの基本フォーマット
;Label/Mnemonic/Operand/Comment
;
;数値の表現方法
;
;2進数 B’001111001’
;8進数 O’777’
;10進数 D’100'
;16進数 H’9f' / 0AFH
;ASCII ‘C’ / A’C’
;
;GOTO、CALLは7FFまでPCLATHをつかわずに指定できる
;バイト処理命令127まで128個を指定できる
;
;****************************************************************
;MPLAB用エラー対策
;Register in operand not in bank 0. Ensure that bank bits are correct.
;バンク0以外へアクセスしようとしたときに、エラー表示を出なくする。
;
ERRORLEVEL -302
;
;****************************************************************
;バンク0の汎用レジスタ名の設定 20H-7F0 96byte 0-7bit 0-255
;****************************************************************
;汎用レジスタ General Purpose Register
;
GPR20 EQU H'20' ;汎用レジスタ20 8点 バンク0指定
Startup_complete EQU 0;0bit : 起動完了
Special_func_reg_ini_comp EQU 1;1bit : 特殊機能レジスタ初期化完了
Variable_ini_comp EQU 2;2bit : メインプログラム変数初期化完了
;3bit : 未使用
;4bit : 未使用
;5bit : 未使用
Step_memory EQU 6;6bit : STEP I/O割り込みの入力状態記憶
Dir_memory EQU 7;7bit : DIR I/O割り込みの入力状態記憶
;
GPR21 EQU H'21' ;汎用レジスタ21 8点 バンク0指定
;0bit : 未使用
PWM_ACTION EQU 1;1bit : STEP変更可:0 PWM動作中:1
;PWM_VECTOR EQU 2;2bit : PWMベクトル ステップの増加に対してPWM値の 1:増加 0:減少
;3bit : 未使用
;4bit : 未使用
;5bit : 未使用
;6bit : 未使用
;7bit : 未使用
;
GPR22 EQU H'22' ;汎用レジスタ22 8点 バンク0指定(未使用)
GPR23 EQU H'23' ;汎用レジスタ23 8点 バンク0指定(未使用)
GPR24 EQU H'24' ;汎用レジスタ24 8点 バンク0指定(未使用)
GPR25 EQU H'25' ;汎用レジスタ25 8点 バンク0指定(未使用)
GPR26 EQU H'26' ;汎用レジスタ26 8点 バンク0指定(未使用)
GPR27 EQU H'27' ;汎用レジスタ27 8点 バンク0指定(未使用)
GPR28 EQU H'28' ;汎用レジスタ28 8点 バンク0指定(未使用)
GPR29 EQU H'29' ;汎用レジスタ29 8点 バンク0指定(未使用)
GPR2A EQU H'2A' ;汎用レジスタ2A 8点 バンク0指定(未使用)
GPR2B EQU H'2B' ;汎用レジスタ2B 8点 バンク0指定(未使用)
GPR2C EQU H'2C' ;汎用レジスタ2C 8点 バンク0指定(未使用)
GPR2D EQU H'2D' ;汎用レジスタ2D 8点 バンク0指定(未使用)
GPR2E EQU H'2E' ;汎用レジスタ2E 8点 バンク0指定(未使用)
GPR2F EQU H'2F' ;汎用レジスタ2F 8点 バンク0指定(未使用)
GPR30 EQU H'30' ;汎用レジスタ30 8点 バンク0指定(未使用)
GPR31 EQU H'31' ;汎用レジスタ31 8点 バンク0指定(未使用)
GPR32 EQU H'32' ;汎用レジスタ32 8点 バンク0指定(未使用)
GPR33 EQU H'33' ;汎用レジスタ33 8点 バンク0指定(未使用)
GPR34 EQU H'34' ;汎用レジスタ34 8点 バンク0指定(未使用)
GPR35 EQU H'35' ;汎用レジスタ35 8点 バンク0指定(未使用)
GPR36 EQU H'36' ;汎用レジスタ36 8点 バンク0指定(未使用)
GPR37 EQU H'37' ;汎用レジスタ37 8点 バンク0指定(未使用)
GPR38 EQU H'38' ;汎用レジスタ38 8点 バンク0指定(未使用)
GPR39 EQU H'39' ;汎用レジスタ39 8点 バンク0指定(未使用)
GPR3A EQU H'3A' ;汎用レジスタ3A 8点 バンク0指定(未使用)
GPR3B EQU H'3B' ;汎用レジスタ3B 8点 バンク0指定(未使用)
GPR3C EQU H'3C' ;汎用レジスタ3C 8点 バンク0指定(未使用)
GPR3D EQU H'3D' ;汎用レジスタ3D 8点 バンク0指定(未使用)
GPR3E EQU H'3E' ;汎用レジスタ3E 8点 バンク0指定(未使用)
GPR3F EQU H'3F' ;汎用レジスタ3F 8点 バンク0指定(未使用)
;モーターの励磁モード設定
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1?2相励磁
;0000 0100:PWMステップ
MODE EQU H'40'
EXCITATION_MODE_ADDRESS_L EQU H'41';モーターの励磁モード設定より、ジャンプ先のアドレス
EXCITATION_MODE_ADDRESS_H EQU H'42';モーターの励磁モード設定より、ジャンプ先のアドレス
STEP EQU H'43' ;励磁ステップ
DIV EQU H'44';モーターの分割数設定 Division_number
;MCU EQU H'45' ;タイマー1の最小カウント単位 Minimum count unit
PSTEP EQU H'46' ;PWMステップ
PAPWM EQU H'47' ;PWM出力をするポートのビット選択
PA EQU H'48' ; ポートA用の出力データ
COMBINED_STEPS EQU H'49' ;STEPとPSTEPをあわせたステップ
;CASE32 EQU H'4A' ;CASE32 8点 バンク0指定
GPR4A EQU H'4A' ;汎用レジスタ4A 8点 バンク0指定(未使用)
GPR4B EQU H'4B' ;汎用レジスタ4B 8点 バンク0指定(未使用)
GPR4C EQU H'4C' ;汎用レジスタ4C 8点 バンク0指定(未使用)
GPR4D EQU H'4D' ;汎用レジスタ4D 8点 バンク0指定(未使用)
GPR4E EQU H'4E' ;汎用レジスタ4E 8点 バンク0指定(未使用)
GPR4F EQU H'4F' ;汎用レジスタ4F 8点 バンク0指定(未使用)
Startup_complete_L EQU H'50' ;起動完了カウンタL バンク0指定
Startup_complete_H EQU H'51' ;起動完了カウンタH バンク0指定
MSL EQU H'52' ;モーターから音を出すときの音の長さL
MSH EQU H'53' ;モーターから音を出すときの音の長さH
MHL EQU H'54' ;D54 バンク0指定(未使用)
MHH EQU H'55' ;D55 バンク0指定(未使用)
MC EQU H'56' ;D56 バンク0指定(未使用)
D57 EQU H'57' ;D57 バンク0指定(未使用)
D58 EQU H'58' ;D58 バンク0指定(未使用)
D59 EQU H'59' ;D59 バンク0指定(未使用)
T1INIL EQU H'5A' ;タイマー1初期値L バンク0指定
T1INIH EQU H'5B' ;タイマー1初期値H バンク0指定
T1PREL EQU H'5C' ;タイマー1現在値L バンク0指定 Present value
T1PREH EQU H'5D' ;タイマー1現在値H バンク0指定 Present value
COMPARE_1_INI_L EQU H'5E' ;コンペア1初期値L バンク0指定
COMPARE_1_INI_H EQU H'5F' ;コンペア1初期値H バンク0指定
D60 EQU H'60' ;D60 バンク0指定(未使用)
D61 EQU H'61' ;D61 バンク0指定(未使用)
D62 EQU H'62' ;D62 バンク0指定(未使用)
D63 EQU H'63' ;D63 バンク0指定(未使用)
D64 EQU H'64' ;D64 バンク0指定(未使用)
D65 EQU H'65' ;D65 バンク0指定(未使用)
D66 EQU H'66' ;D66 バンク0指定(未使用)
D67 EQU H'67' ;D67 バンク0指定(未使用)
D68 EQU H'68' ;D68 バンク0指定(未使用)
D69 EQU H'69' ;D69 バンク0指定(未使用)
D6A EQU H'6A' ;D6A バンク0指定(未使用)
D6B EQU H'6B' ;D6B バンク0指定(未使用)
D6C EQU H'6C' ;D6C バンク0指定(未使用)
D6D EQU H'6D' ;D6D バンク0指定(未使用)
D6E EQU H'6E' ;D6E バンク0指定(未使用)
D6F EQU H'6F' ;D6F バンク0指定(未使用)
WAIT70 EQU H'70' ;Wait70 待ち時間用変数0
WAIT71 EQU H'71' ;Wait71 待ち時間用変数1
WAIT72 EQU H'72' ;Wait72 待ち時間用変数2
WAIT73 EQU H'73' ;Wait73 待ち時間用変数3
WAIT74 EQU H'74' ;Wait74 待ち時間用変数4
WAIT75 EQU H'75' ;Wait75 待ち時間用変数5
WAIT76 EQU H'76' ;Wait76 待ち時間用変数6
WAIT77 EQU H'77' ;Wait77 待ち時間用変数7
WAIT78 EQU H'78' ;Wait78 待ち時間用変数8
WAIT79 EQU H'79' ;Wait79 待ち時間用変数9
WAIT7A EQU H'7A' ;Wait7A 待ち時間用変数A(未使用)
WAIT7B EQU H'7B' ;Wait7B 待ち時間用変数B(未使用)
WAIT7C EQU H'7C' ;Wait7C 待ち時間用変数C(未使用)
WAIT7D EQU H'7D' ;Wait7D 待ち時間用変数D(未使用)
WAIT7E EQU H'7E' ;Wait7E 待ち時間用変数E(未使用)
WAIT7F EQU H'7F' ;Wait7F 待ち時間用変数F(未使用)
;****************************************************************
;バンク1の汎用レジスタ名の設定 A0H-EFH 80byte 0-7bit 0-255
;****************************************************************
;F0H-FFH Access
;****************************************************************
;バンク2の汎用レジスタ名の設定 110H-11F 16byte 0-7bit 0-255
;****************************************************************
;****************************************************************
;バンク2の汎用レジスタ名の設定 120H-16F 80byte 0-7bit 0-255
;****************************************************************
;170H-17FH Access
;****************************************************************
;バンク3の汎用レジスタ名の設定 190H-19F 16byte 0-7bit 0-255
;****************************************************************
;****************************************************************
;バンク3の汎用レジスタ名の設定 1A0H-1EF 80byte 0-7bit 0-255
;****************************************************************
;1F0H-1FFH Access
;****************************************************************
;メインプログラム
;****************************************************************
;
;プログラムカウンタ
;8K×14のプログラムメモリ空間をアドレス指定することが可能な、
;13ビットプログラムカウンタを有しています。
;13ビットは0-1FFF(16進)までカウントできる 0-8191(10進)
;
;プログラムメモリ(PCLATHとあわせてページ切り替え)
;ページ0 0000-07FF 0-2047行分
;ページ1 0800-0FFF 0-2047行分
;ページ2 1000-17FF 0-2047行分
;ページ3 1800-1FFF 0-2047行分
;
;ビットのセット、リセットの方法
;BSF ビットのセット
;BCF ビットのリセット
;
;分岐の方法
;BTFSC ;レジスタの指定したビットが0なら次の命令をスキップ
;BTFSS ;レジスタの指定したビットが1なら次の命令をスキップ
;DECFSZ ;レジスタ値を1減算し,値が0なら次の命令をスキップ
;INCFSZ ;レジスタ値を1加算し,値が0なら次の命令をスキップ
;
;GOTOを使うときに注意すること。
;GOTOを使うときは、ジャンプ先のプログラムカウンタのアドレスが全部入らないから、
;GOTOの一個上の行にPCLATHを使って3,4ビット目を事前にセットする。
;
;他の命令でもPCLATHが必要なところがあるらしい。
;ADDWF PCLなどを使うときの、出力先かもしれない。
;それの8ビットとPCLATHから5ビットの13ビットで使えるらしい。
;GOTO,CALLを使うときは、それの11ビットとPCLATHから2ビットの13ビットで使える。
;RETURN,RETFIE,RETLWはスタックメモリより13ビットが直接戻される。
;
;
;STATUSレジスタの内容
;7bit IRP 間接アドレッシング時のバンク選択
; 1バンク2、3
; 0バンク0、1
;
;6,5bit RP0,1 データレジスタ用メモリのバンク選択
;RP1,RP0 0,0 バンク0(0x0000-0x007F 128bytes)
;RP1,RP0 0,1 バンク1(0x0080-0x00FF 128bytes)
;RP1,RP0 1,0 バンク2(0x0100-0x017F 128bytes)
;RP1,RP0 1,1 バンク3(0x0180-0x01FF 128bytes)
;
;4bit TO タイムアウトビット
; 1= Afterpower-up,CLRWDTinstructionorSLEEPinstruction
; 起動時か、CLRWDT/SLEEP命令実行時
; 0= AWDTtime-outoccurred
; ウォッチドックタイマによるタイムアウトが発生 読み込み専用
;
;3bit PD パワーダウンビット
; 1= Afterpower-uporbytheCLRWDTinstruction
; 起動後か、CLRWDT命令実行時
; 0= ByexecutionoftheSLEEPinstruction
; SLEEP命令実行時
;
;2bit Z ゼロビット
; 1算術演算または論理演算の結果がゼロであります
; 0結果がゼロではありません
;
;1bit DC
; 1第4ビットキャリー発生
; 0第4ビットキャリー発生してません
;
;0bit C
;; 1最上位キャリー発生
; 0最上位キャリー発生してません
;
;****************************************************************
;プログラムメモリ ページ0 0000-07FF 2kB
;****************************************************************
ORG_000 ORG 0x000 ;リセットベクタ
H000 CLRWDT ;ウォッチドッグタイマのリセット
H001 CLRF STATUS ;ステータスレジスタのクリア バンク0を選択
H002 CLRF PCLATH ;プログラムメモリ0を指定
H003 GOTO H0A0 ;起動開始ベクタ
ORG_004 ORG 0x004 ;割り込みベクタ
H004 CLRWDT ;ウォッチドッグタイマのリセット
;STEP SET
H005 BSF GPR20,Step_memory ;STEP I/O割り込み
;DIR SET/RESET
H006 BCF GPR20,Dir_memory ;DIR リセット
H007 BTFSC PORTB,6 ;レジスタの指定したビットが0なら次の命令をスキップ
H008 BSF GPR20,Dir_memory ;DIR セット
H009 BCF INTCON,4
;割り込みで データを変更
;割り込みから スタックで戻って
;タイマーとコンペアの グルグル
;右方向には動く、左方向にはリセットがかかる
;DIR_memoryのセット、リセットを逆にすることにした
;左方向のスイッチで右方向にだけ動いた
;右方向のスイッチを押すとリセットがかかる
;エラーにはジャンプしてなさそう
;リセット入力になっていてピック自体が入力からリセットがかかってる感じではなさそうだった
;正転はうごいてる 逆転が動いてない
H00A RETFIE ;割り込みから戻る
H00B NOP
H00C NOP
H00D NOP
H00E NOP
H00F NOP
ORG_0A0 ORG 0x0A0 ;起動開始ベクタ
H0A0 BCF STATUS,RP0 ;0 バンク0を選択する
H0A1 BCF STATUS,RP1 ;0 バンク0を選択する
H0A2 BCF GPR20,Startup_complete ;起動完了フラグクリア バンク0指定
;起動カウンタのカウンタリセット
H0A3 MOVLW H'00' ;H'00'をWへ格納
H0A4 MOVWF Startup_complete_H ;Wを Startup_complete_H へ格納 起動カウンタH バンク0指定
H0A5 MOVLW H'00' ;H'00'をWへ格納
H0A6 MOVWF Startup_complete_L ;Wを Startup_complete_L へ格納 起動カウンタL バンク0指定
H0A7 GOTO H0B0 ;起動カウンタのインクリメントへ
H0A8 NOP ;何もしない
H0A9 NOP ;何もしない
H0AA NOP ;何もしない
H0AB NOP ;何もしない
H0AC NOP ;何もしない
H0AD NOP ;何もしない
H0AE NOP ;何もしない
H0AF NOP ;何もしない
ORG_0B0 ORG 0x0B0 ;起動カウンタのインクリメント
;(1024までカウントして割り込みベクタへ戻る)
H0B0 CLRWDT ;ウォッチドッグタイマのリセット
H0B1 MOVF Startup_complete_L,0 ;起動カウンタD30LをWへ格納
H0B2 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H0B3 MOVWF Startup_complete_L ;WレジスタからStartup_complete_Lレジスタへデータを移動します
H0B4 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H0B5 GOTO H0BA ;起動カウンタが1024かどうか確認するへ
H0B6 MOVF Startup_complete_H,0 ;起動完了カウンタStartup_complete_HをWへ格納
H0B7 ADDLW H'1' ;Wへ1加算 オーバーフローの確認はしない
H0B8 MOVWF Startup_complete_H ;WレジスタからStartup_complete_Hレジスタへデータを移動します。
H0B9 GOTO H0B0 ;起動カウンタのインクリメントへ戻る
;起動カウンタが1024かどうか確認する "0000 0100 0000 0000"(2進数)
H0BA BTFSS Startup_complete_H,2 ;Startup_complete_Hの2ビットが1なら次の命令をスキップする バンク0指定
H0BB GOTO H0B0 ;Startup_complete_Hの2ビットが0の時。 インクリメントへ戻る
H0BC BSF GPR20,Startup_complete ;起動完了フラグセット バンク0指定
H0BD GOTO H0C0 ;
H0BE NOP ;何もしない
H0BF NOP ;何もしない
ORG_0C0 ORG 0x0C0 ;特殊機能レジスタの初期化開始ベクタ
H0C0 BCF STATUS,RP0 ;0 バンク0を選択する
H0C1 BCF STATUS,RP1 ;0 バンク0を選択する
H0C2 BTFSS GPR20,Startup_complete ;起動完了フラグが1だったら次の命令をスキップする
H0C3 GOTO H000 ;
H0C4 BCF GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了クリア バンク0指定
H0C5 GOTO H100 ;特殊機能レジスタの初期設定へ
H0C6 NOP ;何もしない
H0C7 NOP ;何もしない
H0C8 NOP ;何もしない
H0C9 NOP ;何もしない
H0CA NOP ;何もしない
H0CB NOP ;何もしない
H0CC NOP ;何もしない
H0CD NOP ;何もしない
H0CE NOP ;何もしない
H0CF NOP ;何もしない
;****************************************************************
ORG_100 ORG 0x100 ;特殊機能レジスタの初期設定
;****************************************************************
;OPTION_REG:OPTION制御レジスタ(アドレス81H,181H DS30487C-18ページ)
;----- OPTION_REG Bits -----------------------------------------------------
;7bit1 NOT_RBPU ポートBプルアップ 1無効 0有効
;6bit1 INTEDG
;RB0/INTピン 1立ち上がりエッジで割り込み 0立下りエッジで割り込み
;
;5bit0 T0CS TMR0カウント
;1RA4/T0CKI/C2OUTピンの変遷 0内部サイクルクロック(CLKO)
;
;4bit0 T0SE RA4/T0CKI/C2OUTピンのカウントアップのタイミング
;1ハイからロー 0ローからハイ
;
;3bit0 PSA プリスケーラの割り当て 1WDT 0タイマ0
;
;PS<2:0>プリスケーラ選択ビット
; TMR0 WDT
;000 1:2 1:1 とりあえずこれに設定
;001 1:4 1:2
;010 1:8 1:4
;011 1:16 1:8
;100 1:32 1:16
;101 1:64 1:32
;110 1:128 1:64
;111 1:256 1:128
;2bit0 PS2
;1bit0 PS1
;0bit0 PS0
H100 BSF STATUS,RP0 ;1 バンク1を選択する
H101 BCF STATUS,RP1 ;0 バンク1を選択する
H102 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H103 MOVWF OPTION_REG ;Wレジスタからデータを移動します。
;****************************************************************
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;7bit0 GIE 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;6bit0 PEIE 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;5bit0 TMR0IE TMR0オーバーフロー割り込み 1有効 0無効
;4bit0 INTE RB0/INT外部割り込み 1有効 0無効
;3bit0 RBIE RBポート変化割り込み 1有効 0無効
;2bit0 TMR0IF TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;
;1bit0 INTF RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;
;0bit0 RBIF RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H104 BCF STATUS,RP0 ;0 バンク0を選択する
H105 BCF STATUS,RP1 ;0 バンク0を選択する
H106 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H107 MOVWF INTCON ;Wレジスタからデータを移動します。
;****************************************************************
;PIE1:周辺装置割り込みレジスタ1をENABLE(アドレス8CH DS30487C-20ページ)
;----- PIE1 Bits ----------------------------------------------------------
;6bit0 ADIE A/D変換器割り込み 1使用可能 0使用禁止
;5bit0 RCIE AUSART受信割り込み 1使用可能 0無効
;4bit0 TXIE AUSART送信割り込み 1使用可能 0無効
;3bit0 SSPIE 同期シリアルポート割り込み 1使用可能 0無効
;2bit0 CCP1IE CCP1割り込み 1使用可能 0無効
;1bit0 TMR2IE PR2一致割り込み(TMR2) 1使用可能 2無効
;0bit0 TMR1IE TMR1オーバーフロー割り込み 1使用可能 0使用禁止
H108 BSF STATUS,RP0 ;1 バンク1を選択する
H109 BCF STATUS,RP1 ;0 バンク1を選択する
H10A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H10B MOVWF PIE1 ;Wレジスタからデータを移動します。
;****************************************************************
;PIR1:周辺割り込み要求(FLAG)レジスタ1(アドレス0CH DS30487C-21ページ)
;----- PIR1 Bits ----------------------------------------------------------
;6bit0 ADIF A/D変換(ソフトウェアでクリアする必要がある) 1完了 0未完了
;5bit0 RCIF AUSARTの受信バッファ(RCREGを読み出すことによってクリア)
;1受信バッファがいっぱい 0受信バッファがない
;
;4bit1 TXIF AUSARTの送信バッファ(TXREGに書き込むことでクリアされる)
;1送信バッファがない 0送信バッファがいっぱい
;
;3bit0 SSPIF 同期シリアルポート(SSP)(ソフトウエアでクリアする必要がある)
;1送信/受信 完了 0送信/受信するために待機しています
;
;2bit0 CCP1IF TMR1レジスタのキャプチャ(ソフトウエアでクリアする必要がある)
;1キャプチャが発生した 0キャプチャが発生してない
;
;1bit0 TMR2IF TMR2 PR2との一致(ソフトウェアでクリアする必要がある)
;1一致が発生した 0一致は発生してない
;
;0bit0 TMR1IF TMR1のオーバーフロー(ソフトウェアでクリアする必要がある)
;1オーバーフローした 0オーバーフローしませんでした
H10C BCF STATUS,RP0 ;0 バンク0を選択する
H10D BCF STATUS,RP1 ;0 バンク0を選択する
H10E MOVLW B'00010000' ;8ビットリテラルをWレジスタへ格納
H10F MOVWF PIR1 ;Wレジスタからデータを移動します。
;****************************************************************
;PIE2:周辺装置割り込みレジスタ2をENABLE(アドレス 8DH DS30487C-22ページ)
;----- PIE2 Bits ----------------------------------------------------------
;7bit0 OSFIE オシレータ失敗割り込み 1使用可能 0無効
;6bit0 CMIE コンパレータ割り込み 1使用可能 0無効
;4bit0 EEIE 操作割り込み(EEPROM) 1使用可能 0無効
H110 BSF STATUS,RP0 ;1 バンク1を選択する
H111 BCF STATUS,RP1 ;0 バンク1を選択する
H112 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H113 MOVWF PIE2 ;Wレジスタからデータを移動します。
;****************************************************************
;PIR2周辺割り込み要求(FLAG)レジスタ2(アドレス 0DH DS30487C-23ページ)
;----- PIR2 Bits ----------------------------------------------------------
;7bit0 OSFIF (ソフトウェアでクリアの必要がある)
;1システム発振器が失敗し、クロック入力はINTRCに変更されました。
;0システムクロック動作
;
;6bit0 CMIF (ソフトウェアでクリアの必要がある)
;1コンパレータの入力が変化した
;0コンパレータの入力は変化していません
;
;4bit0 EEIF (ソフトウェアでクリアする必要がある)
;1 EEPROM書き込み完了
;0 EEPROM書き込みが完了してない
H114 BCF STATUS,RP0 ;0 バンク0を選択する
H115 BCF STATUS,RP1 ;0 バンク0を選択する
H116 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H117 MOVWF PIR2 ;Wレジスタからデータを移動します。
;****************************************************************
;PCON:POWER制御レジスタ(アドレス8EH DS30487C-24ページ)
;----- PCON Bits ----------------------------------------------------------
;1bitx NOT_POR
;1パワーオンリセットが発生してません
;0パワーオンリセットが発生しました(ソフトで設定が必要)
;
;0bitx NOT_BOR
;1ブラウンアウトリセットが発生してません
;0ブラウンアウトリセットが発生しました(ソフトでセットが必要)
H118 NOP ;BSF STATUS,RP0 ;1 バンク1を選択する
H119 NOP ;BCF STATUS,RP1 ;0 バンク1を選択する
H11A NOP ;MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H11B NOP ;MOVWF PCON ;Wレジスタからデータを移動します。
;****************************************************************
;EEPROM用レジスタの初期化
H11C BCF STATUS,RP0 ;0 バンク2を選択する
H11D BSF STATUS,RP1 ;1 バンク2を選択する
H11E MOVLW H'00' ;0x00をWへ格納
H11F MOVWF EEDATA ;WをEEDATAへ格納
H120 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H121 MOVWF EEDATH ;Wレジスタからデータを移動します。
H122 MOVLW H'00' ;0x00をWへ格納
H123 MOVWF EEADR ;WをEEADRへ格納
H124 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H125 MOVWF EEADRH ;Wレジスタからデータを移動します。
;EECON1:EEPROMアクセス制御レジスタ1(アドレス18CH DS30487C-28ページ)
;----- EECON1 Bits --------------------------------------------------------
;7bit0 EEPGD
;1フラッシュメモリにアクセス(このプログラムの入るメモリ)
;0データメモリにアクセス(EEPROM)
;
;4bit0 FREE
;1次のWRコマンドでEEADR:EEADRHによって対象メモリ行を消去
;0次のWRコマンドで書き込みを行います
;
;3bit0 WRERR
;1MCLRまたはWDT通常時のリセットが発生 書き込みが途中で終了したフラグ
;0書き込み動作が完了します。
;
;2bit0 WREN EEPROMへの書き込み
;1可能
;0禁止
;
;1bit0 WR
;1書き込みサイクルの開始(ハードウェアによって解除)
;0書き込みサイクル完了
;
;0bit0 RD
;1EERPOMへの読み取りを開始(ハードウェアによって解除)
;0開始しません
H126 BSF STATUS,RP0 ;1 バンク3を選択する
H127 BSF STATUS,RP1 ;1 バンク3を選択する
H128 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H129 MOVWF EECON1 ;Wレジスタからデータを移動します。
;EECON2 誤書き込み防止用レジスタ
;EEPROMは8ビットのこれだけかと思ったことがあった気がした
;ここに何か書き込まないと EEPROMに書き込めない雰囲気がしてくる ではなくて
;所定の書き込み手順がないとEECON2に書き込めない
;その所定の書き込みだけのためにある になっている
;とりあえず全部0にしておくことにした
H12A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H12B MOVWF EECON2 ;Wレジスタからデータを移動します。
;****************************************************************
;OSCTUNE内部発振器の調節(アドレス90H DS30487-38ページ)
;下位6bitを2の補数で指定する
;10 0000(最小周波数)?000000(中心周波数、校正周波数で動作)‾011111(最大周波数)
H12C BSF STATUS,RP0 ;1 バンク1を選択する
H12D BCF STATUS,RP1 ;0 バンク1を選択する
H12E MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H12F MOVWF OSCTUNE ;Wレジスタからデータを移動します。
;音を出して確認 7ドが7ミぐらいだった
;周波数を下げることにした
;とりあえず半分ぐらい 16 1 0000
;7ラになった
;先頭に1をつけると7ファになった
;最小周波数 7ミになった
;調節しても変化がないのかもしれない
;最大周波数にしてみることにした
;7ラになった
;中心に戻すことにした
;7ファ#になった
;OSCCON発振器制御レジスタ (アドレス8FH DS30487-40ページ)
;----- OSCCON Bits -------------------------------------------------------
; <6:4> = 111( 8MHz), 110( 4MHz), 101( 2MHz), 100( 1MHz)
; 011(500kHz), 010(250kHz), 001(125kHz), 000(31.25kHz)
;6bit1 IRCF2 周波数設定
;5bit1 IRCF1 周波数設定
;4bit1 IRCF0 周波数設定
;3bitx OSTS 3bit読み出しのみ
;1プライマリクロックから実行
;0T1OSCまたはINTRCから実行
;
;2bitx IOFS 2bit読み出しのみ
;1周波数が安定
;0周波数が不安定
;オシレータモード選択ビット
;00:FOSCで定義されたオシレータモード
;01:T1OSCは、システムクロックのために使用されています
;10:内部RCは、システムクロックのために使用されています
;11:予約済み
;1bit1 SCS1
;0bit0 SCS0
H130 BSF STATUS,RP0 ;1 バンク1を選択する
H131 BCF STATUS,RP1 ;0 バンク1を選択する
H132 BSF OSCCON,IRCF2 ;8MHzに設定
H133 NOP ;BCF OSCCON,IRCF2
H134 BSF OSCCON,IRCF1
H135 NOP ;BCF OSCCON,IRCF1
H136 BSF OSCCON,IRCF0
H137 NOP ;BCF OSCCON,IRCF0
H138 BSF OSCCON,SCS1 ;内部RCに設定
H139 NOP ;BCF OSCCON,SCS1
H13A NOP ;BSF OSCCON,SCS0
H13B BCF OSCCON,SCS0
;****************************************************************
;PORTAの初期化(アドレス5H DS30487-51ページ)
;
;17 RA0/AN0 TTL A出力
;18 RA1/AN1 TTL /A出力
;1 RA2/AN2/CVref/Vref- TTL B出力
;2 RA3/AN3/Vref+/C1out TTL /B出力
;3 RA4/AN4/T0CK1/C2out ST 空き 0出力
;4 RA5/MCLR*/Vpp ST +5Vに直結 リセット入力
;15 RA6/OSC2/CLK0 ST (内部周波数)/4Hzのモニター出力
;16 RA7/OSC1/CLK1 ST/CMOS 空き 0出力
H13C BCF STATUS,RP0 ;0 バンク0を選択する
H13D BCF STATUS,RP1 ;0 バンク0を選択する
H13E CLRF PORTA ;PORTAを初期化することで、出力をクリアします。データラッチ
;****************************************************************
;----- ANSEL Bits ---------------------------------------------------------
;6bit0 ANS6 AN6アナログ
;5bit0 ANS5 AN5アナログ
;4bit0 ANS4 AN4アナログ
;3bit0 ANS3 AN3アナログ
;2bit0 ANS2 AN2アナログ
;1bit0 ANS1 AN1アナログ
;0bit0 ANS0 AN0アナログ
H13F BSF STATUS,RP0 ;1 バンク1を選択する
H140 BCF STATUS,RP1 ;0 バンク1を選択する
H141 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H142 MOVWF ANSEL ;Wレジスタからデータを移動します。
;7bit0 TRISA RA7 1入力 0出力
;6bit1 TRISA RA6 1入力 0出力
;5bit1 TRISA RA5 1入力 0出力
;4bit0 TRISA RA4 1入力 0出力
;3bit0 TRISA RA3 1入力 0出力
;2bit0 TRISA RA2 1入力 0出力
;1bit0 TRISA RA1 1入力 0出力
;0bit0 TRISA RA0 1入力 0出力
H143 MOVLW B'01100000' ;8ビットリテラルをWレジスタへ格納
H144 MOVWF TRISA ;Wレジスタからデータを移動します。
;****************************************************************
;PORTBの初期化(アドレス6H DS30487-57ページ)
;
;6 RB0/INT/CCP1 TTL/ST STEP入力 ポートBプルアップ無効 立ち上がりエッジで割り込み
;7 RB1/SDI/SDA TTL/ST 空き入力 ポートBプルアップ無効
;8 RB2/SDO/RX/DT TTL/ST 空き入力 ポートBプルアップ無効
;9 RB3PGM/CCP1 TTL/ST 空き入力 ポートBプルアップ無効 コンパレータ入力
;10 RB4/SCK/SCL TTL/ST 空き入力 ポートBプルアップ無効
;11 RB5/SS*/TX/CK TTL 空き入力 ポートBプルアップ無効
;12 RB6/AN5/PGC/T1OSO/T1CK1 TTL/ST DER入力 ポートBプルアップ無効
;13 RB7/AN6/PGD/T1OSI TTL/ST 空き入力 ポートBプルアップ無効
H145 BCF STATUS,RP0 ;0 バンク0を選択する
H146 BCF STATUS,RP1 ;0 バンク0を選択する
H147 CLRF PORTB ;PORTBを初期化することで、出力をクリアします。データラッチ
;7bit1 TRISB RB7 1入力 0出力
;6bit1 TRISB RB6 1入力 0出力
;5bit1 TRISB RB5 1入力 0出力
;4bit1 TRISB RB4 1入力 0出力
;3bit1 TRISB RB3 1入力 0出力
;2bit1 TRISB RB2 1入力 0出力
;1bit1 TRISB RB1 1入力 0出力
;0bit1 TRISB RB0 1入力 0出力
H148 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H149 MOVWF TRISB ;Wレジスタからデータを移動します。
;****************************************************************
;TMR0の初期化
H14A BCF STATUS,RP0 ;0 バンク0を選択する
H14B BCF STATUS,RP1 ;0 バンク0を選択する
H14C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H14D MOVWF TMR0 ;Wレジスタからデータを移動します。
;TIMER0モジュール 8ビットタイマ/カウンタ(DS30487-67ページ)
;インターバルタイマーとして使える
;タイマーオーバーフローの割り込みを発生させることができる
;カウンタの初期値を変更して、オーバーフローまでのカウント数を変更して
;タイマーの値を設定する
;
;カウンタの設定値の求め方
;(インターバル時間)/(CPUクロック×4)
;例 CPUの水晶発振子が10MHzの時に20msecのインターバルとするためには、
;20msec×1000/0.1usec×4=50000
;
;TMR0には8ビットのプリスケーラが接続されています
;従って8ビット+8ビットで合計16ビットで
;65535までのカウントができます。
;
;プリスケーラの動かし方は、2,4,8,16,32,64,128,256カウントの8種類となっています。
;
;上例20msecのタイマーとするには
;50000/256=約195(16進数でC3H)となります
;従ってカウンタの設定値は結局下記となります。
;プリスケーラ 256カウント
;TMR0カウンタはアップカウンタなので
;FFH-C3H=3CHで3Cが設定値となる。
;タイマーのカウンタの動作速度。 規格表に書いてあるらしい
;プリスケーラ無しの時は、最大2.3MHz
;プリスケーラ付きの時は、最大18MHz
;
;TMR0カウンタ本体 :
;最小パルス幅=(クロックサイクル)+20nsec ;=420nsec周期=2.38MHz
;
;プリスケーラ本体 : 最小パルス幅=50nsec(電源5V)
; =20MHz
; プリスケーラとTMR0の組み合わせの時
; : 最小パルス幅=((クロックサイクル)+40nsec)/(プリスケーラ値)
; プリスケーラ値毎に計算すると
; =440/2=220nsec=4.54MHz
; =440/4=110nsec=9.09MHz
; =440/8= 55nsec=18.1MHz(最大動作値)
; =440/16=27.5nsec=36.3MHZ>20MHz
;クロックが10Mhzの時は プリスケーラーは8までしか使えない に なっている
;入力信号の安定時間用のタイマーにしようと思った
;今回の入力ステップ信号のパルス調整幅 1-5us 0.000001s-0.000005s
;PICクロックが8MHzのとき、パルス信号5μsの間に何命令実行できるかを調べることにした。
;1命令4クロック 4/8=0.5us より
;10命令分のパルス幅しかないことがわかった
;出力の更新をしながら入力の確認と信号の安定時間のプログラムは作れそうにない
;信号の入力には、割り込み入力を使うことになった
;移動速度とそのときの周波数の計算
;最大移動速度は、仮に3秒で150mmほどを目安にすることとした
;1秒で50mm移動できることを目標とする
;12mmで200ステップの時は1mmあたり16.6666ステップになる
;50mmの時は 50mm×16.6666ステップ=833.33ステップになる
;1秒間に833.33ステップを出す時は 出力周波数 833.33Hz のこと
;2相励磁のときは、833.33Hzの出力周波数になる
;1命令 0.0000005sだから 1秒間に2000000命令実行できる
;出力周波数の更新ごとに2000000/833.33=2400命令実行できる
;2相励磁のときは入力待ちループでも大丈夫かもしれない
;PWM出力にするときは割り込み入力が必要になる
;今のうちに入力は割り込みから持ってこれるようにしたほうがいい気がした
;
;PWMにするときはステップの変更とタイマー設定値の変更
;タイマーのカウントアップを見つつ出力をオンオフすると良さそう
;タイマー0(DS30487-67ページ) 未使用 ポートBプルアップ追加
;OPTION_REG:OPTION制御レジスタ(アドレス81H,181H DS30487C-18ページ)
;----- OPTION_REG Bits -----------------------------------------------------
;7bit1 NOT_RBPU ポートBプルアップ
;1無効
;0有効
;
;6bit1 INTEDG RB0/INTピン
;1立ち上がりエッジで割り込み
;0立ち下がりエッジで割り込み
;
;5bit0 T0CS TMR0クロック
;1RA4/T0CKI/C2OUTピンの変遷
;0内部サイクルクロック(CLKO)
;
;4bit0 T0SE RA4/T0CKI/C2OUTピンのインクリメント
;1ハイからロー
;0ローからハイ
;
;3bit0 PSA プリスケーラの割り当て
;1WDT
;0タイマ0
;
;PS<2:0>プリスケーラ選択ビット
; TMR0 WDT
;000 1:2 1:1 とりあえずこれに設定
;001 1:4 1:2
;010 1:8 1:4
;011 1:16 1:8
;100 1:32 1:16
;101 1:64 1:32
;110 1:128 1:64
;111 1:256 1:128
;PS2 2bit0
;PS1 1bit0
;PS0 0bit0
H14E BSF STATUS,RP0 ;1 バンク1を選択する
H14F BCF STATUS,RP1 ;0 バンク1を選択する
H150 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H151 MOVWF OPTION_REG ;Wレジスタからデータを移動します。
;****************************************************************
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;7bit0 GIE
;1全てのマスクされてない割り込みを許可
;0全ての割り込みは無効
;
;6bit0 PEIE
;1全てのマスクされていない周辺割り込みを有効
;0全ての周辺割り込みを無効
;
;5bit0 TMR0IE
;TMR0オーバーフロー割り込み
;1有効
;0無効
;
;4bit0 INTE
;RB0/INT外部割り込み
;1有効
;0無効
;
;3bit0 RBIE
;RBポート変化割り込み
;1有効
;0無効
;
;2bit0 TMR0IF
;TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
;1した
;0しませんでした
;
;1bit0 INTF
;RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
;1発生した
;0発生しませんでした
;
;0bit0 RBIF
;RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
;1発生した
;0変化なし
;
H152 BCF STATUS,RP0 ;0 バンク0を選択する
H153 BCF STATUS,RP1 ;0 バンク0を選択する
H154 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H155 MOVWF INTCON ;Wレジスタからデータを移動します。
;****************************************************************
;タイマー1の設定 PWM信号用にする
;カウンターの入力はクロック/4になっている
;最大内部クロック8MHzの時に、最大2MHzがカウンターに入力される
;1命令実行する時間で、カウンターも1カウントされるからわかりやすい
;PWM周波数は、20kHzぐらいがよく使われているらしい。
;早すぎてキーンと音が聞こえないのがちょっと寂しい
;2MHzは1秒間に2,000,000個の山がある速さのことで、
;TMR0の時は、プリスケーラ無しで255までカウントできる
;TMR1の時は、プリスケーラ無しで65535までカウントできる
;2,000,000/20,000=100 より、100回繰り返すと2MHzになる
;1秒間に100回繰り返すから100Hzのこと
;高音すぎて聞こえないかと思いきや、低音すぎてきこえなかったのかもしれない
;で 1kHzにするとしたら プリスケーラーが必要になると思いきや
;20kHzだと思っていた カウント数 のところを減らすことにした
;2,000,000 / 2,000 = 1000Hz
;タイマーのカウントアップを2000にセットすると
;PWM分解能1000ステップ、出力周波数は1kHzとなる
;
;タイマー1を使うことになった。16ビットカウンタ。
;タイマー1(DS30487-71ページ)
;タイマー0と同様の機能を持っている
;カウンタが16ビットになっている TMR1H:TMR1L
;キャプチャ機能やコンペア機能がある
;
;タイマー1の設定とカウント動作開始
;コンペアを使うことにする
;使えそうな分割数と最小移動量
;分割数 / 移動量 / 1-2相ステップ間の分割数 / PWM周波数
;1200分割 0.01mm 1200/400=3 2MHz/1.666kHz
;2400分割 0.005mm 2400/400=6 2MHz/833.333Hz
;6000分割 0.002mm 6000/400=15 2MHz/333.333Hz
;12000分割 0.001mm 12000/400=30 2MHz/166.666Hz
;24000分割 0.0005mm 24000/400=60 2MHz/83.333Hz
;60000分割 0.0002mm 60000/400=150 2MHz/33.333Hz
;120000分割 0.0001mm 120000/400=300 2MHz/16.666Hz
;割り切れないから誤差が出る
;誤差が気にならないところにセットしたらよさそう
;プログラムからの誤差より小さいかもしれない
;TMR1の初期設定
H156 BCF STATUS,RP0 ;0 バンク0を選択する
H157 BCF STATUS,RP1 ;0 バンク0を選択する
;タイマー1の初期値
;1秒間に50mmの移動速度を最高速度としたとき
;1相励磁のときは 833.33Hz でモーターが回ってる
;1-2相励磁のときは 1.666kHz でモーターが回ってる
;1相励磁の1パルスあたり2400命令分使える
;1-2相励磁の1パルスあたり1200命令分使える
;PWM周波数はそれの10倍がいいのかもしれない
;1.666kHzの10倍ないと PWM周波数と同じになって脱調になる
;16kHz以上の周波数がほしくなった
;とりあえず20KHzに設定することにした
;65535-20000=45535
;1011 0001 1101 1111
;とおもいきや
;200カウントで10kHzになってるから
;200でよさそう
;前のは100Hzかもしれない
;65535-200=65335
;1111 1111 0011 0111
H158 MOVLW B'00110111' ;8ビットリテラルをWへ格納
H159 MOVWF T1INIL ;WをT1INILへ格納
H15A MOVLW B'11111111' ;8ビットリテラルをWへ格納
H15B MOVWF T1INIH ;WをT1INIHへ格納
H15C MOVF T1INIL,0 ;T1INILをWへ格納
H15D MOVWF TMR1L ;WをTMR1Lへ格納
H15E MOVF T1INIH,0 ;T1INIHをWへ格納
H15F MOVWF TMR1H ;TMR1Hへ格納
;タイマー1動作させる設定 (DS30487-71ページ)
;タイマー0と同様の機能を持っている
;カウンタが16ビットになっている TMR1H:TMR1L
;キャプチャ機能やコンペア機能がある
;
;T1CON:TIMER1コントロールレジスタ(アドレス10H DS3048-71ページ)
;----- T1CON Bits ---------------------------------------------------------
;6bit0 T1RUN
;1タイマ1よりシステムクロック
;0別ソースより
;
;タイマ1の入力クロックプリスケール選択ビット
;11=1:8プリスケール値
;10=1:4プリスケール値
;01=1:2プリスケール値
;00=1:1プリスケール値 これに設定
;5bit0 T1CKPS1
;4bit0 T1CKPS0
;3bit0 T1OSCEN
;1外部発振器有効
;0外部発振器遮断
;
;2bit1 NOT_T1SYNC
;1外部クロックを同期しない
;0外部クロックを同期する
;
;2bit T1INSYNC 下位互換性
;
;1bit0 TMR1CS
;1RB6/AN5から外部クロック
;0内部クロック(FOSC/4)
;
;0bit1 TMR1ON
;1タイマ1が有効
;0タイマ1が停止
H160 MOVLW B'00000101' ;8ビットリテラルをWレジスタへ格納
H161 MOVWF T1CON ;Wレジスタからデータを移動します。
;****************************************************************
;PR2の初期化 PWMの周期幅の設定 (パルス幅CCPR1L) TMR2のカウント数
H162 BCF STATUS,RP0 ;0 バンク0を選択する
H163 BCF STATUS,RP1 ;0 バンク0を選択する
H164 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H165 MOVWF PR2 ;Wレジスタからデータを移動します。
;TMR2の初期化
H166 BCF STATUS,RP0 ;0 バンク0を選択する
H167 BCF STATUS,RP1 ;0 バンク0を選択する
H168 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H169 MOVWF TMR2 ;Wレジスタからデータを移動します。
;タイマー2(DS30487-79ページ) 未使用
;前段4ビットプリスケーラ、出力段4ビットポストスケーラ付き8ビットカウンタ
;CCP1モジュールのPWMモードのPWMタイムベースとして使用できる
;入力は内部クロックのみ
;T2CON:TIMER2コントロールレジスタ(12H DS30487-80ページ)
;----- T2CON Bits ---------------------------------------------------------
;タイマ2出力ポストスケール選択
;0000=1:1ポストスケール これに設定
;0001=1:2ポストスケール
;0010=1:3ポストスケール
;・
;・
;・
;1111=1:16ポストスケール
;6bit0 TOUTPS3
;5bit0 TOUTPS2
;4bit0 TOUTPS1
;3bit0 TOUTPS0
;2bit0 TMR2ON
;1タイマ2がオンになっています
;0タイマ2はオフになっています
;
;00プリスケーラは1 これに設定
;01プリスケーラは4
;1×プリスケーラは16
;1bit0 T2CKPS1
;0bit0 T2CKPS0
H16A BCF STATUS,RP0 ;0 バンク0を選択する
H16B BCF STATUS,RP1 ;0 バンク0を選択する
H16C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H16D MOVWF T2CON ;Wレジスタからデータを移動します。
;****************************************************************
;CCP1CON:キャプチャ/コンペア/PWM制御レジスタ1(アドレス17H DS30487-81ページ)
;----- CCP1CON Bits -------------------------------------------------------
; CCPR1Lレジスタの下位に連結されるビット
; 10ビットとしてPWMのパルス幅を指定する時用。
; 今回は0固定
;5bit0 CCP1X
;4bit0 CCP1Y
;0000 CCPモジュール未使用(CCPモジュール初期化)
;0100 キャプチャモード(立ち下がりエッジ)
;0101 キャプチャモード(立ち上がりエッジ)
;0110 キャプチャモード(立ち上がりエッジ4回毎)
;0111 キャプチャモード(立ち上がりエッジ16回毎)
;1000 コンペアモード(出力セット CCP1IFセット)
;1001 コンペアモード(出力クリア CCP1IFセット)
;1010 コンペアモード(出力変化なし CCP1IFセット) これにする
;1011 コンペアモード(出力変化なし CCP1IFセット TMR1リセット A/Dが有効なら開始)
;11xx PWMモード
;3bit1 CCP1M3
;2bit0 CCP1M2
;1bit1 CCP1M1
;0bit0 CCP1M0
;CCPモジュール初期化
H16E BCF STATUS,RP0 ;0 バンク0を選択する
H16F BCF STATUS,RP1 ;0 バンク0を選択する
H170 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H171 MOVWF CCP1CON ;Wレジスタからデータを移動します。
;CCPR1L,H コンペア・キャプチャ・PWM用のレジスタの初期設定
;コンペア初期値の設定
;タイマー1は20kHzに設定してある
;カウント値は0-100の間になる
;3分割の設定で 33づつ増減とする 6666かもしれない
;初期値 65535-20000+33=45568 ではなくて
;初期値 65535-20000+6666=52201 ではなくて
;初期値 65535-20000=45535
;1011 0001 1101 1111
H172 MOVLW B'11011111' ;8ビットリテラルをWレジスタへ格納
H173 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H174 MOVLW B'10110001' ;8ビットリテラルをWレジスタへ格納
H175 MOVWF CCPR1H ;Wレジスタからデータを移動します。
;CCPモジュール開始
H176 MOVLW B'00001010' ;8ビットリテラルをWレジスタへ格納
H177 MOVWF CCP1CON ;Wレジスタからデータを移動します。
;****************************************************************
;SSPBUFの初期化 SPI通信用のバッファ
H178 BCF STATUS,RP0 ;0 バンク0を選択する
H179 BCF STATUS,RP1 ;0 バンク0を選択する
H17A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H17B MOVWF SSPBUF ;Wレジスタからデータを移動します。
;****************************************************************
;SSPADD シリアル通信用 スレーブ時の自アドレス の 初期化
H17C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H17D MOVWF SSPADD ;Wレジスタからデータを移動します。
;****************************************************************
;****************************************************************
;SSPSTAT:同期シリアルポート・ステータス・レジスタ(アドレス94H DS30487-88ページ)
;----- SSPSTAT Bits -------------------------------------------------------
;7bit1 SMP スルーレート
;1標準速度指定(100kbps,1MHz)
;0高速指定(400kbps)
;
;6bit1 CKE クロックエッジ
;1SCKの立ち上がり
;0SCKの立ち下がり
;
;5bitx D
;1最新受信バイトがデータである
;0最新受信バイトがアドレスである
;
;5bit I2C_DATA
;5bit NOT_A
;5bit NOT_ADDRESS
;5bit D_A
;5bit DATA_ADDRESS
;
;4bit P Stopシーケンス検出
;1検出した
;0未検出
;
;4bit I2C_STOP
;
;3bit S Startシーケンス検出
;1検出した
;0未検出
;
;3bit I2C_START
;2bit R スレーブ時
;1Read 0Write マスタ時 1送信中
;0送信中ではない
;
;2bit I2C_READ
;2bit NOT_W
;2bit NOT_WRITE
;2bit R_W
;2bit READ_WRITE
;
;1bit UA アドレス更新要求
;1更新が必要
;0更新不要
;
;0bit BF 受信中
;1受信完了
;0受信未完了
;送信中
;1送信中
;0送信完了
H17E BSF STATUS,RP0 ;1 バンク1を選択する
H17F BCF STATUS,RP1 ;0 バンク1を選択する
H180 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H181 MOVWF SSPSTAT ;Wレジスタからデータを移動します。
;****************************************************************
;SSPCON:同期シリアルポートコントロールレジスタ(アドレス14H DS3048-89ページ)
;----- SSPCON Bits --------------------------------------------------------
;7bit0 WCOL
;1SSPモジュールビジー、SSPBUF書き込み失敗
;0衝突なし
;
;6bit0 SSPOV
;1SSPBUFオーバーフロー
;0オーバーフローではありません
;
;5bit0 SSPEN
;1シリアル有効 SDA SCL
;0シリアル無効I/O
;
;4bit0 CKP 4bit0
;1立ち上がりエッジで受信
;0立ち下がりエッジで受信
;
;3bit0 SSPM3 同期シリアルポートモード
;2bit0 SSPM2 SPIマスターモード クロック OSC/4
;1bit0 SSPM1
;0bit0 SSPM0
H182 BCF STATUS,RP0 ;0 バンク0を選択する
H183 BCF STATUS,RP1 ;0 バンク0を選択する
H184 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H185 MOVWF SSPCON ;Wレジスタからデータを移動します。
;****************************************************************
;TXREGの初期化 送信データ用レジスタ
H186 BCF STATUS,RP0 ;0 バンク0を選択する
H187 BCF STATUS,RP1 ;0 バンク0を選択する
H188 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H189 MOVWF TXREG ;Wレジスタからデータを移動します。
;****************************************************************
;USART
;TXSTA:送信ステータスおよび制御レジスタ(アドレス98H DS30487-97ページ)
;----- TXSTA Bits ---------------------------------------------------------
;7bit0 CSRC クロック選択
;1内部
;0外部
;
;6bit0 TX9 ビットモード
;1,9ビット
;0,8ビット
;
;6bit NOT_TX8
;6bit TX8_9
;
;5bit0 TXEN 送信許可
;1許可
;0禁止
;
;4bit0 SYNC モード選択
;1同期
;0非同期
;
;2bit0 BRGH 高速サンプル
;1高速
;0低速
;
;1bit0 TRMT 送信レジスタ
;1TSR空
;0TSRフル
;
;0bit0 TX9D 送信データ9ビット目
;0bit TXD8
H18A BSF STATUS,RP0 ;1 バンク1を選択する
H18B BCF STATUS,RP1 ;0 バンク1を選択する
H18C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H18D MOVWF TXSTA ;Wレジスタからデータを移動します。
;****************************************************************
;RCREGの初期化 受信データ用レジスタ
H18E BCF STATUS,RP0 ;0 バンク0を選択する
H18F BCF STATUS,RP1 ;0 バンク0を選択する
H190 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H191 MOVWF RCREG ;Wレジスタからデータを移動します。
;RCSTA:11-2ステータスレジスタを受け取り、制御レジスタ(アドレス18H DS30487-98ページ)
;----- RCSTA Bits ---------------------------------------------------------
;7bit0 SPEN シリアルピン
;1シリアル
;0汎用
;
;6bit0 RX9 ビットモード
;1、9ビット
;0、8ビット
;
;6bit RC9
;6bit NOT_RC8
;6bit RC8_9
;
;5bit0 SREN シングル受信許可
;1許可
;0禁止
;
;4bit0 CREN 継続受信許可
;1許可
;0禁止
;
;3bit0 ADDEN アドレス受信許可(9ビットモードのみ)
;1許可
;0禁止
;
;2bit0 FERR フレーミングエラーステータス
;1エラー
;0正常
;
;1bit0 OERR オーバーランエラーステータス
;1エラー
;0正常
;
;0bit0 RX9D 受信デーた9ビット目パリティ
;0bit RCD8
H192 BCF STATUS,RP0 ;0 バンク0を選択する
H193 BCF STATUS,RP1 ;0 バンク0を選択する
H194 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H195 MOVWF RCSTA ;Wレジスタからデータを移動します。
;****************************************************************
;SPBRG ボーレートの設定(アドレス99H)
H196 BSF STATUS,RP0 ;1 バンク1を選択する
H197 BCF STATUS,RP1 ;0 バンク1を選択する
H198 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H199 MOVWF SPBRG ;Wレジスタからデータを移動します。
;****************************************************************
;A/D変換の設定
;ANSEL:アナログSELECT REGISTER(アドレス 9BH DS30487-113ページ)
;----- ANSEL Bits ---------------------------------------------------------
;6bit0 ANS6 AN6アナログ
;5bit0 ANS5 AN5アナログ
;4bit0 ANS4 AN4アナログ
;3bit0 ANS3 AN3アナログ
;2bit0 ANS2 AN2アナログ
;1bit0 ANS1 AN1アナログ
;0bit0 ANS0 AN0アナログ
H19A BSF STATUS,RP0 ;1 バンク1を選択する
H19B BCF STATUS,RP1 ;0 バンク1を選択する
H19C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H19D MOVWF ANSEL ;Wレジスタからデータを移動します。
;****************************************************************
;ADCON0:A/D制御レジスタ(アドレス 1FH DS30487-114ページ)
;----- ADCON0 Bits --------------------------------------------------------
;A/D変換クロック ADCON1のADCS2が2ビット目
;000 FOSC/2
;001 FOSC/8
;010 FOSC/32
;011 FRC
;000 FOSC/4
;001 FOSC/16
;010 FOSC/64
;011 FRC
;7bit0 ADCS1
;6bit0 ADCS0
;CHS <2:0>: アナログチャネル選択ビット
;000 = チャネル0(RA0 / AN0)
;001 = チャンネル1(RA1 / AN1)
;010 = チャンネル2(RA2 / AN2)
;011 = チャンネル3(RA3 / AN3)
;100 = チャンネル4(RA4 / AN4)
;101 = チャンネル5(RB6 / AN5)
;110 = チャンネル6(RB7 / AN6)
;5bit0 CHS2
;4bit0 CHS1
;3bit0 CHS0
;2bit0 GO
;1A/D変換を開始
;0完了
;
;2bit NOT_DONE
;2bit GO_DONE
;0bit0 ADON
;1A/Dコンバータが動作
;0A/Dコンバータの電源オフ
H19E BCF STATUS,RP0 ;0 バンク0を選択する
H19F BCF STATUS,RP1 ;0 バンク0を選択する
H1A0 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H1A1 MOVWF ADCON0 ;Wレジスタからデータを移動します。
;****************************************************************
;ADCON1:A/D制御レジスタ1(アドレス9FH DS30487-115ページ)
;----- ADCON1 Bits --------------------------------------------------------
;7bit1 ADFM A/D結果フォーマット
;1右詰
;0左揃え
;
;6bit0 ADCS2 A/D変換クロック 0、1ビットはADCON0
;
;VCFG<1:0>ビット 基準電圧の設定
;00 AVDD AVSS これに設定
;01 AVDD VREF-
;10 VREF+ AVSS
;11 VREF+ VREF-
;5bit0 VCFG1
;4bit0 VCFG0
H1A2 BSF STATUS,RP0 ;1 バンク1を選択する
H1A3 BCF STATUS,RP1 ;0 バンク1を選択する
H1A4 MOVLW B'10000000' ;8ビットリテラルをWレジスタへ格納
H1A5 MOVWF ADCON1 ;Wレジスタからデータを移動します。
;****************************************************************
;CMCON:コンパレータモジュール制御レジスタ(アドレス9CH DS30487-121ページ)
;----- CMCON Bits ---------------------------------------------------------
;7bit C2OUT コンパレータ出力
;6bit C1OUT コンパレータ出力
;5bit C2INV コンパレータ反転出力
;4bit C1INV コンパレータ反転出力
;3bit0 CIS コンパレータの入力ピン切り替え
;2bit1 CM2 コンパレータオフ デフォルト
;1bit1 CM1
;0bit1 CM0
H1A6 BSF STATUS,RP0 ;1 バンク1を選択する
H1A7 BCF STATUS,RP1 ;0 バンク1を選択する
H1A8 NOP ;BSF CMCON,CIS ;何もしない
H1A9 BCF CMCON,CIS
H1AA BSF CMCON,CM2
H1AB NOP ;BCF CMCON,CM2 ;何もしない
H1AC BSF CMCON,CM1
H1AD NOP ;BCF CMCON,CM1 ;何もしない
H1AE BSF CMCON,CM0
H1AF NOP ;BCF CMCON,CM0 ;何もしない
;****************************************************************
;CVRCON:コンパレータ電圧リファレンス制御レジスタ(アドレス 9DH DS30487-127ページ)
;----- CVRCON Bits --------------------------------------------------------
;7bit0 CVREN リファレンス
;1使う
;0使わない
;
;6bit0 CVROE Vrefの外部出力
;1RA2に出力
;0出力せず
;
;5bit0 CVRR
;1,0.0-0.75 24step
;0,0.25-0.75 43step
;
;3bit0 CVR3 電圧微調節
;2bit0 CVR2
;1bit0 CVR1
;0bit0 CVR0
H1B0 BSF STATUS,RP0 ;1 バンク1を選択する
H1B1 BCF STATUS,RP1 ;0 バンク1を選択する
H1B2 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H1B3 MOVWF CVRCON ;Wレジスタからデータを移動します。
;****************************************************************
;ウォッチドッグタイマの設定
;WDTCON:ウォッチドッグ制御レジスタ(アドレス105H DS30487-142ページ)
;----- WDTCON Bits --------------------------------------------------------
;WDTPS<3:0>Watch Dog Prescaler value
;0000=1:32
;0001=1:64
;0010=1:128
;0011=1:256
;0100=1:512
;0101=1:1024
;0110=1:2048
;0111=1:4096
;1000=1:8192
;1001=1:16384
;1010=1:32768
;1011=1:65536
;4bit0 WDTPS3
;3bit0 WDTPS2
;2bit0 WDTPS1
;1bit0 WDTPS0
;0bit1 SWDTEN
;1Watch dog timer is on
;0Watch dog timer is off
;
;0bit SWDTE 0bit
H1B4 BCF STATUS,RP0 ;0 バンク2を選択する
H1B5 BSF STATUS,RP1 ;1 バンク2を選択する
H1B6 MOVLW B'00000001' ;8ビットリテラルをWレジスタへ格納
H1B7 MOVWF WDTCON ;Wレジスタからデータを移動します。
;****************************************************************
;ULPWUモジュールの設定
;極低消費電流ウェイクアップ
;コンデンサに充電してスリープ。放電後コンパレータの割り込みで復帰
;取説で見た気がしたけど見当たらなくなった
;と思いきやバンク0に書き込んだことがあった気がした
;EQUのアドレス指定が別になっていて、間違えないようになっていた
;ビットは同じだけど、間違えない先だから大丈夫なのかもしれない
H1B8 GOTO H1F0 ;
H1B9 NOP ;何もしない
H1BA NOP ;何もしない
H1BB NOP ;何もしない
H1BC NOP ;何もしない
H1BD NOP ;何もしない
H1BE NOP ;何もしない
H1BF NOP ;何もしない
ORG_1F0 ORG 0x1F0 ;特殊機能レジスタの初期化完了ベクタ
H1F0 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより
H1F1 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより
H1F2 BSF GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了フラグセット
H1F3 GOTO H200 ;メインプログラム変数の初期化へ
H1F4 NOP ;何もしない
H1F5 NOP ;何もしない
H1F6 NOP ;何もしない
H1F7 NOP ;何もしない
H1F8 NOP ;何もしない
H1F9 NOP ;何もしない
H1FA NOP ;何もしない
H1FB NOP ;何もしない
H1FC NOP ;何もしない
H1FD NOP ;何もしない
H1FE NOP ;何もしない
H1FF NOP ;何もしない
;****************************************************************
;今の設定
;CPU8MHzで動作中
;割り込み無しでシステムの初期設定まで
;****************************************************************
; Main Routine
;****************************************************************
ORG_200 ORG 0x200 ;メインプログラム変数の初期化開始ベクタ
H200 CLRWDT ;ウォッチドックタイマのリセット
H201 BTFSS GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了フラグが1だったら次をスキップ
H202 GOTO H000 ;
H203 BCF GPR20,Variable_ini_comp ;メインプログラム変数初期化完了フラグクリア バンク0指定
H204 BCF GPR20,Step_memory ;STEP I/O割り込みの入力状態記憶
H205 BCF GPR20,Dir_memory ;DIR I/O割り込みの入力状態記憶
;STEP変数の初期化
H206 MOVLW H'00' ;H'00'をWへ格納
H207 MOVWF STEP
;モーターの励磁モード設定 (MODE)
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1-2相励磁
;0000 0100:PWMステップ
H208 MOVLW B'00000100' ;モーターの励磁モード設定
H209 MOVWF MODE ;WをMODEへ格納 バンク0指定
H20A GOTO H230
H20B NOP
H20C NOP
H20D NOP
H20E NOP
H20F NOP
;モーターの分割数設定(PWMステップ用の設定)
;10分割にしてみることにした
ORG_230 ORG 0x230
H230 MOVLW B'00001010' ;H'00010100'をWへ格納 10分割に設定
H231 MOVWF DIV ;WをDIVへ格納 バンク0指定
H232 NOP ;何もしない
H233 NOP ;何もしない
H234 NOP ;何もしない
H235 NOP ;何もしない
H236 NOP ;何もしない
H237 NOP ;何もしない
H238 NOP ;何もしない
H239 NOP ;何もしない
H23A NOP ;何もしない
H23B NOP ;何もしない
H23C NOP ;何もしない
H23D NOP ;何もしない
H23E NOP ;何もしない
H23F NOP ;何もしない
ORG_240 ORG 0x240
;レジスタの初期化完了
H240 BSF GPR20,Variable_ini_comp ;メインプログラム変数初期化完了フラグセット バンク0指定
;サーボオン リセットがかかったことがわかるように 初期動作しようかな やっぱりやめた
;サーボオンした時、移動中のリセットだった場合いきなり大きく動いてぶつかるかもしれない
;パソコンからパルス出力中に電源を入れないこと。
;一軸だけリセットだと 他のは動いていて 変な動きになるかもしれない
;できるだけ早く復帰して 動き始めた方がいいかもしれない これが良さそう
H241 CALL H600 ;音 ド
H242 CALL H650 ;音 レ
H243 CALL H6A0 ;音 ミ
H244 NOP
H245 NOP
H246 NOP
H247 NOP
H248 NOP
H249 NOP
H24A NOP
H24B NOP
H24C NOP
H24D NOP
H24E NOP
H24F NOP
;****************************************************************
ORG_250 ORG 0x250
;起動時の初期励磁プログラムの選択ベクタ
H250 CLRWDT ;ウォッチドッグタイマのリセット
H251 BTFSS GPR20,Variable_ini_comp ;メインプログラム変数初期化完了 1なら次をスキップ
H252 GOTO H000 ;リセットベクタへ
H253 BTFSC MODE,Variable_ini_comp ;ビットが0なら次の命令をスキップする
H254 GOTO H300 ;PWMステッププログラム
H255 BTFSC MODE,1 ;ビットが0なら次の命令をスキップする
H256 GOTO H290 ;1-2相励磁プログラム
H257 BTFSC MODE,0 ;ビットが0なら次の命令をスキップする
H258 GOTO H262 ;2相 初期励磁
H259 GOTO H260 ;1相 初期励磁
H25A NOP ;何もしない
H25B NOP ;何もしない
H25C NOP ;何もしない
H25D NOP ;何もしない
H25E NOP ;何もしない
H25F NOP ;何もしない
;****************************************************************
ORG_260 ORG 0x260
;1相 初期励磁
H260 BSF PORTA,0 ;PORTA,0bit 出力ON
H261 GOTO H270 ;1相励磁プログラム
;2相 初期励磁
H262 BSF PORTA,0 ;PORTA,0bit 出力ON
H263 BSF PORTA,1 ;PORTA,0bit 出力ON
H264 GOTO H270 ;2相励磁プログラム
H265 ;何もしない
H266 ;何もしない
H267 ;何もしない
H268 ;何もしない
H269 ;何もしない
H26A ;何もしない
H26B ;何もしない
H26C ;何もしない
H26D ;何もしない
H26E ;何もしない
H26F ;何もしない
ORG_270 ORG 0x270 ;RB0/INT外部割込みのみ有効にする(1相、2相励磁プログラム)
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H270 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H271 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H272 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ(割り込み待ち)(1相、2相励磁用)
H273 CLRWDT ;ウォッチドッグタイマのリセット
H274 BTFSS GPR20,Step_memory ;STEP入力状態が1なら次の命令をスキップする
H275 GOTO H273 ;入力待ちへ戻る(割り込み待ちへ戻る)
H276 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H277 GOTO H27E ;STEPの立ち上がりが発生した時にDIRが1だった時
;STEPの立ち上がりが発生した時にDIRが0だった時
H278 RLF PORTA,1 ;左へ1ビットシフト PORTAへ上書き
H279 BTFSS PORTA,4 ;PORTA4ビットが1なら次の命令をスキップ
H27A GOTO H283 ;STEP信号OFF待ちベクタへ
H27B BCF PORTA,4 ;PORTA4ビットをクリア
H27C BSF PORTA,0 ;PORTA0ビットをセット
H27D GOTO H283 ;STEP信号OFF待ちベクタへ
;STEPの立ち上がりが発生した時にDIRが1だった時
H27E RRF PORTA,1 ;右へ1ビットシフト PORTAへ上書き
H27F BTFSS STATUS,C ;STATUS,Cビットが1なら次の命令をスキップ
H280 GOTO H283 ;STEP信号OFF待ちベクタへ
H281 BSF PORTA,3 ;PORTA3ビットをセット
H282 GOTO H283 ;STEP信号OFF待ちベクタへ
;STEP信号OFF待ち
H283 CLRWDT ;ウォッチドックタイマのリセット
H284 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H285 GOTO H283 ;STEP入力が1の時は、0に戻り待ちへ戻る
H286 BCF GPR20,Step_memory ;STEP入力状態が1だったフラグオフ
H287 GOTO H270 ;割込み開始へ戻る(1相、2相励磁用)
H288 NOP ;何もしない
H289 NOP ;何もしない
H28A NOP ;何もしない
H28B NOP ;何もしない
H28C NOP ;何もしない
H28D NOP ;何もしない
H28E NOP ;何もしない
H28F NOP ;何もしない
;モーターの励磁モード (MODE)
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1?2相励磁
;0000 0100:PWMステップ
;2019年10月11日
;CNCの動作速度
;200分割のPWMの時の最速の移動速度の計算
;0.001秒のパルス幅がMACH3から出せる最速だとしたら
;一秒間に 1000パルスの半分で 500パルス出るとしたら
;一回転40000パルスにすると
;一回転に80秒いることになる
;ちょっと遅すぎる気がした
;PICは 8,000,000Hzになっていて
;1usパルスは 4000クロックON 4000クロックOFFのことで
;十分拾えるはず
;一パルス入った時に その位置まで じわーっと動いていけば 良さそうな気がした
;4000クロックの間に その位置まで行けるのか わからなくなった
;割り込みを使わずに ループで入力待ちの方がわかりやすいかもしれない気がしてきた
;PORTAの設定
;
;17 RA0/AN0 TTL A出力
;18 RA1/AN1 TTL /A出力
;1 RA2/AN2/CVref/Vref- TTL B出力
;2 RA3/AN3/Vref+/C1out TTL /B出力
;3 RA4/AN4/T0CK1/C2out ST 空き 0出力
;4 RA5/MCLR*/Vpp ST +5Vに直結 リセット入力
;15 RA6/OSC2/CLK0 ST (内部周波数)/4Hzのモニター出力
;16 RA7/OSC1/CLK1 ST/CMOS 空き 0出力
;モーター ユニポーラ
;励磁方式
;1相励磁(ユニポーラモーターでのフルステップ駆動) 6線モーター
;2相励磁(バイポーラモーターでのフルステップ駆動) 4線モーター
;1?2相励磁(ハーフステップ駆動)
;PWMステップ駆動
;励磁の順序 A,/A,B,/B
;分岐の方法
;BTFSC ;レジスタの指定したビットが0なら次の命令をスキップ
;BTFSS ;レジスタの指定したビットが1なら次の命令をスキップ
;DECFSZ ;レジスタ値を1減算し,値が0なら次の命令をスキップ
;INCFSZ ;レジスタ値を1加算し,値が0なら次の命令をスキップ
;1-2相 初期励磁
ORG_290 ORG 0x290
H290 BSF PORTA,0 ;PORTA,0bit 出力ON
H291 GOTO H2A0 ;1-2相励磁プログラム
H292 ;何もしない
H293 ;何もしない
H294 ;何もしない
H295 ;何もしない
H296 ;何もしない
H297 ;何もしない
H298 ;何もしない
H299 ;何もしない
H29A ;何もしない
H29B ;何もしない
H29C ;何もしない
H29D ;何もしない
H29E ;何もしない
H29F ;何もしない
ORG_2A0 ORG 0x2A0 ;割込み開始 (1-2相用)
H2A0 CLRWDT ;ウォッチドッグタイマのリセット
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H2A1 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H2A2 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H2A3 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ (1-2相用)
H2A4 CLRWDT ;ウォッチドッグタイマのリセット 割込み待ち開始
H2A5 BTFSS GPR20,Step_memory ;STEP入力状態が1なら次の命令をスキップする(1-2相励磁用)
H2A6 GOTO H2A4 ;入力待ちループへ戻る(1-2相励磁用)
H2A7 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H2A8 GOTO H2B4 ;STEPの立ち上がりが発生した時にDIRが1だった時
;正転
H2A9 CLRF PCLATH
H2AA MOVLW D'1'
H2AB ADDWF STEP,1
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H2AC MOVF STEP,0 ;DATA2
H2AD XORLW D'8';DATA1
H2AE BTFSS STATUS,Z
H2AF GOTO H2C0;8以外だったら ステップ更新完了
;8と同じだったら
H2B0 MOVLW D'0'
H2B1 MOVWF STEP ;WをSTEPへ格納 バンク0指定
H2B2 GOTO H2C0;ステップ更新完了
H2B3 NOP
ORG_2B4 ORG 0x2B4
H2B4 CLRF PCLATH
;逆転
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H2B5 MOVF STEP,0 ;DATA2
;H2B6 XORWF D'0',0;DATA1
H2B6 BTFSS STATUS,Z ;1だったら次をスキップ
H2B7 GOTO H2BC ;0以外だったら
H2B8 GOTO H2B9 ;0と同じだったら
;逆転したら実機だけエラーになるのはこれかもしれない
;H2B5 MOVF STEP になっていた ,0を書いてなかった
;1-2相も実機だと逆転しなくなった
;シュミレーションでは動いてる
;前に動いたことがあった気がして
;戻せるかもしれないような そのまま進めていったほうがいいような
;結果00だったら
H2B9 MOVLW D'7'
H2BA MOVWF STEP ;WをSTEPへ格納 バンク0指定
H2BB GOTO H2C0;ステップ更新完了
;結果00以外だったら
H2BC MOVLW D'1'
H2BD SUBWF STEP,1
H2BE GOTO H2C0;ステップ更新完了
H2BF NOP
;1-2相励磁 I/O割り込み発生後、ステップ値の変更後に出力の更新
ORG_2C0 ORG 0x2C0
;プログラムカウンタを変更してジャンプ
H2C0 MOVLW B'00000010'
H2C1 MOVWF PCLATH
H2C2 MOVF STEP,0
H2C3 ADDWF PCL,1
H2C4 GOTO H2D0 ;0
H2C5 GOTO H2D4 ;1
H2C6 GOTO H2D8 ;2
H2C7 GOTO H2DC ;3
H2C8 GOTO H2E0 ;4
H2C9 GOTO H2E4 ;5
H2CA GOTO H2E8 ;6
H2CB GOTO H2EC ;7
H2CC NOP ;進むほうに脱調がかかってる
H2CD NOP
H2CE NOP ;PWMステップの前に1?2相が動かなくなってる
H2CF NOP ;ビットでCASEから データでCASEに変更したとき
;動かなくなったときとか調子の悪いときは
;一個前のバージョンに戻すとよさそう
;次のバージョンで修正すると
;前のバージョンも 修正が必要になった時
;次のバージョンが完成しても アドレスの全変更が必要になる
ORG_2D0 ORG 0x2D0
;STEP0
H2D0 CLRF PCLATH
H2D1 MOVLW B'00000001' ; /B,B,/A,A
H2D2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2D3 GOTO H2F0 ;
;STEP1
H2D4 CLRF PCLATH
H2D5 MOVLW B'00000011' ; /B,B,/A,A
H2D6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2D7 GOTO H2F0 ;
;STEP2
H2D8 CLRF PCLATH
H2D9 MOVLW B'00000010' ; /B,B,/A,A
H2DA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2DB GOTO H2F0 ;
;STEP3
H2DC CLRF PCLATH
H2DD MOVLW B'00000110' ; /B,B,/A,A
H2DE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2DF GOTO H2F0 ;
;STEP4
H2E0 CLRF PCLATH
H2E1 MOVLW B'00000100' ; /B,B,/A,A
H2E2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2E3 GOTO H2F0 ;
;STEP5
H2E4 CLRF PCLATH
H2E5 MOVLW B'00001100' ; /B,B,/A,A
H2E6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2E7 GOTO H2F0 ;
;STEP6
H2E8 CLRF PCLATH
H2E9 MOVLW B'00001000' ; /B,B,/A,A
H2EA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2EB GOTO H2F0 ;
;STEP7
H2EC CLRF PCLATH
H2ED MOVLW B'00001001' ; /B,B,/A,A
H2EE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2EF GOTO H2F0 ;
ORG_2F0 ORG 0x2F0 ;入力が0だったら、フラグを消して戻る
H2F0 CLRWDT ;ウォッチドックタイマのリセット
H2F1 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H2F2 GOTO H2F0 ;STEP入力が1の時は、0に戻り待ちへ戻る
H2F3 BCF GPR20,Step_memory ;前の入力状態が1だったフラグオフ
H2F4 GOTO H2A0 ;割込み開始へ戻る
H2F5 NOP ;何もしない
H2F6 NOP ;何もしない
H2F7 NOP ;何もしない
H2F8 NOP ;何もしない
H2F9 NOP ;何もしない
H2FA NOP ;何もしない
H2FB NOP ;何もしない
H2FC NOP ;何もしない
H2FD NOP ;何もしない
H2FE NOP ;何もしない
H2FF NOP ;何もしない
;PWMステップ用
;****************************************************************
;PWMステップ 初期励磁
ORG_300 ORG 0x300
H300 CLRF PCLATH
H301 BSF PORTA,0 ;PORTA,0bit 出力ON
H302 MOVLW B'00000010'
H303 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
;PWMステップのステップ値
H304 MOVLW B'00000001'
H305 MOVWF PSTEP ;WをPSTEPへ格納 バンク0指定
H306 BCF GPR21,PWM_ACTION ;STEP変更可:0 PWM動作中:1
;ステップとPWMステップを合わせた値
H307 MOVLW H'00'
H308 MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H309 GOTO H310 ;PWMステッププログラム
H30A NOP ;何もしない
H30B NOP ;何もしない
H30C NOP ;何もしない
H30D NOP ;何もしない
H30E NOP ;何もしない
H30F NOP ;何もしない
ORG_310 ORG 0x310 ;割込み開始 (PWMステップ用)
H310 CLRWDT ;ウォッチドッグタイマのリセット
H311 CLRF PCLATH
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H312 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H313 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H314 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ開始 (PWMステップ用)
H315 CLRWDT ;ウォッチドッグタイマのリセット 割込み待ち開始
H316 BTFSC GPR20,Step_memory ;STEP入力状態が0なら次の命令をスキップする
H317 GOTO H330 ;割り込み発生 ステップ値の更新
;タイマーの確認とPWM出力の更新のみ
;****************************************************************
;TMR1のカウントアップとコンペア使ってPWMを作る
;タイマー1のカウントアップが発生したら自動的にカウント値が0に戻る。
;その時にタイマーの初期値を再セットする。
;しばらくうごかすとタイマーが止まったような動きになる
;タイマー停止中に割り込みがかかって リセットがうまくいってないのかもしれない
;入力の割り込みを禁止にしたらいいかもしれない
;どこで割り込みがかかってもうまくリセットできるようにしたい
;タイマーの初期値をセットした後にふらぐのリセットがよさそう
;タイマー1がオーバーフローしているか確認する 1のときスキップ
H318 BTFSS PIR1,0 ;TMR1IF 1:オーバーフロー発生 0:オーバーフローしませんでした
;タイマー1カウントアップ未発生時、コンペアが発生しているか確認する
H319 GOTO H321 ;オーバーフロー未発生
;オーバーフロー発生
H31A MOVF T1INIL,0 ;T1INILをWへ格納
H31B MOVWF TMR1L ;WをTMR1Lへ格納
H31C MOVF T1INIH,0 ;T1INIHをWへ格納
H31D MOVWF TMR1H ;TMR1Hへ格納
H31E BCF PIR1,0 ;TMR1IF オーバーフロー発生フラグクリア
;PAPWMの1になっているビットのところを出力ON
H31F MOVF PAPWM,0 ;WレジスタにPAPWMを格納
;いずれかのビットが1なら1
H320 IORWF PORTA,1 ; 論理和 W OR f → W か f へ格納
H321 MOVF CCPR1H,0 ;WレジスタにCCPR1Hの値を代入
H322 SUBWF TMR1H,0 ;TMR1H-Wを計算しWへ格納、B_REG>=WのときキャリービットC=1となる
H323 BTFSS STATUS,C ;キャリー発生のときジャンプ
H324 GOTO H315 ;コンペア未発生
H325 MOVF CCPR1L,0 ;WレジスタにCCPR1Lの値を代入
H326 SUBWF TMR1L,0 ;TMR1L-Wを計算しWへ格納、B_REG>=WのときキャリービットC=1となる
H327 BTFSS STATUS,C ;キャリー発生のときジャンプ
H328 GOTO H315 ;コンペア未発生
;CCP1CON:キャプチャ/コンペア/PWM制御レジスタ1(アドレス17H DS30487-81ページ)
;----- CCP1CON Bits -------------------------------------------------------
; CCPR1Lレジスタの下位に連結されるビット
; 10ビットとしてPWMのパルス幅を指定する時用。
; 今回は0固定
;CCP1X 5bit0
;CCP1Y 4bit0
;0000 CCPモジュール未使用(リセット)
;0100 キャプチャモード(立ち下がりエッジ)
;0101 キャプチャモード(立ち上がりエッジ)
;0110 キャプチャモード(立ち上がりエッジ4回毎)
;0111 キャプチャモード(立ち上がりエッジ16回毎)
;1000 コンペアモード(出力セット CCP1IFセット)
;1001 コンペアモード(出力クリア CCP1IFセット)
;1010 コンペアモード(出力変化なし CCP1IFセット) これにする
;1011 コンペアモード(出力変化なし CCP1IFセット TMR1リセット A/Dが有効なら開始)
;11xx PWMモード
;CCP1M3 3bit1
;CCP1M2 2bit0
;CCP1M1 1bit1
;CCP1M0 0bit0
;マスクデータの作成 出力をオフにしたいところだけ0になる
H329 COMF PAPWM,0 ;fの0,1反転→Wかfへ格納
H32A ANDWF PORTA,1 ; 論理積 W AND f → W か f へ格納
H32B BSF PIR1,2 ;CCP1IF コンペアの一致発生フラグセット
H32C GOTO H315
H32D NOP ;何もしない
H32E NOP ;何もしない
H32F NOP ;何もしない
ORG_330 ORG 0x330 ;入力からの割り込み発生 (PWMステップ用)
H330 CLRWDT
H331 CLRF PCLATH
H332 CLRF STEP
H333 CLRF PSTEP
H334 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H335 GOTO H340 ;STEPの立ち上がりが発生した時にDIRが1だった時 逆転
;正転
H336 MOVLW D'1'
H337 ADDWF COMBINED_STEPS,1
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H338 MOVF COMBINED_STEPS,0 ;DATA2
H339 XORLW D'24';DATA1
H33A BTFSS STATUS,Z
H33B GOTO H350;24以外だったら ステップ更新完了
;24と同じだったら
H33C MOVLW D'00'
H33D MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H33E GOTO H350;ステップ更新完了
H33F NOP
;逆転
ORG_340 ORG 0x340
;H440 GOTO H700 ;エラーテスト ここまで動作した
;逆転
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H340 MOVF COMBINED_STEPS,0 ;DATA2
;H2B6 XORWF D'0',0;DATA1
H341 BTFSS STATUS,Z ;1だったら次をスキップ
H342 GOTO H347 ;0以外だったら
H343 GOTO H344 ;0と同じだったら
;結果00だったら
H344 MOVLW D'23'
H345 MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H346 GOTO H370;ステップ更新完了
;結果00以外だったら
H347 MOVLW D'1'
H348 SUBWF COMBINED_STEPS,1
H349 GOTO H370;ステップ更新完了
H34A NOP
H34B NOP ;何もしない
H34C NOP ;何もしない
H34D NOP ;何もしない
H34E NOP ;何もしない
H34F NOP ;何もしない
ORG_350 ORG 0x350
;プログラムカウンタを変更してジャンプ 正転
H350 MOVLW B'00000011'
H351 MOVWF PCLATH
H352 MOVF COMBINED_STEPS,0
H353 ADDWF PCL,1
H354 GOTO H390 ;0
H355 GOTO H396 ;1
H356 GOTO H39C ;2
H357 GOTO H3A2 ;3
H358 GOTO H3A8 ;4
H359 GOTO H3AE ;5
H35A GOTO H3B4 ;6
H35B GOTO H3BA ;7
H35C GOTO H3C0 ;8
H35D GOTO H3C6 ;9
H35E GOTO H3CC ;10
H35F GOTO H3D2 ;11
H360 GOTO H3D8 ;12
H361 GOTO H3DE ;13
H362 GOTO H3E4 ;14
H363 GOTO H3EA ;15
H364 GOTO H3F0 ;16
H365 GOTO H3F6 ;17
H366 GOTO H3FC ;18
H367 GOTO H402 ;19
H368 GOTO H408 ;20
H369 GOTO H40E ;21
H36A GOTO H414 ;22
H36B GOTO H41A ;23
H36C NOP ;何もしない
H36D NOP ;何もしない
H36E NOP ;何もしない
H36F NOP ;何もしない
ORG_370 ORG 0x370
;プログラムカウンタを変更してジャンプ 逆転
H370 MOVLW B'00000011'
H371 MOVWF PCLATH
H372 MOVF COMBINED_STEPS,0
H373 ADDWF PCL,1
H374 GOTO H420 ;0
H375 GOTO H426 ;1
H376 GOTO H42C ;2
H377 GOTO H433 ;3
H378 GOTO H438 ;4
H379 GOTO H43E ;5
H37A GOTO H444 ;6
H37B GOTO H44A ;7
H37C GOTO H450 ;8
H37D GOTO H456 ;9
H37E GOTO H45C ;10
H37F GOTO H462 ;11
H380 GOTO H468 ;12
H381 GOTO H46E ;13
H382 GOTO H474 ;14
H383 GOTO H47A ;15
H384 GOTO H480 ;16
H385 GOTO H486 ;17
H386 GOTO H48C ;18
H387 GOTO H492 ;19
H388 GOTO H498 ;20
H389 GOTO H49E ;21
H38A GOTO H4A4 ;22
H38B GOTO H4AA ;23
H38C NOP ;何もしない
H38D NOP ;何もしない
H38E NOP ;何もしない
H38F NOP ;何もしない
ORG_390 ORG 0x390
;STEP 0bit PSTEP 1bit 0
;正転 STEP0 PSTEP1
H390 CLRF PCLATH
H391 MOVLW D'0'
H392 MOVWF STEP
H393 MOVLW D'1'
H394 MOVWF PSTEP
H395 GOTO H4B0
;STEP 0bit PSTEP 1bit 1
;正転 STEP0 PSTEP2
H396 CLRF PCLATH
H397 MOVLW D'0'
H398 MOVWF STEP
H399 MOVLW D'2'
H39A MOVWF PSTEP
H39B GOTO H4B0
;STEP 0bit PSTEP 2bit 2
;正転 STEP1 PSTEP3
H39C CLRF PCLATH
H39D MOVLW D'1'
H39E MOVWF STEP
H39F MOVLW D'3'
H3A0 MOVWF PSTEP
H3A1 GOTO H4B0
;STEP 1bit PSTEP 3bit 3
;正転 STEP1 PSTEP2
H3A2 CLRF PCLATH
H3A3 MOVLW D'1'
H3A4 MOVWF STEP
H3A5 MOVLW D'2'
H3A6 MOVWF PSTEP
H3A7 GOTO H4B0
;STEP 1bit PSTEP 2bit 4
;正転 STEP1 PSTEP1
H3A8 CLRF PCLATH
H3A9 MOVLW D'1'
H3AA MOVWF STEP
H3AB MOVLW D'1'
H3AC MOVWF PSTEP
H3AD GOTO H4B0
;STEP 1bit PSTEP 1bit 5
;正転 STEP2 PSTEP0
H3AE CLRF PCLATH
H3AF MOVLW D'2'
H3B0 MOVWF STEP
H3B1 MOVLW D'0'
H3B2 MOVWF PSTEP
H3B3 GOTO H4B0
;STEP 2bit PSTEP 0bit 6
;正転 STEP2 PSTEP1
H3B4 CLRF PCLATH
H3B5 MOVLW D'2'
H3B6 MOVWF STEP
H3B7 MOVLW D'1'
H3B8 MOVWF PSTEP
H3B9 GOTO H4B0
;STEP 2bit PSTEP 1bit 7
;正転 STEP2 PSTEP2
H3BA CLRF PCLATH
H3BB MOVLW D'2'
H3BC MOVWF STEP
H3BD MOVLW D'2'
H3BE MOVWF PSTEP
H3BF GOTO H4B0
;STEP 2bit PSTEP 2bit 8
;正転 STEP3 PSTEP3
H3C0 CLRF PCLATH
H3C1 MOVLW D'3'
H3C2 MOVWF STEP
H3C3 MOVLW D'3'
H3C4 MOVWF PSTEP
H3C5 GOTO H4B0
;STEP 3bit PSTEP 3bit 9
;正転 STEP3 PSTEP2
H3C6 CLRF PCLATH
H3C7 MOVLW D'3'
H3C8 MOVWF STEP
H3C9 MOVLW D'2'
H3CA MOVWF PSTEP
H3CB GOTO H4B0
;STEP 3bit PSTEP 2bit 10
;正転 STEP3 PSTEP1
H3CC CLRF PCLATH
H3CD MOVLW D'3'
H3CE MOVWF STEP
H3CF MOVLW D'1'
H3D0 MOVWF PSTEP
H3D1 GOTO H4B0
;STEP 3bit PSTEP 1bit 11
;正転 STEP4 PSTEP0
H3D2 CLRF PCLATH
H3D3 MOVLW D'4'
H3D4 MOVWF STEP
H3D5 MOVLW D'0'
H3D6 MOVWF PSTEP
H3D7 GOTO H4B0
;STEP 4bit PSTEP 0bit 12
;正転 STEP4 PSTEP1
H3D8 CLRF PCLATH
H3D9 MOVLW D'4'
H3DA MOVWF STEP
H3DB MOVLW D'1'
H3DC MOVWF PSTEP
H3DD GOTO H4B0
;STEP 4bit PSTEP 1bit 13
;正転 STEP4 PSTEP2
H3DE CLRF PCLATH
H3DF MOVLW D'4'
H3E0 MOVWF STEP
H3E1 MOVLW D'2'
H3E2 MOVWF PSTEP
H3E3 GOTO H4B0
;STEP 4bit PSTEP 2bit 14
;正転 STEP5 PSTEP3
H3E4 CLRF PCLATH
H3E5 MOVLW D'5'
H3E6 MOVWF STEP
H3E7 MOVLW D'3'
H3E8 MOVWF PSTEP
H3E9 GOTO H4B0
;STEP 5bit PSTEP 3bit 15
;正転 STEP5 PSTEP2
H3EA CLRF PCLATH
H3EB MOVLW D'5'
H3EC MOVWF STEP
H3ED MOVLW D'2'
H3EE MOVWF PSTEP
H3EF GOTO H4B0
;STEP 5bit PSTEP 2bit 16
;正転 STEP5 PSTEP1
H3F0 CLRF PCLATH
H3F1 MOVLW D'5'
H3F2 MOVWF STEP
H3F3 MOVLW D'1'
H3F4 MOVWF PSTEP
H3F5 GOTO H4B0
;STEP 5bit PSTEP 1bit 17
;正転 STEP6 PSTEP0
H3F6 CLRF PCLATH
H3F7 MOVLW D'6'
H3F8 MOVWF STEP
H3F9 MOVLW D'0'
H3FA MOVWF PSTEP
H3FB GOTO H4B0
;STEP 6bit PSTEP 0bit 18
;正転 STEP6 PSTEP1
H3FC CLRF PCLATH
H3FD MOVLW D'6'
H3FE MOVWF STEP
H3FF MOVLW D'1'
H400 MOVWF PSTEP
H401 GOTO H4B0
;STEP 6bit PSTEP 1bit 19
;正転 STEP6 PSTEP2
H402 CLRF PCLATH
H403 MOVLW D'6'
H404 MOVWF STEP
H405 MOVLW D'2'
H406 MOVWF PSTEP
H407 GOTO H4B0
;STEP 6bit PSTEP 2bit 20
;正転 STEP7 PSTEP3
H408 CLRF PCLATH
H409 MOVLW D'7'
H40A MOVWF STEP
H40B MOVLW D'3'
H40C MOVWF PSTEP
H40D GOTO H4B0
;STEP 7bit PSTEP 3bit 21
;正転 STEP7 PSTEP2
H40E CLRF PCLATH
H40F MOVLW D'7'
H410 MOVWF STEP
H411 MOVLW D'2'
H412 MOVWF PSTEP
H413 GOTO H4B0
;STEP 7bit PSTEP 2bit 22
;正転 STEP7 PSTEP1
H414 CLRF PCLATH
H415 MOVLW D'7'
H416 MOVWF STEP
H417 MOVLW D'1'
H418 MOVWF PSTEP
H419 GOTO H4B0
;STEP 7bit PSTEP 1bit 23
;正転 STEP0 PSTEP0
H41A CLRF PCLATH
H41B MOVLW D'0'
H41C MOVWF STEP
H41D MOVLW D'0'
H41E MOVWF PSTEP
H41F GOTO H4B0
ORG_420 ORG 0x420
;STEP 0bit PSTEP 0bit 0
;逆転 STEP7 PSTEP1
H420 CLRF PCLATH
H421 MOVLW D'7'
H422 MOVWF STEP
H423 MOVLW D'1'
H424 MOVWF PSTEP
H425 GOTO H4B0
;STEP 0bit PSTEP 1bit 1
;逆転 STEP0 PSTEP0
H426 CLRF PCLATH
H427 MOVLW D'0'
H428 MOVWF STEP
H429 MOVLW D'0'
H42A MOVWF PSTEP
H42B GOTO H4B0
;STEP 0bit PSTEP 2bit 2
;逆転 STEP0 PSTEP1
H42C CLRF PCLATH
H42D MOVLW D'0'
H42E MOVWF STEP
H42F MOVLW D'1'
H430 MOVWF PSTEP
H431 GOTO H4B0
;STEP 1bit PSTEP 3bit 3
;逆転 STEP0 PSTEP2
H432 CLRF PCLATH
H433 MOVLW D'0'
H434 MOVWF STEP
H435 MOVLW D'2'
H436 MOVWF PSTEP
H437 GOTO H4B0
;STEP 1bit PSTEP 2bit 4
;逆転 STEP1 PSTEP3
H438 CLRF PCLATH
H439 MOVLW D'1'
H43A MOVWF STEP
H43B MOVLW D'3'
H43C MOVWF PSTEP
H43D GOTO H4B0
;STEP 1bit PSTEP 1bit 5
;逆転 STEP1 PSTEP2
H43E CLRF PCLATH
H43F MOVLW D'1'
H440 MOVWF STEP
H441 MOVLW D'2'
H442 MOVWF PSTEP
H443 GOTO H4B0
;STEP 2bit PSTEP 0bit 6
;逆転 STEP1 PSTEP1
H444 CLRF PCLATH
H445 MOVLW D'1'
H446 MOVWF STEP
H447 MOVLW D'1'
H448 MOVWF PSTEP
H449 GOTO H4B0
;STEP 2bit PSTEP 1bit 7
;逆転 STEP2 PSTEP0
H44A CLRF PCLATH
H44B MOVLW D'2'
H44C MOVWF STEP
H44D MOVLW D'0'
H44E MOVWF PSTEP
H44F GOTO H4B0
;STEP 2bit PSTEP 2bit 8
;逆転 STEP2 PSTEP1
H450 CLRF PCLATH
H451 MOVLW D'2'
H452 MOVWF STEP
H453 MOVLW D'1'
H454 MOVWF PSTEP
H455 GOTO H4B0
;STEP 3bit PSTEP 3bit 9
;逆転 STEP2 PSTEP2
H456 CLRF PCLATH
H457 MOVLW D'2'
H458 MOVWF STEP
H459 MOVLW D'2'
H45A MOVWF PSTEP
H45B GOTO H4B0
;STEP 3bit PSTEP 2bit 10
;逆転 STEP3 PSTEP3
H45C CLRF PCLATH
H45D MOVLW D'3'
H45E MOVWF STEP
H45F MOVLW D'3'
H460 MOVWF PSTEP
H461 GOTO H4B0
;STEP 3bit PSTEP 1bit 11
;逆転 STEP3 PSTEP2
H462 CLRF PCLATH
H463 MOVLW D'3'
H464 MOVWF STEP
H465 MOVLW D'2'
H466 MOVWF PSTEP
H467 GOTO H4B0
;STEP 4bit PSTEP 0bit 12
;逆転 STEP3 PSTEP1
H468 CLRF PCLATH
H469 MOVLW D'3'
H46A MOVWF STEP
H46B MOVLW D'1'
H46C MOVWF PSTEP
H46D GOTO H4B0
;STEP 4bit PSTEP 1bit 13
;逆転 STEP4 PSTEP0
H46E CLRF PCLATH
H46F MOVLW D'4'
H470 MOVWF STEP
H471 MOVLW D'0'
H472 MOVWF PSTEP
H473 GOTO H4B0
;STEP 4bit PSTEP 2bit 14
;逆転 STEP4 PSTEP1
H474 CLRF PCLATH
H475 MOVLW D'4'
H476 MOVWF STEP
H477 MOVLW D'1'
H478 MOVWF PSTEP
H479 GOTO H4B0
;STEP 5bit PSTEP 3bit 15
;逆転 STEP4 PSTEP2
H47A CLRF PCLATH
H47B MOVLW D'4'
H47C MOVWF STEP
H47D MOVLW D'2'
H47E MOVWF PSTEP
H47F GOTO H4B0
;STEP 5bit PSTEP 2bit 16
;逆転 STEP5 PSTEP3
H480 CLRF PCLATH
H481 MOVLW D'5'
H482 MOVWF STEP
H483 MOVLW D'3'
H484 MOVWF PSTEP
H485 GOTO H4B0
;STEP 5bit PSTEP 1bit 17
;逆転 STEP5 PSTEP2
H486 CLRF PCLATH
H487 MOVLW D'5'
H488 MOVWF STEP
H489 MOVLW D'2'
H48A MOVWF PSTEP
H48B GOTO H4B0
;STEP 6bit PSTEP 0bit 18
;逆転 STEP5 PSTEP1
H48C CLRF PCLATH
H48D MOVLW D'5'
H48E MOVWF STEP
H48F MOVLW D'1'
H490 MOVWF PSTEP
H491 GOTO H4B0
;STEP 6bit PSTEP 1bit 19
;逆転 STEP6 PSTEP0
H492 CLRF PCLATH
H493 MOVLW D'6'
H494 MOVWF STEP
H495 MOVLW D'0'
H496 MOVWF PSTEP
H497 GOTO H4B0
;STEP 6bit PSTEP 2bit 20
;逆転 STEP6 PSTEP1
H498 CLRF PCLATH
H499 MOVLW D'6'
H49A MOVWF STEP
H49B MOVLW D'1'
H49C MOVWF PSTEP
H49D GOTO H4B0
;STEP 7bit PSTEP 3bit 21
;逆転 STEP6 PSTEP2
H49E CLRF PCLATH
H49F MOVLW D'6'
H4A0 MOVWF STEP
H4A1 MOVLW D'2'
H4A2 MOVWF PSTEP
H4A3 GOTO H4B0
;STEP 7bit PSTEP 2bit 22
;逆転 STEP 7 PSTEP3
H4A4 CLRF PCLATH
H4A5 MOVLW D'7'
H4A6 MOVWF STEP
H4A7 MOVLW D'3'
H4A8 MOVWF PSTEP
H4A9 GOTO H4B0
;STEP 7bit PSTEP 1bit 23
;逆転 STEP7 PSTEP2
H4AA CLRF PCLATH
H4AB MOVLW D'7'
H4AC MOVWF STEP
H4AD MOVLW D'2'
H4AE MOVWF PSTEP
H4AF GOTO H4B0
;PWMステップ励磁 I/O割り込み発生後、ステップ値の変更後に出力の更新
ORG_4B0 ORG 0x4B0
;プログラムカウンタを変更してジャンプ
H4B0 MOVLW B'00000100'
H4B1 MOVWF PCLATH
H4B2 MOVF STEP,0
H4B3 ADDWF PCL,1
H4B4 GOTO H4C0 ;0
H4B5 GOTO H4C6 ;1
H4B6 GOTO H4CC ;2
H4B7 GOTO H4D2 ;3
H4B8 GOTO H4D8 ;4
H4B9 GOTO H4DE ;5
H4BA GOTO H4E4 ;6
H4BB GOTO H4EA ;7
H4BC NOP ;何もしない
H4BD NOP ;何もしない
H4BE NOP ;何もしない
H4BF NOP ;何もしない
;STEP番号から出力先を選択する
ORG_4C0 ORG 0x4C0
;STEP0
H4C0 CLRF PCLATH
H4C1 MOVLW B'00000001' ; /B,B,/A,A
H4C2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4C3 MOVLW B'00000010' ; /B,B,/A,A
H4C4 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4C5 GOTO H4F0 ;PWMステップ値の選択
;STEP1
H4C6 CLRF PCLATH
H4C7 MOVLW B'00000010' ; /B,B,/A,A
H4C8 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4C9 MOVLW B'00000001' ; /B,B,/A,A
H4CA MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4CB GOTO H4F0 ;PWMステップ値の選択
;STEP2
H4CC CLRF PCLATH
H4CD MOVLW B'00000010' ; /B,B,/A,A
H4CE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4CF MOVLW B'00000100' ; /B,B,/A,A
H4D0 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4D1 GOTO H4F0 ;PWMステップ値の選択
;STEP3
H4D2 CLRF PCLATH
H4D3 MOVLW B'00000100' ; /B,B,/A,A
H4D4 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4D5 MOVLW B'00000010' ; /B,B,/A,A
H4D6 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4D7 GOTO H4F0 ;PWMステップ値の選択
;STEP4
H4D8 CLRF PCLATH
H4D9 MOVLW B'00000100' ; /B,B,/A,A
H4DA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4DB MOVLW B'00001000' ; /B,B,/A,A
H4DC MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4DD GOTO H4F0 ;PWMステップ値の選択
;STEP5
H4DE CLRF PCLATH
H4DF MOVLW B'00001000' ; /B,B,/A,A
H4E0 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4E1 MOVLW B'00000100' ; /B,B,/A,A
H4E2 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4E3 GOTO H4F0 ;PWMステップ値の選択
;STEP6
H4E4 CLRF PCLATH
H4E5 MOVLW B'00001000' ; /B,B,/A,A
H4E6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4E7 MOVLW B'00000001' ; /B,B,/A,A
H4E8 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4E9 GOTO H4F0 ;PWMステップ値の選択
;STEP7
H4EA CLRF PCLATH
H4EB MOVLW B'00000001' ; /B,B,/A,A
H4EC MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4ED MOVLW B'00001000' ; /B,B,/A,A
H4EE MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4EF GOTO H4F0 ;PWMステップ値の選択
ORG_4F0 ORG 0x4F0
;プログラムカウンタを変更してジャンプ
H4F0 MOVLW B'00000100'
H4F1 MOVWF PCLATH
H4F2 MOVF PSTEP,0
H4F3 ADDWF PCL,1
H4F4 GOTO H500 ;0
H4F5 GOTO H506 ;1
H4F6 GOTO H50C ;2
H4F7 GOTO H512 ;3
H4F8 NOP ;何もしない
H4F9 NOP ;何もしない
H4FA NOP ;何もしない
H4FB NOP ;何もしない
H4FC NOP ;何もしない
H4FD NOP ;何もしない
H4FE NOP ;何もしない
H4FF NOP ;何もしない
;PWMステップ値の選択
ORG_500 ORG 0x500
;PSTEP0
;65535-20000=45535
;1011 0001 1101 1111
;65535-200=65335
;1111 1111 0011 0111
H500 CLRF PCLATH
H501 MOVLW B'00110111' ;8ビットリテラルをWレジスタへ格納
H502 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H503 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H504 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H505 GOTO H520
;H56C GOTO H730
;PSTEP1
;65535-20000+6666=52201
;1100 1011 1110 1001
;65535-200+66=65401
;1111 1111 0111 1001
H506 CLRF PCLATH
H507 MOVLW B'01111001' ;8ビットリテラルをWレジスタへ格納
H508 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H509 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H50A MOVWF CCPR1H ;Wレジスタからデータを移動します。
H50B GOTO H520
;H565 GOTO H730
;PSTEP2
;65535-20000+6666+6666=58867
;1110 0101 1111 0011
;65535-200+66+66=65467
;1111 1111 1011 1011
H50C CLRF PCLATH
H50D MOVLW B'10111011' ;8ビットリテラルをWレジスタへ格納
H50E MOVWF CCPR1L ;Wレジスタからデータを移動します。
H50F MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H510 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H511 GOTO H520
;H55E GOTO H730
;PSTEP3
;65535-20000+6666+6666+6666=65533
;1111 1111 1111 1101
;65535-200+66+66+66=65533
;1111 1111 1111 1101
H512 CLRF PCLATH
H513 MOVLW B'11111101' ;8ビットリテラルをWレジスタへ格納
H514 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H515 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H516 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H517 GOTO H520
;H557 GOTO H730
H518 NOP
H519 NOP
H51A NOP
H51B NOP
H51C NOP
H51D NOP
H51E NOP
H51F NOP
ORG_520 ORG 0x520 ;入力が0だったら、フラグを消して戻る
H520 CLRWDT ;ウォッチドックタイマのリセット
H521 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H522 GOTO H520 ;STEP入力が1の時は、0に戻り待ちへ戻る
H523 BCF GPR20,Step_memory ;前の入力状態が1だったフラグオフ
H524 GOTO H310 ;割込み開始へ戻る
H525 NOP
H526 NOP
H527 NOP
H528 NOP
H529 NOP
H52A NOP
H52B NOP
H52C NOP
H52D NOP
H52E NOP
H52F NOP
;****************************************************************
;音 ド
;****************************************************************
ORG_H600 ORG 0x600 ;モーターから音を出す
H600 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H601 MOVLW H'00' ;H'00'をWへ格納
H602 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H603 MOVLW H'00' ;H'00'をWへ格納
H604 MOVWF MSL ;WをMSLへ格納 バンク0指定
H605 CALL H750 ;WAIT 0.1秒 音出力前の間
H606 CALL H750 ;WAIT 0.1秒 音出力前の間
H607 CALL H750 ;WAIT 0.1秒 音出力前の間
H608 CALL H750 ;WAIT 0.1秒 音出力前の間
H609 CALL H750 ;WAIT 0.1秒 音出力前の間
H60A GOTO H610 ;音のループへ
H60B NOP ;何もしない
H60C NOP ;何もしない
H60D NOP ;何もしない
H60E NOP ;何もしない
H60F NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H610 CLRWDT ;ウォッチドックタイマのリセット
H611 BSF PORTA,0 ;PORTA,0bit 出力ON
;H612 BCF PORTA,1 ;PORTA,1bit 出力OFF
H612 NOP
; 200 20 11 1
H613 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H614 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H615 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H616 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H617 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H618 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H619 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61A CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61B CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H61C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61D CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61E CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 441Hz
H61F NOP ;何もしない
;H620 NOP
;H621 NOP
;H622 NOP
;H623 NOP ;7ド 436.5Hz
;H624 NOP
;H625 NOP
;H626 NOP
;H627 NOP
;H628 NOP ;7ド 432Hz
;H61F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H620 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H621 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 低め
H620 BCF PORTA,0 ;PORTA,0bit 出力OFF
;H621 BSF PORTA,1 ;PORTA,1bit 出力ON
H621 NOP
H622 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H623 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H624 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H625 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H626 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H627 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H628 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H629 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62A CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H62B CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62D CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 441Hz
H62E NOP ;何もしない
;H633 NOP
;H634 NOP
;H635 NOP
;H636 NOP
;H63C NOP
;H63D NOP
;H63E NOP
;H63F NOP
;H640 NOP
;H61F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H620 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H621 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 低め
H62F MOVF MSL,0 ;音カウンタMSLをWへ格納
H630 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H631 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H632 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H633 GOTO H610 ;音ループへ戻る
H634 MOVF MSH,0 ;音カウンタMSHをWへ格納
H635 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H636 MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H637 BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H638 GOTO H610 ;音のループへ戻る
H639 BCF PORTA,0 ;PORTA,0bit 出力OFF
H63A BCF PORTA,1 ;PORTA,1bit 出力OFF
H63B RETURN
H63C NOP ;何もしない
H63D NOP ;何もしない
H63E NOP ;何もしない
H63F NOP ;何もしない
;****************************************************************
;音 レ
;****************************************************************
ORG_H650 ORG 0x650 ;モーターから音を出す
H650 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H651 MOVLW H'00' ;H'00'をWへ格納
H652 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H653 MOVLW H'00' ;H'00'をWへ格納
H654 MOVWF MSL ;WをMSLへ格納 バンク0指定
H655 CALL H750 ;WAIT 0.1秒 音出力前の間
H656 CALL H750 ;WAIT 0.1秒 音出力前の間
H657 CALL H750 ;WAIT 0.1秒 音出力前の間
H658 CALL H750 ;WAIT 0.1秒 音出力前の間
H659 CALL H750 ;WAIT 0.1秒 音出力前の間
H65A GOTO H660 ;音のループへ
H65B NOP ;何もしない
H65C NOP ;何もしない
H65D NOP ;何もしない
H65E NOP ;何もしない
H65F NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H660 CLRWDT ;ウォッチドックタイマのリセット
H661 BSF PORTA,0 ;PORTA,0bit 出力ON
;H662 BCF PORTA,1 ;PORTA,1bit 出力OFF
H662 NOP
H663 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H664 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H665 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H666 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H667 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H668 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H669 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H66A CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H66B CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ 437Hz
H66B NOP ;何もしない
H66C NOP ;何もしない
H66D NOP ;何もしない
H66E NOP ;何もしない
H66F NOP ;何もしない
H670 NOP ;何もしない
H671 NOP ;何もしない
H672 NOP ;何もしない
H673 NOP ;何もしない
H674 NOP ;何もしない
H675 NOP ;何もしない
H676 NOP ;何もしない
H677 NOP ;何もしない
H678 NOP ;何もしない
;H679 NOP
;H67A NOP
;H67B NOP ;437Hz
H679 BCF PORTA,0 ;PORTA,0bit 出力OFF
;H67A BSF PORTA,1 ;PORTA,1bit 出力ON
H67A NOP
H67B CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H67C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H67D CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H67E CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H67F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H680 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H681 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H682 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H676 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H683 NOP ;何もしない
H684 NOP ;何もしない
H685 NOP ;何もしない
H686 NOP ;何もしない
H687 NOP ;何もしない
H688 NOP ;何もしない
H689 NOP ;何もしない
H68A NOP ;何もしない
H68B NOP ;何もしない
H68C NOP ;何もしない
H68D NOP ;何もしない
H68E NOP ;何もしない
H68F NOP ;何もしない
H690 NOP ;何もしない
;H694 NOP
;H695 NOP
;H696 NOP
H691 MOVF MSL,0 ;音カウンタMSLをWへ格納
H692 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H693 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H694 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H695 GOTO H660 ;音ループへ戻る
H696 MOVF MSH,0 ;音カウンタMSHをWへ格納
H697 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H698 MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H699 BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H69A GOTO H660 ;音のループへ戻る
H69B BCF PORTA,0 ;PORTA,0bit 出力OFF
H69C BCF PORTA,1 ;PORTA,1bit 出力OFF
;H69D GOTO H660
H69D RETURN
H69E NOP ;何もしない
H69F NOP ;何もしない
;****************************************************************
;音 ミ
;****************************************************************
ORG_H6A0 ORG 0x6A0 ;モーターから音を出す
H6A0 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H6A1 MOVLW H'00' ;H'00'をWへ格納
H6A2 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H6A3 MOVLW H'00' ;H'00'をWへ格納
H6A4 MOVWF MSL ;WをMSLへ格納 バンク0指定
H6A5 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A6 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A7 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A8 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A9 CALL H750 ;WAIT 0.1秒 音出力前の間
H6AA GOTO H6B0 ;音のループへ
H6AB NOP ;何もしない
H6AC NOP ;何もしない
H6AD NOP ;何もしない
H6AE NOP ;何もしない
H6AF NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H6B0 CLRWDT ;ウォッチドックタイマのリセット
H6B1 BSF PORTA,0 ;PORTA,0bit 出力ON
;H6B2 BCF PORTA,1 ;PORTA,1bit 出力OFF
H6B2 NOP
H6B3 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H6B4 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B5 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H6B6 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B7 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B8 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B9 NOP
H6BA BCF PORTA,0 ;PORTA,0bit 出力OFF
;H6BB BSF PORTA,1 ;PORTA,1bit 出力ON
H6BB NOP
H6BC CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H6BD CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6BE CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H6BF CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C0 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C1 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C2 NOP
H6C3 MOVF MSL,0 ;音カウンタMSLをWへ格納
H6C4 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H6C5 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H6C6 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H6C7 GOTO H6B0 ;音ループへ戻る
H6C8 MOVF MSH,0 ;音カウンタMSHをWへ格納
H6C9 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H6CA MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H6CB BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H6CC GOTO H6B0 ;音のループへ戻る
H6CD BCF PORTA,0 ;PORTA,0bit 出力OFF
H6CE BCF PORTA,1 ;PORTA,1bit 出力OFF
H6CF RETURN
;***************************
; Wait Subroutines
;***************************
;メインクロック 8MHz
;1命令サイクル4クロック
;1MHz 1,000,000Hz 1 / 1,000,000Hz = 0.000001秒
;8MHz 8,000,000Hz 1 / 8,000,000Hz = 0.000000125秒
;8MHzの時、1命令4クロック長さ 0.000000125秒*4クロック = 0.0000005秒
;0.0000005s / 500ns / 0.5μs / 0.0005ms
;****************************************************************
;20回繰り返すと (18)
;0.00001s / 10μs / 0.01ms
;****************************************************************
ORG_700 ORG 0x700
H700 CLRWDT ;ウォッチドックタイマのリセット 1
H701 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H702 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H703 MOVLW B'00000010' ;2 1
H704 MOVWF WAIT70 ;WをWAITへ格納 バンク0指定 1
H705 NOP ;NOP 1
H706 DECFSZ WAIT70,1 ; 結果が0だと次の命令がNOPになる 1(2)
H707 GOTO H705 ; 2 (NOP) 1
H708 RETURN ; 2 1 = 10 2 = 14 3 = 18 (2*4=8+10=18)
H709 NOP
H70A NOP
H70B NOP
H70C NOP
H70D NOP
H70E NOP
H70F NOP
;****************************************************************
;200回繰り返すと (198)
;0.0001s / 100μs / 0.1ms
;****************************************************************
ORG_710 ORG 0x710
H710 CLRWDT ;ウォッチドックタイマのリセット 1
H711 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H712 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H713 MOVLW B'01000111' ;47 1
H714 MOVWF WAIT71 ;WをWAITへ格納 バンク0指定 1
H715 NOP ;NOP 1
H716 DECFSZ WAIT71,1 ; 結果が0だと次の命令がNOPになる 1(2)
H717 GOTO H715 ; 2 (NOP) 1
H718 RETURN ; 2 1 = 10 2 = 14 3 = 18 (47*4=188+10=198)
H719 NOP
H71A NOP
H71B NOP
H71C NOP
H71D NOP
H71E NOP
H71F NOP
;****************************************************************
;2000回繰り返すと (1998)
;0.001s / 1000μs / 1ms
;****************************************************************
ORG_720 ORG 0x720
H720 CLRWDT ;ウォッチドックタイマのリセット 1
H721 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H722 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H723 MOVLW B'11111000' ;248 1
H724 MOVWF WAIT72 ;WをWAITへ格納 バンク0指定 1
H725 NOP ;NOP 1
H726 NOP ;NOP 1
H727 NOP ;NOP 1
H728 NOP ;NOP 1
H729 NOP ;NOP 1
H72A DECFSZ WAIT72,1 ; 結果が0だと次の命令がNOPになる 1(2)
H72B GOTO H725 ; 2 (NOP) 1
H72C RETURN ; 2 1 = 14 2 = 22 3 = 30 (248*8=1984+14=1998)
H72D NOP
H72E NOP
H72F NOP
;****************************************************************
;20000回繰り返すと 200 * 100 = 20000 (19998)
;0.01s / 10ms
;****************************************************************
ORG_730 ORG 0x730
H730 CLRWDT ;ウォッチドックタイマのリセット 1
H731 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H732 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H733 MOVLW B'11000010' ;194 1
H734 MOVWF WAIT73 ;WをWAITへ格納 バンク0指定 1
H735 CALL H700 ;20
H736 CALL H700 ;20
H737 CALL H700 ;20
H738 CALL H700 ;20
H739 CALL H700 ;20
H73A DECFSZ WAIT73,1 ; 結果が0だと次の命令がNOPになる 1(2)
H73B GOTO H735 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (194*103=19982 + 6 = 19988)
H73C NOP
H73D NOP
H73E NOP
H73F NOP
H740 NOP
H741 NOP
H742 NOP
H743 NOP
H744 NOP
H745 NOP
H746 RETURN ; 2
H747 NOP
H748 NOP
H749 NOP
H74A NOP
H74B NOP
H74C NOP
H74D NOP
H74E NOP
H74F NOP
;****************************************************************
;200000 (199998)
;0.1秒
;****************************************************************
ORG_750 ORG 0x750
H750 CLRWDT ;ウォッチドックタイマのリセット 1
H751 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H752 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H753 MOVLW B'11000111' ;199 1
H754 MOVWF WAIT74 ;WをWAITへ格納 バンク0指定 1
H755 CALL H710 ;200
H756 CALL H710 ;200
H757 CALL H710 ;200
H758 CALL H710 ;200
H759 CALL H710 ;200
H75A DECFSZ WAIT74,1 ; 結果が0だと次の命令がNOPになる 1(2)
H75B GOTO H755 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (199*1003=199597 + 6 = 199603)
;199998 - 199603 = 395
H75C CLRWDT ;ウォッチドックタイマのリセット 1
H75D BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H75E BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H75F MOVLW B'01011111' ;95 1
H760 MOVWF WAIT75 ;WをWAITへ格納 バンク0指定 1
H761 NOP ;NOP 1
H762 DECFSZ WAIT75,1 ; 結果が0だと次の命令がNOPになる 1(2)
H763 GOTO H761 ; 2 (NOP) 1
H764 NOP
H765 NOP
H766 NOP
H767 NOP
H768 NOP
H769 RETURN ; 2 1 = 10 2 = 14 3 = 18 (95*4=380+10=390)
H76A NOP
H76B NOP
H76C NOP
H76D NOP
H76E NOP
H76F NOP
;****************************************************************
;2000000 (1999998)
;1秒
;****************************************************************
ORG_770 ORG 0x770
H770 CLRWDT ;ウォッチドックタイマのリセット 1
H771 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H772 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H773 MOVLW B'11000111' ;199 1
H774 MOVWF WAIT76 ;WをWAITへ格納 バンク0指定 1
H775 CALL H720 ;2000
H776 CALL H720 ;2000
H777 CALL H720 ;2000
H778 CALL H720 ;2000
H779 CALL H720 ;2000
H77A DECFSZ WAIT76,1 ; 結果が0だと次の命令がNOPになる 1(2)
H77B GOTO H775 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (199*10003=1990597 + 6 = 1990603)
;1999998 - 1990603 = 9395
H77C CALL H720 ;2000
H77D CALL H720 ;2000
H77E CALL H720 ;2000
H77F CALL H720 ;2000
;9395 - 8000 = 1395
H780 CALL H710 ;200
H781 CALL H710 ;200
H782 CALL H710 ;200
H783 CALL H710 ;200
H784 CALL H710 ;200
H785 CALL H710 ;200
;1395 - 1200 = 195
H786 CALL H700 ;20
H787 CALL H700 ;20
H788 CALL H700 ;20
H789 CALL H700 ;20
H78A CALL H700 ;20
H78B CALL H700 ;20
H78C CALL H700 ;20
H78D CALL H700 ;20
H78E CALL H700 ;20
;195 - 180 = 15
H78F NOP
H790 NOP
H791 NOP
H792 NOP
H793 NOP
H794 NOP
H795 NOP
H796 NOP
H797 NOP
H798 NOP
H799 NOP
H79A NOP
H79B NOP
H79C NOP
H79D NOP
H79E RETURN ; 2
H79F NOP
;****************************************************************
;プログラムメモリ ページ1 0800-0FFF 2kB
;****************************************************************
;****************************************************************
;プログラムメモリ ページ2 1000-17FF 2kB
;****************************************************************
;PIC16F88 プログラムメモリ未実装
;****************************************************************
;プログラムメモリ ページ3 1800-1FFF 2kB
;****************************************************************
;PIC16F88 プログラムメモリ未実装
END
いちおう動いてるようには見えます
MPLABX IDEでシミュレーターを動かすには
PICの周波数だけ設定が必要です、たぶん
RC Oscillator frequency 8MHz
Instruction frequency(Fcys) 2MHz
精度は、うーんびみょうです。
作った時に確認したはずですが、色々忘れてる気がします。
1mmごとに0.00付近まで動いてるのは確認してました。
ちょとずつ増えてる気がしましたが。
1mm以下の精度では見てるだけの確認。
0.01mmごとの指令に対して実際どれぐらい動いたか確認したらよかったかな。
なんか大変そうでまだできてない気がするし記録に残ってない。
でもPWMの値セットする時ちょっとだけ見てたかも。
1mm全部じゃなくて6ステップだけの確認はしてた。たぶん。
行ったり来たりさせて同じところに繰り返し位置が決まるからパルスはしっかり拾えてるっぽいかなぁ
10mm移動させると0.05mm多く移動するのはなぜなのか?
10mm戻すと元の位置には戻る
何度繰り返しても同じだけズレたところを行ったり来たり
ボールねじが原因かなぁ🤔
確認したのが搬送用たぶんC10のボールネジ
精度は±210μ/300mm
10mmだと7μ だから±0.007mmは誤差かもしれないと思ったんだけど
なんでだろう
たとえば真ん中ぐらいまで僕が思ったより大きく動いていて
そこから半分は小さく動いていて
300mm地点では±210μには入ってるってことなのかな?
そんなに長く測れないからわかんないです。
次はリニアスケールを買うべきか位置決め用のボールネジを買うべきか。
どっちも高額の予想。
精度としては0.1mmはほしかったかも
今からもう一回確認してみる
今測ると10mm移動した後0.01mmだけ多く移動してる。
何回繰り返しても同じ。
あれ?大丈夫っぽい。
試しにダイヤルゲージをナナメに当ててみた。
10mm移動した後0.1mmおおく動きました。
何回繰り返しても同じ。
失礼しましたこれが原因かも。
測定器のセットはいつもしてもらっていて
なにせほとんど初めてダイヤルゲージセットしたもので。
こんなに測定値に影響するなんてびっくりです。
最高移動速度は計算してないし未確認です。
2024/09/23
精度の再確認をした
10mmのインチングは精度が出てる 誤差0.01mm以下
1mmのインチングは精度が出てる 誤差0.01mm以下
0.1mmのインチングは精度が出てる 誤差0.01mm以下
0.01mmのインチングは
なんか増えたり減ったりしてる
0.02ごとには、だいたいぴったりこないけどメモリ通りに動いてる気がした
2024/09/24
pwmをオシロで測ってみたくなった
測ってみた
9.4kHzのpwmになっていた
よしよし
たぶん10kHzの設定だったと思う
PWMの割合を測ってみた
0.01mm 5%
0.02mm 33.64%
0.03mm 69.00%
0.04mm 100%
0.05mm 100%
0.06mm 100%
0.07mm 100%
0.08mm 100%
0.09mm 100%
0.10mm 100%あれ?ここが69%じゃない??
0.11mm 69.00%
0.12mm 33.6%
0.13mm 5%
5%PWMは何故か安定してない
まぁいいや
ノイズが混じって測れてないだけかも
イメージでは0.10mmのところでPWM2になって
69%なにるはずなのに、あれ?一個ずれてるのを見つけた
0.10mmのところで PWM3 ほぼ100%
0.11mmのところで PWM2になってる
あってる
プログラム作る時に考えたタイミングチャート通り動いてる
今思ってる動きと違う
ようはPSTEPが
012321012321とカウントするじゃなくて
012210012210のほうがいいと思った
0.01の精度が出ないのはこのせいかもしれない
プログラムの修正をした
シミュレータでのみ動作の確認済み
実機でも確認した
あとはPWMの設定値を探って再設定と精度の確認をする
なかなか精度が出ないです。
パターン 0123210123210にもどした。
0.02の精度がだいたいでた
pwmと常時オンの位相を一個ずらしてるのは
プログラムのミスかと思いきや
わざとずらしてた気がした
2024/09/29
新しいオシロスコープ買ったのでしっかりプログラムが動いてるか確認してみました。
モーターをつないだまま測るとモーターから何かが回り込んでくるのか
思ってるパターンで動いてるように見えません。
モーターの代わりにLEDをつなぐと思ってるパターンで動いてます。
モーターを外して測ると思ってる通りプログラムが動いてるのを確認できました。
;****************************************************************
;題名 CNC用ステッピングモーター制御プログラム
;オリジナルマインド製サーボリンカーからステッピングモーターへの信号変換基盤用
;作成日 2019年9月28日-2019年12月8日
;修正 2024年9月24日
;作成者 福井彰太郎
;****************************************************************
;エンコード Shift_JIS
;フォント Courier_New 18.0pt.(Windows)
;フォント Monospaced 12(MPLAB X IDE)
;****************************************************************
;コンパイラ MPASMで作成開始。
;コンパイラ MPLAB X IDE v2.00へ変更。
;
;アセンブラ MPASM v5.54
;****************************************************************
;マイコン 16F88 3個
;
;入力 フォトカプラ TLP521-2 4個
;
;出力1段目 トランジスタ C1815 12個
;出力2段目 トランジスタ C3890 12個
;逆流保護ダイオード DD10 12個
;
;モーター IAI ロボシリンダー 3個
;ユニポーラ KH42KM2B042 200ステップ 1.8度
;ボールねじ 1回転12mm
;****************************************************************
;励磁方式(1相励磁、2相励磁)
;1相励磁(フルステップ駆動 200ステップ)
;主にユニポーラモーターで使用する。 6線モーター
;励磁の順序 A,/A,B,/B
;
;配線色 黒 青 黄 茶 赤 橙
;
;2相励磁(フルステップ駆動 200ステップ)
;主にバイポーラモーターで使用する。 4線モーター
;
;1回転あたり200パルスのモーターと1回転12ミリのボールネジを使う。
;1相と2相励磁の場合
;1パルスあたりの移動量 ボールネジ12mm / 200step = 0.06mm
;
;動作確認済み
;****************************************************************
;励磁方式(1-2相励磁)
;1-2相励磁(ハーフステップ駆動 400ステップ)
;
;1-2相励磁の場合
;1パルスあたりの移動量 ボールネジ12mm / 400step = 0.03mm
;
;動作確認済み
;****************************************************************
;PWMステップ駆動
;1-2相ベースでPWMステップの作成
;200分割 1相励磁の1ステップを6ステップで進む
;一回転あたり、200ステップ × 6分割 = 1200ステップ
;
;1パルスあたりの移動量 ボールねじ12mm / 1200step = 0.01mm
;
;動作確認済み
;****************************************************************
;プログラム作成の履歴
;2019/10/05
;MPLABでメインプログラム変数の初期化まで動いた
;
;割り込みは使わずにプログラムから入力を確認しに行くタイプとすることにした。
;動いた。
;
;入力信号のON時間が1μsと短く、時間が短いから割り込みを使うことになった。
;
;2019/10/16
;1-2相の正転まで出力できた。
;
;早く回した時に最高速が遅い感じがするのと、全体的に異音が大きい感じがする。
;磁石がくっついたときの衝撃が大きいからかもしれない
;衝撃を小さくするために出力の時間を半分ほどにしたら、高速で回せる気がした。
;
;そのうち試してみることにする。 トルクが落ちてゆっくりになるだけかもしれない
;
;2019/10/31
;ステッピングモーター用のPWM信号を作りたくなった。
;1-2相励磁だと、PWMするのは同時に1本だけで作れそうだと思った。
;1個目がオン、2個目が上がってくる。2個目がオン、1個目が下がってくる。
;2個目がオン、3個目が上がってくる。3個目がオン、2個目が下がってくる。
;3個目がオン、4個目が上がってくる。4個目がオン、3個目が下がってくる。
;これを出力できるようにしたい。
;
;Stimulus スティミュラス(刺激) 音節 (stim・u・lus)
;Clock Stimulus 1サイクルクロック(8MHz/4=500ns)
;a stimulus to growth [development] 成長への刺激
;
;2019/11/13
;PWMの直線増加減で正転逆転が出力できていそうな感じになった
;曲線の増加減とかオフセットとか 相ごとのオフセットができると便利そう
;
;そのうち試してみることになるかもしれない
;
;全部PWMステップだと高速で動かせないかもしれない
;入力パルスの間隔をはかって 励磁モードを自動で変えれると便利そう
;低速はPWMステップ 高速は1相ステップ
;それだと 1パルスあたり 自動でPWMステップが必要になる
;精度が低くなることになる
;
;パソコンから出せるパルス速度に限界がある
;10パルスは 10ミリ なのか 100 ミリなのか を
;パソコンから指示できる仕組みがひつようになる
;外部出力で選択できるようにできるかもしれない
;
;そのうち試してみることになるかもしれない
;
;2019/11/24
;1相励磁の出力を上げたり下げたりして、次のステップを上げたり下げたりを試してみた。
;100μ秒のタイマーで出力をフリッカさせると、トルクが少なくて動かなくなった。
;モーターへの電流がオフベースで動かしてることになった。
;常時100パーセント電流を流しているところが1本ないと手で押すと動いてしまう。
;モーターに電流が流れていないとき、くっついた山の上からどっちかに転がり落ちそうで
;そのとき次のステップ0パーセントだと が 不安定な動きの原因かもしれない
;
;1-2相ベースの1本PWM仕様が使えなくなってる
;復活させようか そのまま 2本PWM仕様へ変更しようか
;切り替えできるようにするか迷った
;
;2019/11/25
;PWMステップのとき その相の反対側へ誘導されて戻ってきてる気がする
;一回壊れて動かなくなったと思ったことがあった気がした ぜんぶ光ってるし になって
;だめだこりゃ だったかもしれない
;うごいてるか確認もできないになった
;
;2相励磁に戻して一回落ち着くことにした
;動く状態はキープしておくことが重要かもしれない
;
;プログラムを先頭から見直しをすることにした
;部品の仕様がわからなくなってる
;壊れたら再検討でいいかもしれない
;ちょこっと気になることをそのままにしないほうがいいかもしれない
;
;2019年12月2日
;PWMステップがそれっぽく動いた シュミレーションのみ
;1ステップ6分割で、1回転1200ステップになった
;1パルスあたりの移動量12/1200=0.01ミリで動かせそうな感じがしてきた
;
;2019年12月6日
;正転 右移動しかしない 逆転 左移動はリセットがかかるエラーの修正
;PWMステップがシュミレーションでは動いてる感じになった
;
;タイマー0で入力パルス間隔を測って エラーがでるようにしたらいいかもしれない
;最小時間をセットしておいて カウントアップがあれば 入力する
;カウントアップがないときはエラーにする
;モーターの方が先に脱調しそうだから いらないかもしれない
;
;2019年12月8日
;PWMステップが、正転と逆転の両方向動くようになった
;逆転の0だったら1のところを、ムーブだけでZを見ることにしたらうまくいった
;
;2019年12月20日
;一方向にまわしっぱなしで、1メモリ2μ半回転100メモリのμメーターで見ると
;動く量が変化するところがあることがわかった
;常時オンの相に近づいていくときと離れていくときではPWM値が変わるのかもしれない
;どちらかの片側は精度が出てる気がする、どうしよう
;精度は1?2相と、ちょっと上がった部分があって、全体的に音が小さくなった程度になった。
;バックラッシュは手で押すと40μほどあることがわかった
;モーターから動かすと20μほどだった
;前はここでPWM値の真ん中を探そうとして失敗した気がした
;エンコーダーがいるのかもしれない
;負荷をかけて測定しないといけないのかもしれない
;仕上げは無負荷でいいかもしれない
;
;10μステップ(0.01mmステップ)で繰り返し同じところに来る
;たまに1ステップだと動かなくて、2ステップで20μ(0.02mm)動く部分がある
;ボールねじの仕様かもしれない気がした
;わざと制度を落としてあるのかもしれない
;
;いろいろプログラムをいじって、結局元に戻したら調子がよかったような気がした
;
;これ以上精度を上げるときはエンコーダーが必須になるのかもしれない
;エンコーダーも波をうっていたら確認のしようがないになりそうな気がした
;2024/9/24
;プログラムの不要なところの整理
;PSTEPを012321012321じゃなくて
; 012210012210に変更
;実際に動かしながらPWM設定値の修正
;正転と逆転が切り替わるところで
;ステップが飛んでた可能性がある
;正転だけのテーブルにした
;ステップの指定とテーブルの中身が一個ずれてた
;ステップ初期値の変更
;シミュレータで動作確認
;****************************************************************
LIST P=16F88
#INCLUDE P16F88.INC
;****************************************************************
;コンフィグレーションビットの設定。
; Set User ID Memory
__idlocs 0x6585
;CONFIG1
;CP/CCPMX/DEBUG/WRT1/WRT0/CPD/LVP/BOREN/MCLRE/FOSC2/PWRTEN/WDTEN/FOSC1/FOSC0
;CP1 プログラム読み出し許可 ○
;CP0 プログラム読み出し禁止
;CCPMX1 RB0コンパレータ入力
;CCPMX0 RB3コンパレータ入力 ○
;DEBUG1 インサーキットデバッガー禁止 RB6,7は入出力ポート ○
;DEBUG0 インサーキットデバッガー許可 RB6,7はICSPCLK,ICSPDAT
;WRT11 フラッシュプログラムメモリ書き込み防止なし ○
;WRT10 書込み防止00-00FF それ以降0FFFまでEECONで設定
;WRT01 書込み防止00-00FF それ以降0FFFまでEECONで設定
;WRT00 書込み防止00-00FF
;CPD1 EEPROM読み出し許可 ○
;CPD0 EEPROM読み出し禁止
;LVP1 低電圧書き込み許可 RB3をハイレベルにして書き込む
;LVP0 /MCLR端子に高電圧(VPP)を与えて書き込む RB3は通常の入出力 ○
;BOREN1 電圧低下 (>4V)リセット許可 ○
;BOREN0 電圧低下リセット禁止
;MCLRE1 RA5はMCLR機能で、負パルスでリセット ○
;MCLRE0 RA5は通常の入出力ポート
;FOSC111 RA7が外部発振RC端子 RA6がクロック出力
;FOSC110 RA7が外部発振RC端子 RA6は通常の入出力ポート
;FOSC101 内部クロック発振 RA6がクロック出力 RA7は通常の入出力ポート
;FOSC100 内部クロック発振 RA6,7は通常の入出力ポート ○
;FOSC011 外部クロック RA7が外部クロック入力 RA6は通常の入出力ポート
;FOSC010 RA7とRA6に高ゲイン(HS)発振子 4MHz-20MHz
;FOSC001 RA7とRA6に中ゲイン(XT)発振子 4MHz以下
;FOSC000 RA7とRA6に32kHz(LP)発振子
;PWRTEN1 電源立ち上げ時遅延スタートなし
;PWRTEN0 電源立ち上げ時遅延スタートあり ○
;WDTEN1 暴走自動停止あり ○
;WDTEN0 暴走自動停止なし
;(111)10 1111 0111 0100
;0x2F74
; __CONFIG _CONFIG1, 0x2F74
;逆転をするとリセットがかかる
;このままで動いた
;ウォッチドッグなしにしてみた 変化なし
;(111)10111 1011 100 00
;0xEF70
__CONFIG _CONFIG1, 0xEF70
;CONFIG2
;13-2bit機能なし 1として読み出し /IESO/FCMEN
;IESO1 電源立ち上げ時 非常用内臓クロック(FRC)使用許可
;IESO0 電源立ち上げ時 非常用内蔵クロック(FRC)使用禁止 ○
;FCMEN1 非常用内臓クロック(FRC)使用許可
;FCMEN0 非常用内臓クロック(FRC)使用禁止 ○
;(111)11 1111 1111 1100
;0x3FFC
__CONFIG _CONFIG2, 0x3FFC
;****************************************************************
;アセンブラプログラムの基本フォーマット
;Label/Mnemonic/Operand/Comment
;
;数値の表現方法
;
;2進数 B’001111001’
;8進数 O’777’
;10進数 D’100'
;16進数 H’9f' / 0AFH
;ASCII ‘C’ / A’C’
;
;GOTO、CALLは7FFまでPCLATHをつかわずに指定できる
;バイト処理命令127まで128個を指定できる
;
;****************************************************************
;MPLAB用エラー対策
;Register in operand not in bank 0. Ensure that bank bits are correct.
;バンク0以外へアクセスしようとしたときに、エラー表示を出なくする。
;
ERRORLEVEL -302
;
;****************************************************************
;バンク0の汎用レジスタ名の設定 20H-7F0 96byte 0-7bit 0-255
;****************************************************************
;汎用レジスタ General Purpose Register
;
GPR20 EQU H'20' ;汎用レジスタ20 8点 バンク0指定
Startup_complete EQU 0;0bit : 起動完了
Special_func_reg_ini_comp EQU 1;1bit : 特殊機能レジスタ初期化完了
Variable_ini_comp EQU 2;2bit : メインプログラム変数初期化完了
;3bit : 未使用
;4bit : 未使用
;5bit : 未使用
Step_memory EQU 6;6bit : STEP I/O割り込みの入力状態記憶
Dir_memory EQU 7;7bit : DIR I/O割り込みの入力状態記憶
;
GPR21 EQU H'21' ;汎用レジスタ21 8点 バンク0指定
;0bit : 未使用
PWM_ACTION EQU 1;1bit : STEP変更可:0 PWM動作中:1
;PWM_VECTOR EQU 2;2bit : PWMベクトル ステップの増加に対してPWM値の 1:増加 0:減少
;3bit : 未使用
;4bit : 未使用
;5bit : 未使用
;6bit : 未使用
;7bit : 未使用
;
GPR22 EQU H'22' ;汎用レジスタ22 8点 バンク0指定(未使用)
GPR23 EQU H'23' ;汎用レジスタ23 8点 バンク0指定(未使用)
GPR24 EQU H'24' ;汎用レジスタ24 8点 バンク0指定(未使用)
GPR25 EQU H'25' ;汎用レジスタ25 8点 バンク0指定(未使用)
GPR26 EQU H'26' ;汎用レジスタ26 8点 バンク0指定(未使用)
GPR27 EQU H'27' ;汎用レジスタ27 8点 バンク0指定(未使用)
GPR28 EQU H'28' ;汎用レジスタ28 8点 バンク0指定(未使用)
GPR29 EQU H'29' ;汎用レジスタ29 8点 バンク0指定(未使用)
GPR2A EQU H'2A' ;汎用レジスタ2A 8点 バンク0指定(未使用)
GPR2B EQU H'2B' ;汎用レジスタ2B 8点 バンク0指定(未使用)
GPR2C EQU H'2C' ;汎用レジスタ2C 8点 バンク0指定(未使用)
GPR2D EQU H'2D' ;汎用レジスタ2D 8点 バンク0指定(未使用)
GPR2E EQU H'2E' ;汎用レジスタ2E 8点 バンク0指定(未使用)
GPR2F EQU H'2F' ;汎用レジスタ2F 8点 バンク0指定(未使用)
GPR30 EQU H'30' ;汎用レジスタ30 8点 バンク0指定(未使用)
GPR31 EQU H'31' ;汎用レジスタ31 8点 バンク0指定(未使用)
GPR32 EQU H'32' ;汎用レジスタ32 8点 バンク0指定(未使用)
GPR33 EQU H'33' ;汎用レジスタ33 8点 バンク0指定(未使用)
GPR34 EQU H'34' ;汎用レジスタ34 8点 バンク0指定(未使用)
GPR35 EQU H'35' ;汎用レジスタ35 8点 バンク0指定(未使用)
GPR36 EQU H'36' ;汎用レジスタ36 8点 バンク0指定(未使用)
GPR37 EQU H'37' ;汎用レジスタ37 8点 バンク0指定(未使用)
GPR38 EQU H'38' ;汎用レジスタ38 8点 バンク0指定(未使用)
GPR39 EQU H'39' ;汎用レジスタ39 8点 バンク0指定(未使用)
GPR3A EQU H'3A' ;汎用レジスタ3A 8点 バンク0指定(未使用)
GPR3B EQU H'3B' ;汎用レジスタ3B 8点 バンク0指定(未使用)
GPR3C EQU H'3C' ;汎用レジスタ3C 8点 バンク0指定(未使用)
GPR3D EQU H'3D' ;汎用レジスタ3D 8点 バンク0指定(未使用)
GPR3E EQU H'3E' ;汎用レジスタ3E 8点 バンク0指定(未使用)
GPR3F EQU H'3F' ;汎用レジスタ3F 8点 バンク0指定(未使用)
;モーターの励磁モード設定
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1?2相励磁
;0000 0100:PWMステップ
MODE EQU H'40'
EXCITATION_MODE_ADDRESS_L EQU H'41';モーターの励磁モード設定より、ジャンプ先のアドレス
EXCITATION_MODE_ADDRESS_H EQU H'42';モーターの励磁モード設定より、ジャンプ先のアドレス
STEP EQU H'43' ;励磁ステップ
DIV EQU H'44';モーターの分割数設定 Division_number
;MCU EQU H'45' ;タイマー1の最小カウント単位 Minimum count unit
PSTEP EQU H'46' ;PWMステップ
PAPWM EQU H'47' ;PWM出力をするポートのビット選択
PA EQU H'48' ; ポートA用の出力データ
COMBINED_STEPS EQU H'49' ;STEPとPSTEPをあわせたステップ
;CASE32 EQU H'4A' ;CASE32 8点 バンク0指定
GPR4A EQU H'4A' ;汎用レジスタ4A 8点 バンク0指定(未使用)
GPR4B EQU H'4B' ;汎用レジスタ4B 8点 バンク0指定(未使用)
GPR4C EQU H'4C' ;汎用レジスタ4C 8点 バンク0指定(未使用)
GPR4D EQU H'4D' ;汎用レジスタ4D 8点 バンク0指定(未使用)
GPR4E EQU H'4E' ;汎用レジスタ4E 8点 バンク0指定(未使用)
GPR4F EQU H'4F' ;汎用レジスタ4F 8点 バンク0指定(未使用)
Startup_complete_L EQU H'50' ;起動完了カウンタL バンク0指定
Startup_complete_H EQU H'51' ;起動完了カウンタH バンク0指定
MSL EQU H'52' ;モーターから音を出すときの音の長さL
MSH EQU H'53' ;モーターから音を出すときの音の長さH
MHL EQU H'54' ;D54 バンク0指定(未使用)
MHH EQU H'55' ;D55 バンク0指定(未使用)
MC EQU H'56' ;D56 バンク0指定(未使用)
D57 EQU H'57' ;D57 バンク0指定(未使用)
D58 EQU H'58' ;D58 バンク0指定(未使用)
D59 EQU H'59' ;D59 バンク0指定(未使用)
T1INIL EQU H'5A' ;タイマー1初期値L バンク0指定
T1INIH EQU H'5B' ;タイマー1初期値H バンク0指定
T1PREL EQU H'5C' ;タイマー1現在値L バンク0指定 Present value
T1PREH EQU H'5D' ;タイマー1現在値H バンク0指定 Present value
COMPARE_1_INI_L EQU H'5E' ;コンペア1初期値L バンク0指定
COMPARE_1_INI_H EQU H'5F' ;コンペア1初期値H バンク0指定
D60 EQU H'60' ;D60 バンク0指定(未使用)
D61 EQU H'61' ;D61 バンク0指定(未使用)
D62 EQU H'62' ;D62 バンク0指定(未使用)
D63 EQU H'63' ;D63 バンク0指定(未使用)
D64 EQU H'64' ;D64 バンク0指定(未使用)
D65 EQU H'65' ;D65 バンク0指定(未使用)
D66 EQU H'66' ;D66 バンク0指定(未使用)
D67 EQU H'67' ;D67 バンク0指定(未使用)
D68 EQU H'68' ;D68 バンク0指定(未使用)
D69 EQU H'69' ;D69 バンク0指定(未使用)
D6A EQU H'6A' ;D6A バンク0指定(未使用)
D6B EQU H'6B' ;D6B バンク0指定(未使用)
D6C EQU H'6C' ;D6C バンク0指定(未使用)
D6D EQU H'6D' ;D6D バンク0指定(未使用)
D6E EQU H'6E' ;D6E バンク0指定(未使用)
D6F EQU H'6F' ;D6F バンク0指定(未使用)
WAIT70 EQU H'70' ;Wait70 待ち時間用変数0
WAIT71 EQU H'71' ;Wait71 待ち時間用変数1
WAIT72 EQU H'72' ;Wait72 待ち時間用変数2
WAIT73 EQU H'73' ;Wait73 待ち時間用変数3
WAIT74 EQU H'74' ;Wait74 待ち時間用変数4
WAIT75 EQU H'75' ;Wait75 待ち時間用変数5
WAIT76 EQU H'76' ;Wait76 待ち時間用変数6
WAIT77 EQU H'77' ;Wait77 待ち時間用変数7
WAIT78 EQU H'78' ;Wait78 待ち時間用変数8
WAIT79 EQU H'79' ;Wait79 待ち時間用変数9
WAIT7A EQU H'7A' ;Wait7A 待ち時間用変数A(未使用)
WAIT7B EQU H'7B' ;Wait7B 待ち時間用変数B(未使用)
WAIT7C EQU H'7C' ;Wait7C 待ち時間用変数C(未使用)
WAIT7D EQU H'7D' ;Wait7D 待ち時間用変数D(未使用)
WAIT7E EQU H'7E' ;Wait7E 待ち時間用変数E(未使用)
WAIT7F EQU H'7F' ;Wait7F 待ち時間用変数F(未使用)
;****************************************************************
;バンク1の汎用レジスタ名の設定 A0H-EFH 80byte 0-7bit 0-255
;****************************************************************
;F0H-FFH Access
;****************************************************************
;バンク2の汎用レジスタ名の設定 110H-11F 16byte 0-7bit 0-255
;****************************************************************
;****************************************************************
;バンク2の汎用レジスタ名の設定 120H-16F 80byte 0-7bit 0-255
;****************************************************************
;170H-17FH Access
;****************************************************************
;バンク3の汎用レジスタ名の設定 190H-19F 16byte 0-7bit 0-255
;****************************************************************
;****************************************************************
;バンク3の汎用レジスタ名の設定 1A0H-1EF 80byte 0-7bit 0-255
;****************************************************************
;1F0H-1FFH Access
;****************************************************************
;メインプログラム
;****************************************************************
;
;プログラムカウンタ
;8K×14のプログラムメモリ空間をアドレス指定することが可能な、
;13ビットプログラムカウンタを有しています。
;13ビットは0-1FFF(16進)までカウントできる 0-8191(10進)
;
;プログラムメモリ(PCLATHとあわせてページ切り替え)
;ページ0 0000-07FF 0-2047行分
;ページ1 0800-0FFF 0-2047行分
;ページ2 1000-17FF 0-2047行分
;ページ3 1800-1FFF 0-2047行分
;
;ビットのセット、リセットの方法
;BSF ビットのセット
;BCF ビットのリセット
;
;分岐の方法
;BTFSC ;レジスタの指定したビットが0なら次の命令をスキップ
;BTFSS ;レジスタの指定したビットが1なら次の命令をスキップ
;DECFSZ ;レジスタ値を1減算し,値が0なら次の命令をスキップ
;INCFSZ ;レジスタ値を1加算し,値が0なら次の命令をスキップ
;
;GOTOを使うときに注意すること。
;GOTOを使うときは、ジャンプ先のプログラムカウンタのアドレスが全部入らないから、
;GOTOの一個上の行にPCLATHを使って3,4ビット目を事前にセットする。
;
;他の命令でもPCLATHが必要なところがあるらしい。
;ADDWF PCLなどを使うときの、出力先かもしれない。
;それの8ビットとPCLATHから5ビットの13ビットで使えるらしい。
;GOTO,CALLを使うときは、それの11ビットとPCLATHから2ビットの13ビットで使える。
;RETURN,RETFIE,RETLWはスタックメモリより13ビットが直接戻される。
;
;
;STATUSレジスタの内容
;7bit IRP 間接アドレッシング時のバンク選択
; 1バンク2、3
; 0バンク0、1
;
;6,5bit RP0,1 データレジスタ用メモリのバンク選択
;RP1,RP0 0,0 バンク0(0x0000-0x007F 128bytes)
;RP1,RP0 0,1 バンク1(0x0080-0x00FF 128bytes)
;RP1,RP0 1,0 バンク2(0x0100-0x017F 128bytes)
;RP1,RP0 1,1 バンク3(0x0180-0x01FF 128bytes)
;
;4bit TO タイムアウトビット
; 1= Afterpower-up,CLRWDTinstructionorSLEEPinstruction
; 起動時か、CLRWDT/SLEEP命令実行時
; 0= AWDTtime-outoccurred
; ウォッチドックタイマによるタイムアウトが発生 読み込み専用
;
;3bit PD パワーダウンビット
; 1= Afterpower-uporbytheCLRWDTinstruction
; 起動後か、CLRWDT命令実行時
; 0= ByexecutionoftheSLEEPinstruction
; SLEEP命令実行時
;
;2bit Z ゼロビット
; 1算術演算または論理演算の結果がゼロであります
; 0結果がゼロではありません
;
;1bit DC
; 1第4ビットキャリー発生
; 0第4ビットキャリー発生してません
;
;0bit C
;; 1最上位キャリー発生
; 0最上位キャリー発生してません
;
;****************************************************************
;プログラムメモリ ページ0 0000-07FF 2kB
;****************************************************************
ORG_000 ORG 0x000 ;リセットベクタ
H000 CLRWDT ;ウォッチドッグタイマのリセット
H001 CLRF STATUS ;ステータスレジスタのクリア バンク0を選択
H002 CLRF PCLATH ;プログラムメモリ0を指定
H003 GOTO H0A0 ;起動開始ベクタ
ORG_004 ORG 0x004 ;割り込みベクタ
H004 CLRWDT ;ウォッチドッグタイマのリセット
;STEP SET
H005 BSF GPR20,Step_memory ;STEP I/O割り込み
;DIR SET/RESET
H006 BCF GPR20,Dir_memory ;DIR リセット
H007 BTFSC PORTB,6 ;レジスタの指定したビットが0なら次の命令をスキップ
H008 BSF GPR20,Dir_memory ;DIR セット
H009 BCF INTCON,4
;割り込みで データを変更
;割り込みから スタックで戻って
;タイマーとコンペアの グルグル
;右方向には動く、左方向にはリセットがかかる
;DIR_memoryのセット、リセットを逆にすることにした
;左方向のスイッチで右方向にだけ動いた
;右方向のスイッチを押すとリセットがかかる
;エラーにはジャンプしてなさそう
;リセット入力になっていてピック自体が入力からリセットがかかってる感じではなさそうだった
;正転はうごいてる 逆転が動いてない
H00A RETFIE ;割り込みから戻る
H00B NOP
H00C NOP
H00D NOP
H00E NOP
H00F NOP
ORG_0A0 ORG 0x0A0 ;起動開始ベクタ
H0A0 BCF STATUS,RP0 ;0 バンク0を選択する
H0A1 BCF STATUS,RP1 ;0 バンク0を選択する
H0A2 BCF GPR20,Startup_complete ;起動完了フラグクリア バンク0指定
;起動カウンタのカウンタリセット
H0A3 MOVLW H'00' ;H'00'をWへ格納
H0A4 MOVWF Startup_complete_H ;Wを Startup_complete_H へ格納 起動カウンタH バンク0指定
H0A5 MOVLW H'00' ;H'00'をWへ格納
H0A6 MOVWF Startup_complete_L ;Wを Startup_complete_L へ格納 起動カウンタL バンク0指定
H0A7 GOTO H0B0 ;起動カウンタのインクリメントへ
H0A8 NOP
;H0A8 GOTO H0BC ;起動カウンタキャンセル
H0A9 NOP ;何もしない
H0AA NOP ;何もしない
H0AB NOP ;何もしない
H0AC NOP ;何もしない
H0AD NOP ;何もしない
H0AE NOP ;何もしない
H0AF NOP ;何もしない
ORG_0B0 ORG 0x0B0 ;起動カウンタのインクリメント
;(1024までカウントして割り込みベクタへ戻る)
H0B0 CLRWDT ;ウォッチドッグタイマのリセット
H0B1 MOVF Startup_complete_L,0 ;起動カウンタD30LをWへ格納
H0B2 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H0B3 MOVWF Startup_complete_L ;WレジスタからStartup_complete_Lレジスタへデータを移動します
H0B4 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H0B5 GOTO H0BA ;起動カウンタが1024かどうか確認するへ
H0B6 MOVF Startup_complete_H,0 ;起動完了カウンタStartup_complete_HをWへ格納
H0B7 ADDLW H'1' ;Wへ1加算 オーバーフローの確認はしない
H0B8 MOVWF Startup_complete_H ;WレジスタからStartup_complete_Hレジスタへデータを移動します。
H0B9 GOTO H0B0 ;起動カウンタのインクリメントへ戻る
;起動カウンタが1024かどうか確認する "0000 0100 0000 0000"(2進数)
H0BA BTFSS Startup_complete_H,2 ;Startup_complete_Hの2ビットが1なら次の命令をスキップする バンク0指定
H0BB GOTO H0B0 ;Startup_complete_Hの2ビットが0の時。 インクリメントへ戻る
H0BC BSF GPR20,Startup_complete ;起動完了フラグセット バンク0指定
H0BD GOTO H0C0 ;
H0BE NOP ;何もしない
H0BF NOP ;何もしない
ORG_0C0 ORG 0x0C0 ;特殊機能レジスタの初期化開始ベクタ
H0C0 BCF STATUS,RP0 ;0 バンク0を選択する
H0C1 BCF STATUS,RP1 ;0 バンク0を選択する
H0C2 BTFSS GPR20,Startup_complete ;起動完了フラグが1だったら次の命令をスキップする
H0C3 GOTO H000 ;
H0C4 BCF GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了クリア バンク0指定
H0C5 GOTO H100 ;特殊機能レジスタの初期設定へ
H0C6 NOP ;何もしない
H0C7 NOP ;何もしない
H0C8 NOP ;何もしない
H0C9 NOP ;何もしない
H0CA NOP ;何もしない
H0CB NOP ;何もしない
H0CC NOP ;何もしない
H0CD NOP ;何もしない
H0CE NOP ;何もしない
H0CF NOP ;何もしない
;****************************************************************
ORG_100 ORG 0x100 ;特殊機能レジスタの初期設定
;****************************************************************
;OPTION_REG:OPTION制御レジスタ(アドレス81H,181H DS30487C-18ページ)
;----- OPTION_REG Bits -----------------------------------------------------
;7bit1 NOT_RBPU ポートBプルアップ 1無効 0有効
;6bit1 INTEDG
;RB0/INTピン 1立ち上がりエッジで割り込み 0立下りエッジで割り込み
;
;5bit0 T0CS TMR0カウント
;1RA4/T0CKI/C2OUTピンの変遷 0内部サイクルクロック(CLKO)
;
;4bit0 T0SE RA4/T0CKI/C2OUTピンのカウントアップのタイミング
;1ハイからロー 0ローからハイ
;
;3bit0 PSA プリスケーラの割り当て 1WDT 0タイマ0
;
;PS<2:0>プリスケーラ選択ビット
; TMR0 WDT
;000 1:2 1:1 とりあえずこれに設定
;001 1:4 1:2
;010 1:8 1:4
;011 1:16 1:8
;100 1:32 1:16
;101 1:64 1:32
;110 1:128 1:64
;111 1:256 1:128
;2bit0 PS2
;1bit0 PS1
;0bit0 PS0
H100 BSF STATUS,RP0 ;1 バンク1を選択する
H101 BCF STATUS,RP1 ;0 バンク1を選択する
H102 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H103 MOVWF OPTION_REG ;Wレジスタからデータを移動します。
;****************************************************************
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;7bit0 GIE 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;6bit0 PEIE 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;5bit0 TMR0IE TMR0オーバーフロー割り込み 1有効 0無効
;4bit0 INTE RB0/INT外部割り込み 1有効 0無効
;3bit0 RBIE RBポート変化割り込み 1有効 0無効
;2bit0 TMR0IF TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;
;1bit0 INTF RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;
;0bit0 RBIF RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H104 BCF STATUS,RP0 ;0 バンク0を選択する
H105 BCF STATUS,RP1 ;0 バンク0を選択する
H106 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H107 MOVWF INTCON ;Wレジスタからデータを移動します。
;****************************************************************
;PIE1:周辺装置割り込みレジスタ1をENABLE(アドレス8CH DS30487C-20ページ)
;----- PIE1 Bits ----------------------------------------------------------
;6bit0 ADIE A/D変換器割り込み 1使用可能 0使用禁止
;5bit0 RCIE AUSART受信割り込み 1使用可能 0無効
;4bit0 TXIE AUSART送信割り込み 1使用可能 0無効
;3bit0 SSPIE 同期シリアルポート割り込み 1使用可能 0無効
;2bit0 CCP1IE CCP1割り込み 1使用可能 0無効
;1bit0 TMR2IE PR2一致割り込み(TMR2) 1使用可能 2無効
;0bit0 TMR1IE TMR1オーバーフロー割り込み 1使用可能 0使用禁止
H108 BSF STATUS,RP0 ;1 バンク1を選択する
H109 BCF STATUS,RP1 ;0 バンク1を選択する
H10A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H10B MOVWF PIE1 ;Wレジスタからデータを移動します。
;****************************************************************
;PIR1:周辺割り込み要求(FLAG)レジスタ1(アドレス0CH DS30487C-21ページ)
;----- PIR1 Bits ----------------------------------------------------------
;6bit0 ADIF A/D変換(ソフトウェアでクリアする必要がある) 1完了 0未完了
;5bit0 RCIF AUSARTの受信バッファ(RCREGを読み出すことによってクリア)
;1受信バッファがいっぱい 0受信バッファがない
;
;4bit1 TXIF AUSARTの送信バッファ(TXREGに書き込むことでクリアされる)
;1送信バッファがない 0送信バッファがいっぱい
;
;3bit0 SSPIF 同期シリアルポート(SSP)(ソフトウエアでクリアする必要がある)
;1送信/受信 完了 0送信/受信するために待機しています
;
;2bit0 CCP1IF TMR1レジスタのキャプチャ(ソフトウエアでクリアする必要がある)
;1キャプチャが発生した 0キャプチャが発生してない
;
;1bit0 TMR2IF TMR2 PR2との一致(ソフトウェアでクリアする必要がある)
;1一致が発生した 0一致は発生してない
;
;0bit0 TMR1IF TMR1のオーバーフロー(ソフトウェアでクリアする必要がある)
;1オーバーフローした 0オーバーフローしませんでした
H10C BCF STATUS,RP0 ;0 バンク0を選択する
H10D BCF STATUS,RP1 ;0 バンク0を選択する
H10E MOVLW B'00010000' ;8ビットリテラルをWレジスタへ格納
H10F MOVWF PIR1 ;Wレジスタからデータを移動します。
;****************************************************************
;PIE2:周辺装置割り込みレジスタ2をENABLE(アドレス 8DH DS30487C-22ページ)
;----- PIE2 Bits ----------------------------------------------------------
;7bit0 OSFIE オシレータ失敗割り込み 1使用可能 0無効
;6bit0 CMIE コンパレータ割り込み 1使用可能 0無効
;4bit0 EEIE 操作割り込み(EEPROM) 1使用可能 0無効
H110 BSF STATUS,RP0 ;1 バンク1を選択する
H111 BCF STATUS,RP1 ;0 バンク1を選択する
H112 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H113 MOVWF PIE2 ;Wレジスタからデータを移動します。
;****************************************************************
;PIR2周辺割り込み要求(FLAG)レジスタ2(アドレス 0DH DS30487C-23ページ)
;----- PIR2 Bits ----------------------------------------------------------
;7bit0 OSFIF (ソフトウェアでクリアの必要がある)
;1システム発振器が失敗し、クロック入力はINTRCに変更されました。
;0システムクロック動作
;
;6bit0 CMIF (ソフトウェアでクリアの必要がある)
;1コンパレータの入力が変化した
;0コンパレータの入力は変化していません
;
;4bit0 EEIF (ソフトウェアでクリアする必要がある)
;1 EEPROM書き込み完了
;0 EEPROM書き込みが完了してない
H114 BCF STATUS,RP0 ;0 バンク0を選択する
H115 BCF STATUS,RP1 ;0 バンク0を選択する
H116 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H117 MOVWF PIR2 ;Wレジスタからデータを移動します。
;****************************************************************
;PCON:POWER制御レジスタ(アドレス8EH DS30487C-24ページ)
;----- PCON Bits ----------------------------------------------------------
;1bitx NOT_POR
;1パワーオンリセットが発生してません
;0パワーオンリセットが発生しました(ソフトで設定が必要)
;
;0bitx NOT_BOR
;1ブラウンアウトリセットが発生してません
;0ブラウンアウトリセットが発生しました(ソフトでセットが必要)
H118 NOP ;BSF STATUS,RP0 ;1 バンク1を選択する
H119 NOP ;BCF STATUS,RP1 ;0 バンク1を選択する
H11A NOP ;MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H11B NOP ;MOVWF PCON ;Wレジスタからデータを移動します。
;****************************************************************
;EEPROM用レジスタの初期化
H11C BCF STATUS,RP0 ;0 バンク2を選択する
H11D BSF STATUS,RP1 ;1 バンク2を選択する
H11E MOVLW H'00' ;0x00をWへ格納
H11F MOVWF EEDATA ;WをEEDATAへ格納
H120 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H121 MOVWF EEDATH ;Wレジスタからデータを移動します。
H122 MOVLW H'00' ;0x00をWへ格納
H123 MOVWF EEADR ;WをEEADRへ格納
H124 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H125 MOVWF EEADRH ;Wレジスタからデータを移動します。
;EECON1:EEPROMアクセス制御レジスタ1(アドレス18CH DS30487C-28ページ)
;----- EECON1 Bits --------------------------------------------------------
;7bit0 EEPGD
;1フラッシュメモリにアクセス(このプログラムの入るメモリ)
;0データメモリにアクセス(EEPROM)
;
;4bit0 FREE
;1次のWRコマンドでEEADR:EEADRHによって対象メモリ行を消去
;0次のWRコマンドで書き込みを行います
;
;3bit0 WRERR
;1MCLRまたはWDT通常時のリセットが発生 書き込みが途中で終了したフラグ
;0書き込み動作が完了します。
;
;2bit0 WREN EEPROMへの書き込み
;1可能
;0禁止
;
;1bit0 WR
;1書き込みサイクルの開始(ハードウェアによって解除)
;0書き込みサイクル完了
;
;0bit0 RD
;1EERPOMへの読み取りを開始(ハードウェアによって解除)
;0開始しません
H126 BSF STATUS,RP0 ;1 バンク3を選択する
H127 BSF STATUS,RP1 ;1 バンク3を選択する
H128 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H129 MOVWF EECON1 ;Wレジスタからデータを移動します。
;EECON2 誤書き込み防止用レジスタ
;EEPROMは8ビットのこれだけかと思ったことがあった気がした
;ここに何か書き込まないと EEPROMに書き込めない雰囲気がしてくる ではなくて
;所定の書き込み手順がないとEECON2に書き込めない
;その所定の書き込みだけのためにある になっている
;とりあえず全部0にしておくことにした
H12A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H12B MOVWF EECON2 ;Wレジスタからデータを移動します。
;****************************************************************
;OSCTUNE内部発振器の調節(アドレス90H DS30487-38ページ)
;下位6bitを2の補数で指定する
;10 0000(最小周波数)?000000(中心周波数、校正周波数で動作)‾011111(最大周波数)
H12C BSF STATUS,RP0 ;1 バンク1を選択する
H12D BCF STATUS,RP1 ;0 バンク1を選択する
H12E MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H12F MOVWF OSCTUNE ;Wレジスタからデータを移動します。
;音を出して確認 7ドが7ミぐらいだった
;周波数を下げることにした
;とりあえず半分ぐらい 16 1 0000
;7ラになった
;先頭に1をつけると7ファになった
;最小周波数 7ミになった
;調節しても変化がないのかもしれない
;最大周波数にしてみることにした
;7ラになった
;中心に戻すことにした
;7ファ#になった
;OSCCON発振器制御レジスタ (アドレス8FH DS30487-40ページ)
;----- OSCCON Bits -------------------------------------------------------
; <6:4> = 111( 8MHz), 110( 4MHz), 101( 2MHz), 100( 1MHz)
; 011(500kHz), 010(250kHz), 001(125kHz), 000(31.25kHz)
;6bit1 IRCF2 周波数設定
;5bit1 IRCF1 周波数設定
;4bit1 IRCF0 周波数設定
;3bitx OSTS 3bit読み出しのみ
;1プライマリクロックから実行
;0T1OSCまたはINTRCから実行
;
;2bitx IOFS 2bit読み出しのみ
;1周波数が安定
;0周波数が不安定
;オシレータモード選択ビット
;00:FOSCで定義されたオシレータモード
;01:T1OSCは、システムクロックのために使用されています
;10:内部RCは、システムクロックのために使用されています
;11:予約済み
;1bit1 SCS1
;0bit0 SCS0
H130 BSF STATUS,RP0 ;1 バンク1を選択する
H131 BCF STATUS,RP1 ;0 バンク1を選択する
H132 BSF OSCCON,IRCF2 ;8MHzに設定
H133 NOP ;BCF OSCCON,IRCF2
H134 BSF OSCCON,IRCF1
H135 NOP ;BCF OSCCON,IRCF1
H136 BSF OSCCON,IRCF0
H137 NOP ;BCF OSCCON,IRCF0
H138 BSF OSCCON,SCS1 ;内部RCに設定
H139 NOP ;BCF OSCCON,SCS1
H13A NOP ;BSF OSCCON,SCS0
H13B BCF OSCCON,SCS0
;****************************************************************
;PORTAの初期化(アドレス5H DS30487-51ページ)
;
;17 RA0/AN0 TTL A出力
;18 RA1/AN1 TTL /A出力
;1 RA2/AN2/CVref/Vref- TTL B出力
;2 RA3/AN3/Vref+/C1out TTL /B出力
;3 RA4/AN4/T0CK1/C2out ST 空き 0出力
;4 RA5/MCLR*/Vpp ST +5Vに直結 リセット入力
;15 RA6/OSC2/CLK0 ST (内部周波数)/4Hzのモニター出力
;16 RA7/OSC1/CLK1 ST/CMOS 空き 0出力
H13C BCF STATUS,RP0 ;0 バンク0を選択する
H13D BCF STATUS,RP1 ;0 バンク0を選択する
H13E CLRF PORTA ;PORTAを初期化することで、出力をクリアします。データラッチ
;****************************************************************
;----- ANSEL Bits ---------------------------------------------------------
;6bit0 ANS6 AN6アナログ
;5bit0 ANS5 AN5アナログ
;4bit0 ANS4 AN4アナログ
;3bit0 ANS3 AN3アナログ
;2bit0 ANS2 AN2アナログ
;1bit0 ANS1 AN1アナログ
;0bit0 ANS0 AN0アナログ
H13F BSF STATUS,RP0 ;1 バンク1を選択する
H140 BCF STATUS,RP1 ;0 バンク1を選択する
H141 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H142 MOVWF ANSEL ;Wレジスタからデータを移動します。
;7bit0 TRISA RA7 1入力 0出力
;6bit1 TRISA RA6 1入力 0出力
;5bit1 TRISA RA5 1入力 0出力
;4bit0 TRISA RA4 1入力 0出力
;3bit0 TRISA RA3 1入力 0出力
;2bit0 TRISA RA2 1入力 0出力
;1bit0 TRISA RA1 1入力 0出力
;0bit0 TRISA RA0 1入力 0出力
H143 MOVLW B'01100000' ;8ビットリテラルをWレジスタへ格納
H144 MOVWF TRISA ;Wレジスタからデータを移動します。
;****************************************************************
;PORTBの初期化(アドレス6H DS30487-57ページ)
;
;6 RB0/INT/CCP1 TTL/ST STEP入力 ポートBプルアップ無効 立ち上がりエッジで割り込み
;7 RB1/SDI/SDA TTL/ST 空き入力 ポートBプルアップ無効
;8 RB2/SDO/RX/DT TTL/ST 空き入力 ポートBプルアップ無効
;9 RB3PGM/CCP1 TTL/ST 空き入力 ポートBプルアップ無効 コンパレータ入力
;10 RB4/SCK/SCL TTL/ST 空き入力 ポートBプルアップ無効
;11 RB5/SS*/TX/CK TTL 空き入力 ポートBプルアップ無効
;12 RB6/AN5/PGC/T1OSO/T1CK1 TTL/ST DER入力 ポートBプルアップ無効
;13 RB7/AN6/PGD/T1OSI TTL/ST 空き入力 ポートBプルアップ無効
H145 BCF STATUS,RP0 ;0 バンク0を選択する
H146 BCF STATUS,RP1 ;0 バンク0を選択する
H147 CLRF PORTB ;PORTBを初期化することで、出力をクリアします。データラッチ
;7bit1 TRISB RB7 1入力 0出力
;6bit1 TRISB RB6 1入力 0出力
;5bit1 TRISB RB5 1入力 0出力
;4bit1 TRISB RB4 1入力 0出力
;3bit1 TRISB RB3 1入力 0出力
;2bit1 TRISB RB2 1入力 0出力
;1bit1 TRISB RB1 1入力 0出力
;0bit1 TRISB RB0 1入力 0出力
H148 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H149 MOVWF TRISB ;Wレジスタからデータを移動します。
;****************************************************************
;TMR0の初期化
H14A BCF STATUS,RP0 ;0 バンク0を選択する
H14B BCF STATUS,RP1 ;0 バンク0を選択する
H14C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H14D MOVWF TMR0 ;Wレジスタからデータを移動します。
;TIMER0モジュール 8ビットタイマ/カウンタ(DS30487-67ページ)
;インターバルタイマーとして使える
;タイマーオーバーフローの割り込みを発生させることができる
;カウンタの初期値を変更して、オーバーフローまでのカウント数を変更して
;タイマーの値を設定する
;
;カウンタの設定値の求め方
;(インターバル時間)/(CPUクロック×4)
;例 CPUの水晶発振子が10MHzの時に20msecのインターバルとするためには、
;20msec×1000/0.1usec×4=50000
;
;TMR0には8ビットのプリスケーラが接続されています
;従って8ビット+8ビットで合計16ビットで
;65535までのカウントができます。
;
;プリスケーラの動かし方は、2,4,8,16,32,64,128,256カウントの8種類となっています。
;
;上例20msecのタイマーとするには
;50000/256=約195(16進数でC3H)となります
;従ってカウンタの設定値は結局下記となります。
;プリスケーラ 256カウント
;TMR0カウンタはアップカウンタなので
;FFH-C3H=3CHで3Cが設定値となる。
;タイマーのカウンタの動作速度。 規格表に書いてあるらしい
;プリスケーラ無しの時は、最大2.3MHz
;プリスケーラ付きの時は、最大18MHz
;
;TMR0カウンタ本体 :
;最小パルス幅=(クロックサイクル)+20nsec ;=420nsec周期=2.38MHz
;
;プリスケーラ本体 : 最小パルス幅=50nsec(電源5V)
; =20MHz
; プリスケーラとTMR0の組み合わせの時
; : 最小パルス幅=((クロックサイクル)+40nsec)/(プリスケーラ値)
; プリスケーラ値毎に計算すると
; =440/2=220nsec=4.54MHz
; =440/4=110nsec=9.09MHz
; =440/8= 55nsec=18.1MHz(最大動作値)
; =440/16=27.5nsec=36.3MHZ>20MHz
;クロックが10Mhzの時は プリスケーラーは8までしか使えない に なっている
;入力信号の安定時間用のタイマーにしようと思った
;今回の入力ステップ信号のパルス調整幅 1-5us 0.000001s-0.000005s
;PICクロックが8MHzのとき、パルス信号5μsの間に何命令実行できるかを調べることにした。
;1命令4クロック 4/8=0.5us より
;10命令分のパルス幅しかないことがわかった
;出力の更新をしながら入力の確認と信号の安定時間のプログラムは作れそうにない
;信号の入力には、割り込み入力を使うことになった
;移動速度とそのときの周波数の計算
;最大移動速度は、仮に3秒で150mmほどを目安にすることとした
;1秒で50mm移動できることを目標とする
;12mmで200ステップの時は1mmあたり16.6666ステップになる
;50mmの時は 50mm×16.6666ステップ=833.33ステップになる
;1秒間に833.33ステップを出す時は 出力周波数 833.33Hz のこと
;2相励磁のときは、833.33Hzの出力周波数になる
;1命令 0.0000005sだから 1秒間に2000000命令実行できる
;出力周波数の更新ごとに2000000/833.33=2400命令実行できる
;2相励磁のときは入力待ちループでも大丈夫かもしれない
;PWM出力にするときは割り込み入力が必要になる
;今のうちに入力は割り込みから持ってこれるようにしたほうがいい気がした
;
;PWMにするときはステップの変更とタイマー設定値の変更
;タイマーのカウントアップを見つつ出力をオンオフすると良さそう
;タイマー0(DS30487-67ページ) 未使用 ポートBプルアップ追加
;OPTION_REG:OPTION制御レジスタ(アドレス81H,181H DS30487C-18ページ)
;----- OPTION_REG Bits -----------------------------------------------------
;7bit1 NOT_RBPU ポートBプルアップ
;1無効
;0有効
;
;6bit1 INTEDG RB0/INTピン
;1立ち上がりエッジで割り込み
;0立ち下がりエッジで割り込み
;
;5bit0 T0CS TMR0クロック
;1RA4/T0CKI/C2OUTピンの変遷
;0内部サイクルクロック(CLKO)
;
;4bit0 T0SE RA4/T0CKI/C2OUTピンのインクリメント
;1ハイからロー
;0ローからハイ
;
;3bit0 PSA プリスケーラの割り当て
;1WDT
;0タイマ0
;
;PS<2:0>プリスケーラ選択ビット
; TMR0 WDT
;000 1:2 1:1 とりあえずこれに設定
;001 1:4 1:2
;010 1:8 1:4
;011 1:16 1:8
;100 1:32 1:16
;101 1:64 1:32
;110 1:128 1:64
;111 1:256 1:128
;PS2 2bit0
;PS1 1bit0
;PS0 0bit0
H14E BSF STATUS,RP0 ;1 バンク1を選択する
H14F BCF STATUS,RP1 ;0 バンク1を選択する
H150 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H151 MOVWF OPTION_REG ;Wレジスタからデータを移動します。
;****************************************************************
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;7bit0 GIE
;1全てのマスクされてない割り込みを許可
;0全ての割り込みは無効
;
;6bit0 PEIE
;1全てのマスクされていない周辺割り込みを有効
;0全ての周辺割り込みを無効
;
;5bit0 TMR0IE
;TMR0オーバーフロー割り込み
;1有効
;0無効
;
;4bit0 INTE
;RB0/INT外部割り込み
;1有効
;0無効
;
;3bit0 RBIE
;RBポート変化割り込み
;1有効
;0無効
;
;2bit0 TMR0IF
;TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
;1した
;0しませんでした
;
;1bit0 INTF
;RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
;1発生した
;0発生しませんでした
;
;0bit0 RBIF
;RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
;1発生した
;0変化なし
;
H152 BCF STATUS,RP0 ;0 バンク0を選択する
H153 BCF STATUS,RP1 ;0 バンク0を選択する
H154 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H155 MOVWF INTCON ;Wレジスタからデータを移動します。
;****************************************************************
;タイマー1の設定 PWM信号用にする
;カウンターの入力はクロック/4になっている
;最大内部クロック8MHzの時に、最大2MHzがカウンターに入力される
;1命令実行する時間で、カウンターも1カウントされるからわかりやすい
;PWM周波数は、20kHzぐらいがよく使われているらしい。
;早すぎてキーンと音が聞こえないのがちょっと寂しい
;2MHzは1秒間に2,000,000個の山がある速さのことで、
;TMR0の時は、プリスケーラ無しで255までカウントできる
;TMR1の時は、プリスケーラ無しで65535までカウントできる
;2,000,000/20,000=100 より、100回繰り返すと2MHzになる
;1秒間に100回繰り返すから100Hzのこと
;高音すぎて聞こえないかと思いきや、低音すぎてきこえなかったのかもしれない
;で 1kHzにするとしたら プリスケーラーが必要になると思いきや
;20kHzだと思っていた カウント数 のところを減らすことにした
;2,000,000 / 2,000 = 1000Hz
;タイマーのカウントアップを2000にセットすると
;PWM分解能1000ステップ、出力周波数は1kHzとなる
;
;タイマー1を使うことになった。16ビットカウンタ。
;タイマー1(DS30487-71ページ)
;タイマー0と同様の機能を持っている
;カウンタが16ビットになっている TMR1H:TMR1L
;キャプチャ機能やコンペア機能がある
;
;タイマー1の設定とカウント動作開始
;コンペアを使うことにする
;使えそうな分割数と最小移動量
;分割数 / 移動量 / 1-2相ステップ間の分割数 / PWM周波数
;1200分割 0.01mm 1200/400=3 2MHz/1.666kHz
;2400分割 0.005mm 2400/400=6 2MHz/833.333Hz
;6000分割 0.002mm 6000/400=15 2MHz/333.333Hz
;12000分割 0.001mm 12000/400=30 2MHz/166.666Hz
;24000分割 0.0005mm 24000/400=60 2MHz/83.333Hz
;60000分割 0.0002mm 60000/400=150 2MHz/33.333Hz
;120000分割 0.0001mm 120000/400=300 2MHz/16.666Hz
;割り切れないから誤差が出る
;誤差が気にならないところにセットしたらよさそう
;プログラムからの誤差より小さいかもしれない
;TMR1の初期設定
H156 BCF STATUS,RP0 ;0 バンク0を選択する
H157 BCF STATUS,RP1 ;0 バンク0を選択する
;タイマー1の初期値
;1秒間に50mmの移動速度を最高速度としたとき
;1相励磁のときは 833.33Hz でモーターが回ってる
;1-2相励磁のときは 1.666kHz でモーターが回ってる
;1相励磁の1パルスあたり2400命令分使える
;1-2相励磁の1パルスあたり1200命令分使える
;PWM周波数はそれの10倍がいいのかもしれない
;1.666kHzの10倍ないと PWM周波数と同じになって脱調になる
;16kHz以上の周波数がほしくなった
;とりあえず20KHzに設定することにした
;65535-20000=45535
;1011 0001 1101 1111
;とおもいきや
;200カウントで10kHzになってるから
;200でよさそう
;前のは100Hzかもしれない
;65535-200=65335
;1111 1111 0011 0111
H158 MOVLW B'00110111' ;8ビットリテラルをWへ格納
H159 MOVWF T1INIL ;WをT1INILへ格納
H15A MOVLW B'11111111' ;8ビットリテラルをWへ格納
H15B MOVWF T1INIH ;WをT1INIHへ格納
H15C MOVF T1INIL,0 ;T1INILをWへ格納
H15D MOVWF TMR1L ;WをTMR1Lへ格納
H15E MOVF T1INIH,0 ;T1INIHをWへ格納
H15F MOVWF TMR1H ;TMR1Hへ格納
;タイマー1動作させる設定 (DS30487-71ページ)
;タイマー0と同様の機能を持っている
;カウンタが16ビットになっている TMR1H:TMR1L
;キャプチャ機能やコンペア機能がある
;
;T1CON:TIMER1コントロールレジスタ(アドレス10H DS3048-71ページ)
;----- T1CON Bits ---------------------------------------------------------
;6bit0 T1RUN
;1タイマ1よりシステムクロック
;0別ソースより
;
;タイマ1の入力クロックプリスケール選択ビット
;11=1:8プリスケール値
;10=1:4プリスケール値
;01=1:2プリスケール値
;00=1:1プリスケール値 これに設定
;5bit0 T1CKPS1
;4bit0 T1CKPS0
;3bit0 T1OSCEN
;1外部発振器有効
;0外部発振器遮断
;
;2bit1 NOT_T1SYNC
;1外部クロックを同期しない
;0外部クロックを同期する
;
;2bit T1INSYNC 下位互換性
;
;1bit0 TMR1CS
;1RB6/AN5から外部クロック
;0内部クロック(FOSC/4)
;
;0bit1 TMR1ON
;1タイマ1が有効
;0タイマ1が停止
H160 MOVLW B'00000101' ;8ビットリテラルをWレジスタへ格納
H161 MOVWF T1CON ;Wレジスタからデータを移動します。
;****************************************************************
;PR2の初期化 PWMの周期幅の設定 (パルス幅CCPR1L) TMR2のカウント数
H162 BCF STATUS,RP0 ;0 バンク0を選択する
H163 BCF STATUS,RP1 ;0 バンク0を選択する
H164 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H165 MOVWF PR2 ;Wレジスタからデータを移動します。
;TMR2の初期化
H166 BCF STATUS,RP0 ;0 バンク0を選択する
H167 BCF STATUS,RP1 ;0 バンク0を選択する
H168 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H169 MOVWF TMR2 ;Wレジスタからデータを移動します。
;タイマー2(DS30487-79ページ) 未使用
;前段4ビットプリスケーラ、出力段4ビットポストスケーラ付き8ビットカウンタ
;CCP1モジュールのPWMモードのPWMタイムベースとして使用できる
;入力は内部クロックのみ
;T2CON:TIMER2コントロールレジスタ(12H DS30487-80ページ)
;----- T2CON Bits ---------------------------------------------------------
;タイマ2出力ポストスケール選択
;0000=1:1ポストスケール これに設定
;0001=1:2ポストスケール
;0010=1:3ポストスケール
;・
;・
;・
;1111=1:16ポストスケール
;6bit0 TOUTPS3
;5bit0 TOUTPS2
;4bit0 TOUTPS1
;3bit0 TOUTPS0
;2bit0 TMR2ON
;1タイマ2がオンになっています
;0タイマ2はオフになっています
;
;00プリスケーラは1 これに設定
;01プリスケーラは4
;1×プリスケーラは16
;1bit0 T2CKPS1
;0bit0 T2CKPS0
H16A BCF STATUS,RP0 ;0 バンク0を選択する
H16B BCF STATUS,RP1 ;0 バンク0を選択する
H16C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H16D MOVWF T2CON ;Wレジスタからデータを移動します。
;****************************************************************
;CCP1CON:キャプチャ/コンペア/PWM制御レジスタ1(アドレス17H DS30487-81ページ)
;----- CCP1CON Bits -------------------------------------------------------
; CCPR1Lレジスタの下位に連結されるビット
; 10ビットとしてPWMのパルス幅を指定する時用。
; 今回は0固定
;5bit0 CCP1X
;4bit0 CCP1Y
;0000 CCPモジュール未使用(CCPモジュール初期化)
;0100 キャプチャモード(立ち下がりエッジ)
;0101 キャプチャモード(立ち上がりエッジ)
;0110 キャプチャモード(立ち上がりエッジ4回毎)
;0111 キャプチャモード(立ち上がりエッジ16回毎)
;1000 コンペアモード(出力セット CCP1IFセット)
;1001 コンペアモード(出力クリア CCP1IFセット)
;1010 コンペアモード(出力変化なし CCP1IFセット) これにする
;1011 コンペアモード(出力変化なし CCP1IFセット TMR1リセット A/Dが有効なら開始)
;11xx PWMモード
;3bit1 CCP1M3
;2bit0 CCP1M2
;1bit1 CCP1M1
;0bit0 CCP1M0
;CCPモジュール初期化
H16E BCF STATUS,RP0 ;0 バンク0を選択する
H16F BCF STATUS,RP1 ;0 バンク0を選択する
H170 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H171 MOVWF CCP1CON ;Wレジスタからデータを移動します。
;CCPR1L,H コンペア・キャプチャ・PWM用のレジスタの初期設定
;コンペア初期値の設定
;タイマー1は20kHzに設定してある
;カウント値は0-100の間になる
;3分割の設定で 33づつ増減とする 6666かもしれない
;初期値 65535-20000+33=45568 ではなくて
;初期値 65535-20000+6666=52201 ではなくて
;初期値 65535-20000=45535
;1011 0001 1101 1111
H172 MOVLW B'11011111' ;8ビットリテラルをWレジスタへ格納
H173 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H174 MOVLW B'10110001' ;8ビットリテラルをWレジスタへ格納
H175 MOVWF CCPR1H ;Wレジスタからデータを移動します。
;CCPモジュール開始
H176 MOVLW B'00001010' ;8ビットリテラルをWレジスタへ格納
H177 MOVWF CCP1CON ;Wレジスタからデータを移動します。
;****************************************************************
;SSPBUFの初期化 SPI通信用のバッファ
H178 BCF STATUS,RP0 ;0 バンク0を選択する
H179 BCF STATUS,RP1 ;0 バンク0を選択する
H17A MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H17B MOVWF SSPBUF ;Wレジスタからデータを移動します。
;****************************************************************
;SSPADD シリアル通信用 スレーブ時の自アドレス の 初期化
H17C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H17D MOVWF SSPADD ;Wレジスタからデータを移動します。
;****************************************************************
;****************************************************************
;SSPSTAT:同期シリアルポート・ステータス・レジスタ(アドレス94H DS30487-88ページ)
;----- SSPSTAT Bits -------------------------------------------------------
;7bit1 SMP スルーレート
;1標準速度指定(100kbps,1MHz)
;0高速指定(400kbps)
;
;6bit1 CKE クロックエッジ
;1SCKの立ち上がり
;0SCKの立ち下がり
;
;5bitx D
;1最新受信バイトがデータである
;0最新受信バイトがアドレスである
;
;5bit I2C_DATA
;5bit NOT_A
;5bit NOT_ADDRESS
;5bit D_A
;5bit DATA_ADDRESS
;
;4bit P Stopシーケンス検出
;1検出した
;0未検出
;
;4bit I2C_STOP
;
;3bit S Startシーケンス検出
;1検出した
;0未検出
;
;3bit I2C_START
;2bit R スレーブ時
;1Read 0Write マスタ時 1送信中
;0送信中ではない
;
;2bit I2C_READ
;2bit NOT_W
;2bit NOT_WRITE
;2bit R_W
;2bit READ_WRITE
;
;1bit UA アドレス更新要求
;1更新が必要
;0更新不要
;
;0bit BF 受信中
;1受信完了
;0受信未完了
;送信中
;1送信中
;0送信完了
H17E BSF STATUS,RP0 ;1 バンク1を選択する
H17F BCF STATUS,RP1 ;0 バンク1を選択する
H180 MOVLW B'11000000' ;8ビットリテラルをWレジスタへ格納
H181 MOVWF SSPSTAT ;Wレジスタからデータを移動します。
;****************************************************************
;SSPCON:同期シリアルポートコントロールレジスタ(アドレス14H DS3048-89ページ)
;----- SSPCON Bits --------------------------------------------------------
;7bit0 WCOL
;1SSPモジュールビジー、SSPBUF書き込み失敗
;0衝突なし
;
;6bit0 SSPOV
;1SSPBUFオーバーフロー
;0オーバーフローではありません
;
;5bit0 SSPEN
;1シリアル有効 SDA SCL
;0シリアル無効I/O
;
;4bit0 CKP 4bit0
;1立ち上がりエッジで受信
;0立ち下がりエッジで受信
;
;3bit0 SSPM3 同期シリアルポートモード
;2bit0 SSPM2 SPIマスターモード クロック OSC/4
;1bit0 SSPM1
;0bit0 SSPM0
H182 BCF STATUS,RP0 ;0 バンク0を選択する
H183 BCF STATUS,RP1 ;0 バンク0を選択する
H184 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H185 MOVWF SSPCON ;Wレジスタからデータを移動します。
;****************************************************************
;TXREGの初期化 送信データ用レジスタ
H186 BCF STATUS,RP0 ;0 バンク0を選択する
H187 BCF STATUS,RP1 ;0 バンク0を選択する
H188 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H189 MOVWF TXREG ;Wレジスタからデータを移動します。
;****************************************************************
;USART
;TXSTA:送信ステータスおよび制御レジスタ(アドレス98H DS30487-97ページ)
;----- TXSTA Bits ---------------------------------------------------------
;7bit0 CSRC クロック選択
;1内部
;0外部
;
;6bit0 TX9 ビットモード
;1,9ビット
;0,8ビット
;
;6bit NOT_TX8
;6bit TX8_9
;
;5bit0 TXEN 送信許可
;1許可
;0禁止
;
;4bit0 SYNC モード選択
;1同期
;0非同期
;
;2bit0 BRGH 高速サンプル
;1高速
;0低速
;
;1bit0 TRMT 送信レジスタ
;1TSR空
;0TSRフル
;
;0bit0 TX9D 送信データ9ビット目
;0bit TXD8
H18A BSF STATUS,RP0 ;1 バンク1を選択する
H18B BCF STATUS,RP1 ;0 バンク1を選択する
H18C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H18D MOVWF TXSTA ;Wレジスタからデータを移動します。
;****************************************************************
;RCREGの初期化 受信データ用レジスタ
H18E BCF STATUS,RP0 ;0 バンク0を選択する
H18F BCF STATUS,RP1 ;0 バンク0を選択する
H190 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H191 MOVWF RCREG ;Wレジスタからデータを移動します。
;RCSTA:11-2ステータスレジスタを受け取り、制御レジスタ(アドレス18H DS30487-98ページ)
;----- RCSTA Bits ---------------------------------------------------------
;7bit0 SPEN シリアルピン
;1シリアル
;0汎用
;
;6bit0 RX9 ビットモード
;1、9ビット
;0、8ビット
;
;6bit RC9
;6bit NOT_RC8
;6bit RC8_9
;
;5bit0 SREN シングル受信許可
;1許可
;0禁止
;
;4bit0 CREN 継続受信許可
;1許可
;0禁止
;
;3bit0 ADDEN アドレス受信許可(9ビットモードのみ)
;1許可
;0禁止
;
;2bit0 FERR フレーミングエラーステータス
;1エラー
;0正常
;
;1bit0 OERR オーバーランエラーステータス
;1エラー
;0正常
;
;0bit0 RX9D 受信デーた9ビット目パリティ
;0bit RCD8
H192 BCF STATUS,RP0 ;0 バンク0を選択する
H193 BCF STATUS,RP1 ;0 バンク0を選択する
H194 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H195 MOVWF RCSTA ;Wレジスタからデータを移動します。
;****************************************************************
;SPBRG ボーレートの設定(アドレス99H)
H196 BSF STATUS,RP0 ;1 バンク1を選択する
H197 BCF STATUS,RP1 ;0 バンク1を選択する
H198 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H199 MOVWF SPBRG ;Wレジスタからデータを移動します。
;****************************************************************
;A/D変換の設定
;ANSEL:アナログSELECT REGISTER(アドレス 9BH DS30487-113ページ)
;----- ANSEL Bits ---------------------------------------------------------
;6bit0 ANS6 AN6アナログ
;5bit0 ANS5 AN5アナログ
;4bit0 ANS4 AN4アナログ
;3bit0 ANS3 AN3アナログ
;2bit0 ANS2 AN2アナログ
;1bit0 ANS1 AN1アナログ
;0bit0 ANS0 AN0アナログ
H19A BSF STATUS,RP0 ;1 バンク1を選択する
H19B BCF STATUS,RP1 ;0 バンク1を選択する
H19C MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H19D MOVWF ANSEL ;Wレジスタからデータを移動します。
;****************************************************************
;ADCON0:A/D制御レジスタ(アドレス 1FH DS30487-114ページ)
;----- ADCON0 Bits --------------------------------------------------------
;A/D変換クロック ADCON1のADCS2が2ビット目
;000 FOSC/2
;001 FOSC/8
;010 FOSC/32
;011 FRC
;000 FOSC/4
;001 FOSC/16
;010 FOSC/64
;011 FRC
;7bit0 ADCS1
;6bit0 ADCS0
;CHS <2:0>: アナログチャネル選択ビット
;000 = チャネル0(RA0 / AN0)
;001 = チャンネル1(RA1 / AN1)
;010 = チャンネル2(RA2 / AN2)
;011 = チャンネル3(RA3 / AN3)
;100 = チャンネル4(RA4 / AN4)
;101 = チャンネル5(RB6 / AN5)
;110 = チャンネル6(RB7 / AN6)
;5bit0 CHS2
;4bit0 CHS1
;3bit0 CHS0
;2bit0 GO
;1A/D変換を開始
;0完了
;
;2bit NOT_DONE
;2bit GO_DONE
;0bit0 ADON
;1A/Dコンバータが動作
;0A/Dコンバータの電源オフ
H19E BCF STATUS,RP0 ;0 バンク0を選択する
H19F BCF STATUS,RP1 ;0 バンク0を選択する
H1A0 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H1A1 MOVWF ADCON0 ;Wレジスタからデータを移動します。
;****************************************************************
;ADCON1:A/D制御レジスタ1(アドレス9FH DS30487-115ページ)
;----- ADCON1 Bits --------------------------------------------------------
;7bit1 ADFM A/D結果フォーマット
;1右詰
;0左揃え
;
;6bit0 ADCS2 A/D変換クロック 0、1ビットはADCON0
;
;VCFG<1:0>ビット 基準電圧の設定
;00 AVDD AVSS これに設定
;01 AVDD VREF-
;10 VREF+ AVSS
;11 VREF+ VREF-
;5bit0 VCFG1
;4bit0 VCFG0
H1A2 BSF STATUS,RP0 ;1 バンク1を選択する
H1A3 BCF STATUS,RP1 ;0 バンク1を選択する
H1A4 MOVLW B'10000000' ;8ビットリテラルをWレジスタへ格納
H1A5 MOVWF ADCON1 ;Wレジスタからデータを移動します。
;****************************************************************
;CMCON:コンパレータモジュール制御レジスタ(アドレス9CH DS30487-121ページ)
;----- CMCON Bits ---------------------------------------------------------
;7bit C2OUT コンパレータ出力
;6bit C1OUT コンパレータ出力
;5bit C2INV コンパレータ反転出力
;4bit C1INV コンパレータ反転出力
;3bit0 CIS コンパレータの入力ピン切り替え
;2bit1 CM2 コンパレータオフ デフォルト
;1bit1 CM1
;0bit1 CM0
H1A6 BSF STATUS,RP0 ;1 バンク1を選択する
H1A7 BCF STATUS,RP1 ;0 バンク1を選択する
H1A8 NOP ;BSF CMCON,CIS ;何もしない
H1A9 BCF CMCON,CIS
H1AA BSF CMCON,CM2
H1AB NOP ;BCF CMCON,CM2 ;何もしない
H1AC BSF CMCON,CM1
H1AD NOP ;BCF CMCON,CM1 ;何もしない
H1AE BSF CMCON,CM0
H1AF NOP ;BCF CMCON,CM0 ;何もしない
;****************************************************************
;CVRCON:コンパレータ電圧リファレンス制御レジスタ(アドレス 9DH DS30487-127ページ)
;----- CVRCON Bits --------------------------------------------------------
;7bit0 CVREN リファレンス
;1使う
;0使わない
;
;6bit0 CVROE Vrefの外部出力
;1RA2に出力
;0出力せず
;
;5bit0 CVRR
;1,0.0-0.75 24step
;0,0.25-0.75 43step
;
;3bit0 CVR3 電圧微調節
;2bit0 CVR2
;1bit0 CVR1
;0bit0 CVR0
H1B0 BSF STATUS,RP0 ;1 バンク1を選択する
H1B1 BCF STATUS,RP1 ;0 バンク1を選択する
H1B2 MOVLW B'00000000' ;8ビットリテラルをWレジスタへ格納
H1B3 MOVWF CVRCON ;Wレジスタからデータを移動します。
;****************************************************************
;ウォッチドッグタイマの設定
;WDTCON:ウォッチドッグ制御レジスタ(アドレス105H DS30487-142ページ)
;----- WDTCON Bits --------------------------------------------------------
;WDTPS<3:0>Watch Dog Prescaler value
;0000=1:32
;0001=1:64
;0010=1:128
;0011=1:256
;0100=1:512
;0101=1:1024
;0110=1:2048
;0111=1:4096
;1000=1:8192
;1001=1:16384
;1010=1:32768
;1011=1:65536
;4bit0 WDTPS3
;3bit0 WDTPS2
;2bit0 WDTPS1
;1bit0 WDTPS0
;0bit1 SWDTEN
;1Watch dog timer is on
;0Watch dog timer is off
;
;0bit SWDTE 0bit
H1B4 BCF STATUS,RP0 ;0 バンク2を選択する
H1B5 BSF STATUS,RP1 ;1 バンク2を選択する
H1B6 MOVLW B'00000001' ;8ビットリテラルをWレジスタへ格納
H1B7 MOVWF WDTCON ;Wレジスタからデータを移動します。
;****************************************************************
;ULPWUモジュールの設定
;極低消費電流ウェイクアップ
;コンデンサに充電してスリープ。放電後コンパレータの割り込みで復帰
;取説で見た気がしたけど見当たらなくなった
;と思いきやバンク0に書き込んだことがあった気がした
;EQUのアドレス指定が別になっていて、間違えないようになっていた
;ビットは同じだけど、間違えない先だから大丈夫なのかもしれない
H1B8 GOTO H1F0 ;
H1B9 NOP ;何もしない
H1BA NOP ;何もしない
H1BB NOP ;何もしない
H1BC NOP ;何もしない
H1BD NOP ;何もしない
H1BE NOP ;何もしない
H1BF NOP ;何もしない
ORG_1F0 ORG 0x1F0 ;特殊機能レジスタの初期化完了ベクタ
H1F0 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより
H1F1 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより
H1F2 BSF GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了フラグセット
H1F3 GOTO H200 ;メインプログラム変数の初期化へ
H1F4 NOP ;何もしない
H1F5 NOP ;何もしない
H1F6 NOP ;何もしない
H1F7 NOP ;何もしない
H1F8 NOP ;何もしない
H1F9 NOP ;何もしない
H1FA NOP ;何もしない
H1FB NOP ;何もしない
H1FC NOP ;何もしない
H1FD NOP ;何もしない
H1FE NOP ;何もしない
H1FF NOP ;何もしない
;****************************************************************
;今の設定
;CPU8MHzで動作中
;割り込み無しでシステムの初期設定まで
;****************************************************************
; Main Routine
;****************************************************************
ORG_200 ORG 0x200 ;メインプログラム変数の初期化開始ベクタ
H200 CLRWDT ;ウォッチドックタイマのリセット
H201 BTFSS GPR20,Special_func_reg_ini_comp ;特殊機能レジスタ初期化完了フラグが1だったら次をスキップ
H202 GOTO H000 ;
H203 BCF GPR20,Variable_ini_comp ;メインプログラム変数初期化完了フラグクリア バンク0指定
H204 BCF GPR20,Step_memory ;STEP I/O割り込みの入力状態記憶
H205 BCF GPR20,Dir_memory ;DIR I/O割り込みの入力状態記憶
;STEP変数の初期化
H206 MOVLW H'00' ;H'00'をWへ格納
H207 MOVWF STEP
;モーターの励磁モード設定 (MODE)
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1-2相励磁
;0000 0100:PWMステップ
H208 MOVLW B'00000100' ;モーターの励磁モード設定
H209 MOVWF MODE ;WをMODEへ格納 バンク0指定
H20A GOTO H230
H20B NOP
H20C NOP
H20D NOP
H20E NOP
H20F NOP
;モーターの分割数設定(PWMステップ用の設定)
;10分割にしてみることにした
ORG_230 ORG 0x230
H230 MOVLW B'00001010' ;H'00010100'をWへ格納 10分割に設定
H231 MOVWF DIV ;WをDIVへ格納 バンク0指定
H232 NOP ;何もしない
H233 NOP ;何もしない
H234 NOP ;何もしない
H235 NOP ;何もしない
H236 NOP ;何もしない
H237 NOP ;何もしない
H238 NOP ;何もしない
H239 NOP ;何もしない
H23A NOP ;何もしない
H23B NOP ;何もしない
H23C NOP ;何もしない
H23D NOP ;何もしない
H23E NOP ;何もしない
H23F NOP ;何もしない
ORG_240 ORG 0x240
;レジスタの初期化完了
H240 BSF GPR20,Variable_ini_comp ;メインプログラム変数初期化完了フラグセット バンク0指定
;サーボオン リセットがかかったことがわかるように 初期動作しようかな やっぱりやめた
;サーボオンした時、移動中のリセットだった場合いきなり大きく動いてぶつかるかもしれない
;パソコンからパルス出力中に電源を入れないこと。
;一軸だけリセットだと 他のは動いていて 変な動きになるかもしれない
;できるだけ早く復帰して 動き始めた方がいいかもしれない これが良さそう
;H241 CALL H600 ;音 ド
;H242 CALL H650 ;音 レ
;H243 CALL H6A0 ;音 ミ
H241 NOP
H242 NOP
H243 NOP
H244 NOP
H245 NOP
H246 NOP
H247 NOP
H248 NOP
H249 NOP
H24A CLRWDT ;ウォッチドッグタイマのリセット
H24B NOP
H24C NOP
H24D NOP
H24E NOP
H24F NOP
;****************************************************************
ORG_250 ORG 0x250
;起動時の初期励磁プログラムの選択ベクタ
H250 CLRWDT ;ウォッチドッグタイマのリセット
H251 BTFSS GPR20,Variable_ini_comp ;メインプログラム変数初期化完了 1なら次をスキップ
H252 GOTO H000 ;リセットベクタへ
H253 BTFSC MODE,Variable_ini_comp ;ビットが0なら次の命令をスキップする
H254 GOTO H300 ;PWMステッププログラム
H255 BTFSC MODE,1 ;ビットが0なら次の命令をスキップする
H256 GOTO H290 ;1-2相励磁プログラム
H257 BTFSC MODE,0 ;ビットが0なら次の命令をスキップする
H258 GOTO H262 ;2相 初期励磁
H259 GOTO H260 ;1相 初期励磁
H25A NOP ;何もしない
H25B NOP ;何もしない
H25C NOP ;何もしない
H25D NOP ;何もしない
H25E NOP ;何もしない
H25F NOP ;何もしない
;****************************************************************
ORG_260 ORG 0x260
;1相 初期励磁
H260 BSF PORTA,0 ;PORTA,0bit 出力ON
H261 GOTO H270 ;1相励磁プログラム
;2相 初期励磁
H262 BSF PORTA,0 ;PORTA,0bit 出力ON
H263 BSF PORTA,1 ;PORTA,0bit 出力ON
H264 GOTO H270 ;2相励磁プログラム
H265 ;何もしない
H266 ;何もしない
H267 ;何もしない
H268 ;何もしない
H269 ;何もしない
H26A ;何もしない
H26B ;何もしない
H26C ;何もしない
H26D ;何もしない
H26E ;何もしない
H26F ;何もしない
ORG_270 ORG 0x270 ;RB0/INT外部割込みのみ有効にする(1相、2相励磁プログラム)
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H270 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H271 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H272 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ(割り込み待ち)(1相、2相励磁用)
H273 CLRWDT ;ウォッチドッグタイマのリセット
H274 BTFSS GPR20,Step_memory ;STEP入力状態が1なら次の命令をスキップする
H275 GOTO H273 ;入力待ちへ戻る(割り込み待ちへ戻る)
H276 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H277 GOTO H27E ;STEPの立ち上がりが発生した時にDIRが1だった時
;STEPの立ち上がりが発生した時にDIRが0だった時
H278 RLF PORTA,1 ;左へ1ビットシフト PORTAへ上書き
H279 BTFSS PORTA,4 ;PORTA4ビットが1なら次の命令をスキップ
H27A GOTO H283 ;STEP信号OFF待ちベクタへ
H27B BCF PORTA,4 ;PORTA4ビットをクリア
H27C BSF PORTA,0 ;PORTA0ビットをセット
H27D GOTO H283 ;STEP信号OFF待ちベクタへ
;STEPの立ち上がりが発生した時にDIRが1だった時
H27E RRF PORTA,1 ;右へ1ビットシフト PORTAへ上書き
H27F BTFSS STATUS,C ;STATUS,Cビットが1なら次の命令をスキップ
H280 GOTO H283 ;STEP信号OFF待ちベクタへ
H281 BSF PORTA,3 ;PORTA3ビットをセット
H282 GOTO H283 ;STEP信号OFF待ちベクタへ
;STEP信号OFF待ち
H283 CLRWDT ;ウォッチドックタイマのリセット
H284 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H285 GOTO H283 ;STEP入力が1の時は、0に戻り待ちへ戻る
H286 BCF GPR20,Step_memory ;STEP入力状態が1だったフラグオフ
H287 GOTO H270 ;割込み開始へ戻る(1相、2相励磁用)
H288 NOP ;何もしない
H289 NOP ;何もしない
H28A NOP ;何もしない
H28B NOP ;何もしない
H28C NOP ;何もしない
H28D NOP ;何もしない
H28E NOP ;何もしない
H28F NOP ;何もしない
;モーターの励磁モード (MODE)
;0000 0000:1相励磁
;0000 0001:2相励磁
;0000 0010:1?2相励磁
;0000 0100:PWMステップ
;2019年10月11日
;CNCの動作速度
;200分割のPWMの時の最速の移動速度の計算
;0.001秒のパルス幅がMACH3から出せる最速だとしたら
;一秒間に 1000パルスの半分で 500パルス出るとしたら
;一回転40000パルスにすると
;一回転に80秒いることになる
;ちょっと遅すぎる気がした
;PICは 8,000,000Hzになっていて
;1usパルスは 4000クロックON 4000クロックOFFのことで
;十分拾えるはず
;一パルス入った時に その位置まで じわーっと動いていけば 良さそうな気がした
;4000クロックの間に その位置まで行けるのか わからなくなった
;割り込みを使わずに ループで入力待ちの方がわかりやすいかもしれない気がしてきた
;PORTAの設定
;
;17 RA0/AN0 TTL A出力
;18 RA1/AN1 TTL /A出力
;1 RA2/AN2/CVref/Vref- TTL B出力
;2 RA3/AN3/Vref+/C1out TTL /B出力
;3 RA4/AN4/T0CK1/C2out ST 空き 0出力
;4 RA5/MCLR*/Vpp ST +5Vに直結 リセット入力
;15 RA6/OSC2/CLK0 ST (内部周波数)/4Hzのモニター出力
;16 RA7/OSC1/CLK1 ST/CMOS 空き 0出力
;モーター ユニポーラ
;励磁方式
;1相励磁(ユニポーラモーターでのフルステップ駆動) 6線モーター
;2相励磁(バイポーラモーターでのフルステップ駆動) 4線モーター
;1?2相励磁(ハーフステップ駆動)
;PWMステップ駆動
;励磁の順序 A,/A,B,/B
;分岐の方法
;BTFSC ;レジスタの指定したビットが0なら次の命令をスキップ
;BTFSS ;レジスタの指定したビットが1なら次の命令をスキップ
;DECFSZ ;レジスタ値を1減算し,値が0なら次の命令をスキップ
;INCFSZ ;レジスタ値を1加算し,値が0なら次の命令をスキップ
;1-2相 初期励磁
ORG_290 ORG 0x290
H290 BSF PORTA,0 ;PORTA,0bit 出力ON
H291 GOTO H2A0 ;1-2相励磁プログラム
H292 ;何もしない
H293 ;何もしない
H294 ;何もしない
H295 ;何もしない
H296 ;何もしない
H297 ;何もしない
H298 ;何もしない
H299 ;何もしない
H29A ;何もしない
H29B ;何もしない
H29C ;何もしない
H29D ;何もしない
H29E ;何もしない
H29F ;何もしない
ORG_2A0 ORG 0x2A0 ;割込み開始 (1-2相用)
H2A0 CLRWDT ;ウォッチドッグタイマのリセット
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H2A1 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H2A2 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H2A3 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ (1-2相用)
H2A4 CLRWDT ;ウォッチドッグタイマのリセット 割込み待ち開始
H2A5 BTFSS GPR20,Step_memory ;STEP入力状態が1なら次の命令をスキップする(1-2相励磁用)
H2A6 GOTO H2A4 ;入力待ちループへ戻る(1-2相励磁用)
H2A7 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H2A8 GOTO H2B4 ;STEPの立ち上がりが発生した時にDIRが1だった時
;正転
H2A9 CLRF PCLATH
H2AA MOVLW D'1'
H2AB ADDWF STEP,1
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H2AC MOVF STEP,0 ;DATA2
H2AD XORLW D'8';DATA1
H2AE BTFSS STATUS,Z
H2AF GOTO H2C0;8以外だったら ステップ更新完了
;8と同じだったら
H2B0 MOVLW D'0'
H2B1 MOVWF STEP ;WをSTEPへ格納 バンク0指定
H2B2 GOTO H2C0;ステップ更新完了
H2B3 NOP
ORG_2B4 ORG 0x2B4
H2B4 CLRF PCLATH
;逆転
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H2B5 MOVF STEP,0 ;DATA2
;H2B6 XORWF D'0',0;DATA1
H2B6 BTFSS STATUS,Z ;1だったら次をスキップ
H2B7 GOTO H2BC ;0以外だったら
H2B8 GOTO H2B9 ;0と同じだったら
;逆転したら実機だけエラーになるのはこれかもしれない
;H2B5 MOVF STEP になっていた ,0を書いてなかった
;1-2相も実機だと逆転しなくなった
;シュミレーションでは動いてる
;前に動いたことがあった気がして
;戻せるかもしれないような そのまま進めていったほうがいいような
;結果00だったら
H2B9 MOVLW D'7'
H2BA MOVWF STEP ;WをSTEPへ格納 バンク0指定
H2BB GOTO H2C0;ステップ更新完了
;結果00以外だったら
H2BC MOVLW D'1'
H2BD SUBWF STEP,1
H2BE GOTO H2C0;ステップ更新完了
H2BF NOP
;1-2相励磁 I/O割り込み発生後、ステップ値の変更後に出力の更新
ORG_2C0 ORG 0x2C0
;プログラムカウンタを変更してジャンプ
H2C0 MOVLW B'00000010'
H2C1 MOVWF PCLATH
H2C2 MOVF STEP,0
H2C3 ADDWF PCL,1
H2C4 GOTO H2D0 ;0
H2C5 GOTO H2D4 ;1
H2C6 GOTO H2D8 ;2
H2C7 GOTO H2DC ;3
H2C8 GOTO H2E0 ;4
H2C9 GOTO H2E4 ;5
H2CA GOTO H2E8 ;6
H2CB GOTO H2EC ;7
H2CC NOP ;進むほうに脱調がかかってる
H2CD NOP
H2CE NOP ;PWMステップの前に1?2相が動かなくなってる
H2CF NOP ;ビットでCASEから データでCASEに変更したとき
;動かなくなったときとか調子の悪いときは
;一個前のバージョンに戻すとよさそう
;次のバージョンで修正すると
;前のバージョンも 修正が必要になった時
;次のバージョンが完成しても アドレスの全変更が必要になる
ORG_2D0 ORG 0x2D0
;STEP0
H2D0 CLRF PCLATH
H2D1 MOVLW B'00000001' ; /B,B,/A,A
H2D2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2D3 GOTO H2F0 ;
;STEP1
H2D4 CLRF PCLATH
H2D5 MOVLW B'00000011' ; /B,B,/A,A
H2D6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2D7 GOTO H2F0 ;
;STEP2
H2D8 CLRF PCLATH
H2D9 MOVLW B'00000010' ; /B,B,/A,A
H2DA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2DB GOTO H2F0 ;
;STEP3
H2DC CLRF PCLATH
H2DD MOVLW B'00000110' ; /B,B,/A,A
H2DE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2DF GOTO H2F0 ;
;STEP4
H2E0 CLRF PCLATH
H2E1 MOVLW B'00000100' ; /B,B,/A,A
H2E2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2E3 GOTO H2F0 ;
;STEP5
H2E4 CLRF PCLATH
H2E5 MOVLW B'00001100' ; /B,B,/A,A
H2E6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2E7 GOTO H2F0 ;
;STEP6
H2E8 CLRF PCLATH
H2E9 MOVLW B'00001000' ; /B,B,/A,A
H2EA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2EB GOTO H2F0 ;
;STEP7
H2EC CLRF PCLATH
H2ED MOVLW B'00001001' ; /B,B,/A,A
H2EE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H2EF GOTO H2F0 ;
ORG_2F0 ORG 0x2F0 ;入力が0だったら、フラグを消して戻る
H2F0 CLRWDT ;ウォッチドックタイマのリセット
H2F1 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H2F2 GOTO H2F0 ;STEP入力が1の時は、0に戻り待ちへ戻る
H2F3 BCF GPR20,Step_memory ;前の入力状態が1だったフラグオフ
H2F4 GOTO H2A0 ;割込み開始へ戻る
H2F5 NOP ;何もしない
H2F6 NOP ;何もしない
H2F7 NOP ;何もしない
H2F8 NOP ;何もしない
H2F9 NOP ;何もしない
H2FA NOP ;何もしない
H2FB NOP ;何もしない
H2FC NOP ;何もしない
H2FD NOP ;何もしない
H2FE NOP ;何もしない
H2FF NOP ;何もしない
;PWMステップ用
;****************************************************************
;PWMステップ 初期励磁
ORG_300 ORG 0x300
H300 CLRF PCLATH
;H301 BSF PORTA,0 ;PORTA,0bit 出力ON
;H302 MOVLW B'00001000'
;H303 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
;PWMステップのステップ値
;H304 MOVLW D'2'
;H305 MOVWF PSTEP
H301 NOP
H302 NOP
H303 NOP
H304 NOP
H305 NOP
H306 BCF GPR21,PWM_ACTION ;STEP変更可:0 PWM動作中:1
;ステップとPWMステップを合わせた値
H307 MOVLW H'00'
H308 MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H309 GOTO H310 ;PWMステッププログラム
H30A NOP ;何もしない
H30B NOP ;何もしない
H30C NOP ;何もしない
H30D NOP ;何もしない
H30E NOP ;何もしない
H30F NOP ;何もしない
ORG_310 ORG 0x310 ;割込み開始 (PWMステップ用)
H310 CLRWDT ;ウォッチドッグタイマのリセット
H311 CLRF PCLATH
;割り込みを有効にする RB0/INT外部割り込みのみ有効にする
;INTCON:割り込み制御レジスタ(アドレス0BHから8BH,10BHから18BH DS30487C-19ページ)
;----- INTCON Bits --------------------------------------------------------
;GIE 7bit1 1全てのマスクされてない割り込みを許可 0全ての割り込みは無効
;PEIE 6bit0 1全てのマスクされていない周辺割り込みを有効 0全ての周辺割り込みを無効
;TMR0IE 5bit0 TMR0オーバーフロー割り込み 1有効 0無効
;INTE 4bit1 RB0/INT外部割り込み 1有効 0無効
;RBIE 3bit0 RBポート変化割り込み 1有効 0無効
;TMR0IF 2bit0 TMR0レジスタのオーバーフロー(ソフトウェアでクリアする必要がある)
; 1した 0しませんでした
;INTF 1bit0 RB0/INT外部割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0発生しませんでした
;RBIF 0bit0 RBポートの変化割り込み(ソフトウェアでクリアする必要がある)
; 1発生した 0変化なし
H312 MOVLW B'10010000' ;8ビットリテラルをWレジスタへ格納
H313 MOVWF INTCON ;Wレジスタからデータを移動します。
;割り込み動作中
;入力信号の立ち上がりから、2μs-2.5μsの位置を読み込んで記録する
;パルス信号は5μsほどの長さに設定しておくこと。
;****************************************************************
H314 CLRF PCLATH ;ピンポーン 割り込みからの突入
;入力待ちループ開始 (PWMステップ用)
H315 CLRWDT ;ウォッチドッグタイマのリセット 割込み待ち開始
H316 BTFSC GPR20,Step_memory ;STEP入力状態が0なら次の命令をスキップする
H317 GOTO H330 ;割り込み発生 ステップ値の更新
;タイマーの確認とPWM出力の更新のみ
;****************************************************************
;TMR1のカウントアップとコンペア使ってPWMを作る
;タイマー1のカウントアップが発生したら自動的にカウント値が0に戻る。
;その時にタイマーの初期値を再セットする。
;しばらくうごかすとタイマーが止まったような動きになる
;タイマー停止中に割り込みがかかって リセットがうまくいってないのかもしれない
;入力の割り込みを禁止にしたらいいかもしれない
;どこで割り込みがかかってもうまくリセットできるようにしたい
;タイマーの初期値をセットした後にふらぐのリセットがよさそう
;タイマー1がオーバーフローしているか確認する 1のときスキップ
H318 BTFSS PIR1,0 ;TMR1IF 1:オーバーフロー発生 0:オーバーフローしませんでした
;タイマー1カウントアップ未発生時、コンペアが発生しているか確認する
H319 GOTO H321 ;オーバーフロー未発生
;オーバーフロー発生
H31A MOVF T1INIL,0 ;T1INILをWへ格納
H31B MOVWF TMR1L ;WをTMR1Lへ格納
H31C MOVF T1INIH,0 ;T1INIHをWへ格納
H31D MOVWF TMR1H ;TMR1Hへ格納
H31E BCF PIR1,0 ;TMR1IF オーバーフロー発生フラグクリア
;PAPWMの1になっているビットのところを出力ON
H31F MOVF PAPWM,0 ;WレジスタにPAPWMを格納
;いずれかのビットが1なら1
H320 IORWF PORTA,1 ; 論理和 W OR f → W か f へ格納
;
H321 MOVF CCPR1H,0 ;WレジスタにCCPR1Hの値を代入
H322 SUBWF TMR1H,0 ;TMR1H-Wを計算しWへ格納、B_REG>=WのときキャリービットC=1となる
H323 BTFSS STATUS,C ;キャリー発生のときジャンプ
H324 GOTO H315 ;コンペア未発生
H325 MOVF CCPR1L,0 ;WレジスタにCCPR1Lの値を代入
H326 SUBWF TMR1L,0 ;TMR1L-Wを計算しWへ格納、B_REG>=WのときキャリービットC=1となる
H327 BTFSS STATUS,C ;キャリー発生のときジャンプ
H328 GOTO H315 ;コンペア未発生
;CCP1CON:キャプチャ/コンペア/PWM制御レジスタ1(アドレス17H DS30487-81ページ)
;----- CCP1CON Bits -------------------------------------------------------
; CCPR1Lレジスタの下位に連結されるビット
; 10ビットとしてPWMのパルス幅を指定する時用。
; 今回は0固定
;CCP1X 5bit0
;CCP1Y 4bit0
;0000 CCPモジュール未使用(リセット)
;0100 キャプチャモード(立ち下がりエッジ)
;0101 キャプチャモード(立ち上がりエッジ)
;0110 キャプチャモード(立ち上がりエッジ4回毎)
;0111 キャプチャモード(立ち上がりエッジ16回毎)
;1000 コンペアモード(出力セット CCP1IFセット)
;1001 コンペアモード(出力クリア CCP1IFセット)
;1010 コンペアモード(出力変化なし CCP1IFセット) これにする
;1011 コンペアモード(出力変化なし CCP1IFセット TMR1リセット A/Dが有効なら開始)
;11xx PWMモード
;CCP1M3 3bit1
;CCP1M2 2bit0
;CCP1M1 1bit1
;CCP1M0 0bit0
;マスクデータの作成 出力をオフにしたいところだけ0になる
H329 COMF PAPWM,0 ;fの0,1反転→Wかfへ格納
H32A ANDWF PORTA,1 ; 論理積 W AND f → W か f へ格納
H32B BSF PIR1,2 ;CCP1IF コンペアの一致発生フラグセット
H32C GOTO H315
H32D NOP ;何もしない
H32E NOP ;何もしない
H32F NOP ;何もしない
ORG_330 ORG 0x330 ;入力からの割り込み発生 (PWMステップ用)
H330 CLRWDT
H331 CLRF PCLATH
H332 CLRF STEP
H333 CLRF PSTEP
H334 BTFSC GPR20,Dir_memory ;DIR入力状態が0なら次の命令をスキップする
H335 GOTO H340 ;STEPの立ち上がりが発生した時にDIRが1だった時 逆転
;正転
H336 MOVLW D'1'
H337 ADDWF COMBINED_STEPS,1
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H338 MOVF COMBINED_STEPS,0 ;DATA2
H339 XORLW D'24';DATA1
H33A BTFSS STATUS,Z
H33B GOTO H350;24以外だったら ステップ更新完了
;24と同じだったら
H33C MOVLW D'00'
H33D MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H33E GOTO H350;ステップ更新完了
H33F NOP
;逆転
ORG_340 ORG 0x340
;H440 GOTO H700 ;エラーテスト ここまで動作した
;逆転
;[IF DATA1 = DATA2 THEN GOTO XXX ]
H340 MOVF COMBINED_STEPS,0 ;DATA2
;H2B6 XORWF D'0',0;DATA1
H341 BTFSS STATUS,Z ;1だったら次をスキップ
H342 GOTO H347 ;0以外だったら
H343 GOTO H344 ;0と同じだったら
;結果00だったら
H344 MOVLW D'23'
H345 MOVWF COMBINED_STEPS ;WをCOMBINED_STEPSへ格納 バンク0指定
H346 GOTO H350;ステップ更新完了
;結果00以外だったら
H347 MOVLW D'1'
H348 SUBWF COMBINED_STEPS,1
H349 GOTO H350;ステップ更新完了
H34A NOP
H34B NOP ;何もしない
H34C NOP ;何もしない
H34D NOP ;何もしない
H34E NOP ;何もしない
H34F NOP ;何もしない
ORG_350 ORG 0x350
;プログラムカウンタを変更してジャンプ 正転
H350 MOVLW B'00000011'
H351 MOVWF PCLATH
H352 MOVF COMBINED_STEPS,0
H353 ADDWF PCL,1
H354 GOTO H390 ;0
H355 GOTO H396 ;1
H356 GOTO H39C ;2
H357 GOTO H3A2 ;3
H358 GOTO H3A8 ;4
H359 GOTO H3AE ;5
H35A GOTO H3B4 ;6
H35B GOTO H3BA ;7
H35C GOTO H3C0 ;8
H35D GOTO H3C6 ;9
H35E GOTO H3CC ;10
H35F GOTO H3D2 ;11
H360 GOTO H3D8 ;12
H361 GOTO H3DE ;13
H362 GOTO H3E4 ;14
H363 GOTO H3EA ;15
H364 GOTO H3F0 ;16
H365 GOTO H3F6 ;17
H366 GOTO H3FC ;18
H367 GOTO H402 ;19
H368 GOTO H408 ;20
H369 GOTO H40E ;21
H36A GOTO H414 ;22
H36B GOTO H41A ;23
H36C NOP ;何もしない
H36D NOP ;何もしない
H36E NOP ;何もしない
H36F NOP ;何もしない
ORG_390 ORG 0x390
;0 STEP0 PSTEP0
H390 CLRF PCLATH
H391 MOVLW D'0'
H392 MOVWF STEP
H393 MOVLW D'0'
H394 MOVWF PSTEP
H395 GOTO H4B0
;1 STEP0 PSTEP
H396 CLRF PCLATH
H397 MOVLW D'0'
H398 MOVWF STEP
H399 MOVLW D'1'
H39A MOVWF PSTEP
H39B GOTO H4B0
;2 STEP0 PSTEP2
H39C CLRF PCLATH
H39D MOVLW D'0'
H39E MOVWF STEP
H39F MOVLW D'2'
H3A0 MOVWF PSTEP
H3A1 GOTO H4B0
;3 STEP1 PSTEP2
H3A2 CLRF PCLATH
H3A3 MOVLW D'1'
H3A4 MOVWF STEP
H3A5 MOVLW D'3'
H3A6 MOVWF PSTEP
H3A7 GOTO H4B0
;4 STEP1 PSTEP1
H3A8 CLRF PCLATH
H3A9 MOVLW D'1'
H3AA MOVWF STEP
H3AB MOVLW D'2'
H3AC MOVWF PSTEP
H3AD GOTO H4B0
;5 STEP1 PSTEP0
H3AE CLRF PCLATH
H3AF MOVLW D'1'
H3B0 MOVWF STEP
H3B1 MOVLW D'1'
H3B2 MOVWF PSTEP
H3B3 GOTO H4B0
;6 STEP2 PSTEP0
H3B4 CLRF PCLATH
H3B5 MOVLW D'2'
H3B6 MOVWF STEP
H3B7 MOVLW D'0'
H3B8 MOVWF PSTEP
H3B9 GOTO H4B0
;7 STEP2 PSTEP1
H3BA CLRF PCLATH
H3BB MOVLW D'2'
H3BC MOVWF STEP
H3BD MOVLW D'1'
H3BE MOVWF PSTEP
H3BF GOTO H4B0
;8 STEP2 PSTEP2
H3C0 CLRF PCLATH
H3C1 MOVLW D'2'
H3C2 MOVWF STEP
H3C3 MOVLW D'2'
H3C4 MOVWF PSTEP
H3C5 GOTO H4B0
;9 STEP3 PSTEP2
H3C6 CLRF PCLATH
H3C7 MOVLW D'3'
H3C8 MOVWF STEP
H3C9 MOVLW D'3'
H3CA MOVWF PSTEP
H3CB GOTO H4B0
;10 STEP3 PSTEP1
H3CC CLRF PCLATH
H3CD MOVLW D'3'
H3CE MOVWF STEP
H3CF MOVLW D'2'
H3D0 MOVWF PSTEP
H3D1 GOTO H4B0
;11 STEP3 PSTEP0
H3D2 CLRF PCLATH
H3D3 MOVLW D'3'
H3D4 MOVWF STEP
H3D5 MOVLW D'1'
H3D6 MOVWF PSTEP
H3D7 GOTO H4B0
;12 STEP4 PSTEP0
H3D8 CLRF PCLATH
H3D9 MOVLW D'4'
H3DA MOVWF STEP
H3DB MOVLW D'0'
H3DC MOVWF PSTEP
H3DD GOTO H4B0
;13 STEP4 PSTEP1
H3DE CLRF PCLATH
H3DF MOVLW D'4'
H3E0 MOVWF STEP
H3E1 MOVLW D'1'
H3E2 MOVWF PSTEP
H3E3 GOTO H4B0
;14 STEP4 PSTEP2
H3E4 CLRF PCLATH
H3E5 MOVLW D'4'
H3E6 MOVWF STEP
H3E7 MOVLW D'2'
H3E8 MOVWF PSTEP
H3E9 GOTO H4B0
;15 STEP5 PSTEP2
H3EA CLRF PCLATH
H3EB MOVLW D'5'
H3EC MOVWF STEP
H3ED MOVLW D'3'
H3EE MOVWF PSTEP
H3EF GOTO H4B0
;16 STEP5 PSTEP1
H3F0 CLRF PCLATH
H3F1 MOVLW D'5'
H3F2 MOVWF STEP
H3F3 MOVLW D'2'
H3F4 MOVWF PSTEP
H3F5 GOTO H4B0
;17 STEP5 PSTEP0
H3F6 CLRF PCLATH
H3F7 MOVLW D'5'
H3F8 MOVWF STEP
H3F9 MOVLW D'1'
H3FA MOVWF PSTEP
H3FB GOTO H4B0
;18 STEP6 PSTEP0
H3FC CLRF PCLATH
H3FD MOVLW D'6'
H3FE MOVWF STEP
H3FF MOVLW D'0'
H400 MOVWF PSTEP
H401 GOTO H4B0
;19 STEP6 PSTEP1
H402 CLRF PCLATH
H403 MOVLW D'6'
H404 MOVWF STEP
H405 MOVLW D'1'
H406 MOVWF PSTEP
H407 GOTO H4B0
;20 STEP6 PSTEP2
H408 CLRF PCLATH
H409 MOVLW D'6'
H40A MOVWF STEP
H40B MOVLW D'2'
H40C MOVWF PSTEP
H40D GOTO H4B0
;21 STEP7 PSTEP2
H40E CLRF PCLATH
H40F MOVLW D'7'
H410 MOVWF STEP
H411 MOVLW D'3'
H412 MOVWF PSTEP
H413 GOTO H4B0
;22 STEP7 PSTEP1
H414 CLRF PCLATH
H415 MOVLW D'7'
H416 MOVWF STEP
H417 MOVLW D'2'
H418 MOVWF PSTEP
H419 GOTO H4B0
;23 STEP7 PSTEP0
H41A CLRF PCLATH
H41B MOVLW D'7'
H41C MOVWF STEP
H41D MOVLW D'1'
H41E MOVWF PSTEP
H41F GOTO H4B0
;PWMステップ励磁 I/O割り込み発生後、ステップ値の変更後に出力の更新
ORG_4B0 ORG 0x4B0
;プログラムカウンタを変更してジャンプ
H4B0 MOVLW B'00000100'
H4B1 MOVWF PCLATH
H4B2 MOVF STEP,0
H4B3 ADDWF PCL,1
H4B4 GOTO H4C0 ;0
H4B5 GOTO H4C6 ;1
H4B6 GOTO H4CC ;2
H4B7 GOTO H4D2 ;3
H4B8 GOTO H4D8 ;4
H4B9 GOTO H4DE ;5
H4BA GOTO H4E4 ;6
H4BB GOTO H4EA ;7
H4BC NOP ;何もしない
H4BD NOP ;何もしない
H4BE NOP ;何もしない
H4BF NOP ;何もしない
;STEP番号から出力先を選択する
ORG_4C0 ORG 0x4C0
;STEP0
H4C0 CLRF PCLATH
H4C1 MOVLW B'00000001' ; /B,B,/A,A
H4C2 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4C3 MOVLW B'00000010' ; /B,B,/A,A
H4C4 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4C5 GOTO H4F0 ;PWMステップ値の選択
;STEP1
H4C6 CLRF PCLATH
H4C7 MOVLW B'00000010' ; /B,B,/A,A
H4C8 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4C9 MOVLW B'00000001' ; /B,B,/A,A
H4CA MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4CB GOTO H4F0 ;PWMステップ値の選択
;STEP2
H4CC CLRF PCLATH
H4CD MOVLW B'00000010' ; /B,B,/A,A
H4CE MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4CF MOVLW B'00000100' ; /B,B,/A,A
H4D0 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4D1 GOTO H4F0 ;PWMステップ値の選択
;STEP3
H4D2 CLRF PCLATH
H4D3 MOVLW B'00000100' ; /B,B,/A,A
H4D4 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4D5 MOVLW B'00000010' ; /B,B,/A,A
H4D6 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4D7 GOTO H4F0 ;PWMステップ値の選択
;STEP4
H4D8 CLRF PCLATH
H4D9 MOVLW B'00000100' ; /B,B,/A,A
H4DA MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4DB MOVLW B'00001000' ; /B,B,/A,A
H4DC MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4DD GOTO H4F0 ;PWMステップ値の選択
;STEP5
H4DE CLRF PCLATH
H4DF MOVLW B'00001000' ; /B,B,/A,A
H4E0 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4E1 MOVLW B'00000100' ; /B,B,/A,A
H4E2 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4E3 GOTO H4F0 ;PWMステップ値の選択
;STEP6
H4E4 CLRF PCLATH
H4E5 MOVLW B'00001000' ; /B,B,/A,A
H4E6 MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4E7 MOVLW B'00000001' ; /B,B,/A,A
H4E8 MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4E9 GOTO H4F0 ;PWMステップ値の選択
;STEP7
H4EA CLRF PCLATH
H4EB MOVLW B'00000001' ; /B,B,/A,A
H4EC MOVWF PORTA ;WをPORTAへ格納 バンク0指定
H4ED MOVLW B'00001000' ; /B,B,/A,A
H4EE MOVWF PAPWM ;WをPAPWMへ格納 バンク0指定
H4EF GOTO H4F0 ;PWMステップ値の選択
ORG_4F0 ORG 0x4F0
;プログラムカウンタを変更してジャンプ
H4F0 MOVLW B'00000100'
H4F1 MOVWF PCLATH
H4F2 MOVF PSTEP,0
H4F3 ADDWF PCL,1
H4F4 GOTO H500 ;0
H4F5 GOTO H506 ;1
H4F6 GOTO H50C ;2
H4F7 GOTO H512 ;3
H4F8 NOP ;何もしない
H4F9 NOP ;何もしない
H4FA NOP ;何もしない
H4FB NOP ;何もしない
H4FC NOP ;何もしない
H4FD NOP ;何もしない
H4FE NOP ;何もしない
H4FF NOP ;何もしない
;PWMステップ値の選択
ORG_500 ORG 0x500
;PSTEP0
;65535-200=65335
;1111 1111 0011 0111
H500 CLRF PCLATH
H501 MOVLW B'00110111' ;8ビットリテラルをWレジスタへ格納
H502 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H503 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H504 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H505 GOTO H520
;PSTEP1
;65535-200+66=65401
;1111 1111 0111 1001
H506 CLRF PCLATH
H507 MOVLW B'01111001' ;8ビットリテラルをWレジスタへ格納
H508 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H509 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H50A MOVWF CCPR1H ;Wレジスタからデータを移動します。
H50B GOTO H520
;PSTEP2
;65535-200+66+66=65467
;1111 1111 1011 1011
H50C CLRF PCLATH
H50D MOVLW B'10111011' ;8ビットリテラルをWレジスタへ格納
H50E MOVWF CCPR1L ;Wレジスタからデータを移動します。
H50F MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H510 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H511 GOTO H520
;PSTEP3
;65535-200+66+66+66=65533
;1111 1111 1111 1101
H512 CLRF PCLATH
H513 MOVLW B'11111101' ;8ビットリテラルをWレジスタへ格納
H514 MOVWF CCPR1L ;Wレジスタからデータを移動します。
H515 MOVLW B'11111111' ;8ビットリテラルをWレジスタへ格納
H516 MOVWF CCPR1H ;Wレジスタからデータを移動します。
H517 GOTO H520
H518 NOP
H519 NOP
H51A NOP
H51B NOP
H51C NOP
H51D NOP
H51E NOP
H51F NOP
ORG_520 ORG 0x520 ;入力が0だったら、フラグを消して戻る
H520 CLRWDT ;ウォッチドックタイマのリセット
H521 BTFSC PORTB,0 ;STEP入力状態が0なら次の命令をスキップする
H522 GOTO H520 ;STEP入力が1の時は、0に戻り待ちへ戻る
H523 BCF GPR20,Step_memory ;前の入力状態が1だったフラグオフ
H524 GOTO H310 ;割込み開始へ戻る
H525 NOP
H526 NOP
H527 NOP
H528 NOP
H529 NOP
H52A NOP
H52B NOP
H52C NOP
H52D NOP
H52E NOP
H52F NOP
;****************************************************************
;音 ド
;****************************************************************
ORG_H600 ORG 0x600 ;モーターから音を出す
H600 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H601 MOVLW H'00' ;H'00'をWへ格納
H602 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H603 MOVLW H'00' ;H'00'をWへ格納
H604 MOVWF MSL ;WをMSLへ格納 バンク0指定
H605 CALL H750 ;WAIT 0.1秒 音出力前の間
H606 CALL H750 ;WAIT 0.1秒 音出力前の間
H607 CALL H750 ;WAIT 0.1秒 音出力前の間
H608 CALL H750 ;WAIT 0.1秒 音出力前の間
H609 CALL H750 ;WAIT 0.1秒 音出力前の間
H60A GOTO H610 ;音のループへ
H60B NOP ;何もしない
H60C NOP ;何もしない
H60D NOP ;何もしない
H60E NOP ;何もしない
H60F NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H610 CLRWDT ;ウォッチドックタイマのリセット
H611 BSF PORTA,0 ;PORTA,0bit 出力ON
;H612 BCF PORTA,1 ;PORTA,1bit 出力OFF
H612 NOP
; 200 20 11 1
H613 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H614 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H615 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H616 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H617 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H618 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H619 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61A CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61B CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H61C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61D CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H61E CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 441Hz
H61F NOP ;何もしない
;H620 NOP
;H621 NOP
;H622 NOP
;H623 NOP ;7ド 436.5Hz
;H624 NOP
;H625 NOP
;H626 NOP
;H627 NOP
;H628 NOP ;7ド 432Hz
;H61F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H620 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H621 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 低め
H620 BCF PORTA,0 ;PORTA,0bit 出力OFF
;H621 BSF PORTA,1 ;PORTA,1bit 出力ON
H621 NOP
H622 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H623 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H624 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H625 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H626 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H627 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H628 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H629 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62A CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H62B CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H62D CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 441Hz
H62E NOP ;何もしない
;H633 NOP
;H634 NOP
;H635 NOP
;H636 NOP
;H63C NOP
;H63D NOP
;H63E NOP
;H63F NOP
;H640 NOP
;H61F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H620 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H621 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ド 低め
H62F MOVF MSL,0 ;音カウンタMSLをWへ格納
H630 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H631 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H632 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H633 GOTO H610 ;音ループへ戻る
H634 MOVF MSH,0 ;音カウンタMSHをWへ格納
H635 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H636 MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H637 BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H638 GOTO H610 ;音のループへ戻る
H639 BCF PORTA,0 ;PORTA,0bit 出力OFF
H63A BCF PORTA,1 ;PORTA,1bit 出力OFF
H63B RETURN
H63C NOP ;何もしない
H63D NOP ;何もしない
H63E NOP ;何もしない
H63F NOP ;何もしない
;****************************************************************
;音 レ
;****************************************************************
ORG_H650 ORG 0x650 ;モーターから音を出す
H650 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H651 MOVLW H'00' ;H'00'をWへ格納
H652 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H653 MOVLW H'00' ;H'00'をWへ格納
H654 MOVWF MSL ;WをMSLへ格納 バンク0指定
H655 CALL H750 ;WAIT 0.1秒 音出力前の間
H656 CALL H750 ;WAIT 0.1秒 音出力前の間
H657 CALL H750 ;WAIT 0.1秒 音出力前の間
H658 CALL H750 ;WAIT 0.1秒 音出力前の間
H659 CALL H750 ;WAIT 0.1秒 音出力前の間
H65A GOTO H660 ;音のループへ
H65B NOP ;何もしない
H65C NOP ;何もしない
H65D NOP ;何もしない
H65E NOP ;何もしない
H65F NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H660 CLRWDT ;ウォッチドックタイマのリセット
H661 BSF PORTA,0 ;PORTA,0bit 出力ON
;H662 BCF PORTA,1 ;PORTA,1bit 出力OFF
H662 NOP
H663 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H664 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H665 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H666 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H667 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H668 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H669 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H66A CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H66B CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ 437Hz
H66B NOP ;何もしない
H66C NOP ;何もしない
H66D NOP ;何もしない
H66E NOP ;何もしない
H66F NOP ;何もしない
H670 NOP ;何もしない
H671 NOP ;何もしない
H672 NOP ;何もしない
H673 NOP ;何もしない
H674 NOP ;何もしない
H675 NOP ;何もしない
H676 NOP ;何もしない
H677 NOP ;何もしない
H678 NOP ;何もしない
;H679 NOP
;H67A NOP
;H67B NOP ;437Hz
H679 BCF PORTA,0 ;PORTA,0bit 出力OFF
;H67A BSF PORTA,1 ;PORTA,1bit 出力ON
H67A NOP
H67B CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H67C CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H67D CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H67E CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H67F CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H680 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H681 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H682 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
;H676 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7レ
H683 NOP ;何もしない
H684 NOP ;何もしない
H685 NOP ;何もしない
H686 NOP ;何もしない
H687 NOP ;何もしない
H688 NOP ;何もしない
H689 NOP ;何もしない
H68A NOP ;何もしない
H68B NOP ;何もしない
H68C NOP ;何もしない
H68D NOP ;何もしない
H68E NOP ;何もしない
H68F NOP ;何もしない
H690 NOP ;何もしない
;H694 NOP
;H695 NOP
;H696 NOP
H691 MOVF MSL,0 ;音カウンタMSLをWへ格納
H692 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H693 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H694 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H695 GOTO H660 ;音ループへ戻る
H696 MOVF MSH,0 ;音カウンタMSHをWへ格納
H697 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H698 MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H699 BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H69A GOTO H660 ;音のループへ戻る
H69B BCF PORTA,0 ;PORTA,0bit 出力OFF
H69C BCF PORTA,1 ;PORTA,1bit 出力OFF
;H69D GOTO H660
H69D RETURN
H69E NOP ;何もしない
H69F NOP ;何もしない
;****************************************************************
;音 ミ
;****************************************************************
ORG_H6A0 ORG 0x6A0 ;モーターから音を出す
H6A0 CLRWDT ;ウォッチドックタイマのリセット
;モーターから音を出すときの音の長さカウンタH
H6A1 MOVLW H'00' ;H'00'をWへ格納
H6A2 MOVWF MSH ;WをMSHへ格納 バンク0指定
;モーターから音を出すときの音の長さカウンタL
H6A3 MOVLW H'00' ;H'00'をWへ格納
H6A4 MOVWF MSL ;WをMSLへ格納 バンク0指定
H6A5 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A6 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A7 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A8 CALL H750 ;WAIT 0.1秒 音出力前の間
H6A9 CALL H750 ;WAIT 0.1秒 音出力前の間
H6AA GOTO H6B0 ;音のループへ
H6AB NOP ;何もしない
H6AC NOP ;何もしない
H6AD NOP ;何もしない
H6AE NOP ;何もしない
H6AF NOP ;何もしない
;音のループ
;A7 ド 4186.009Hz 1/4186.009=0.0002388/2=0.0001194
;A7 レ 4698.636Hz 1/4698.636=0.0002128/2=0.0001064
;A7 ミ 5274.041Hz 1/5274.041=0.0001896/2=0.0000948
H6B0 CLRWDT ;ウォッチドックタイマのリセット
H6B1 BSF PORTA,0 ;PORTA,0bit 出力ON
;H6B2 BCF PORTA,1 ;PORTA,1bit 出力OFF
H6B2 NOP
H6B3 CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H6B4 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B5 CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H6B6 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B7 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B8 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6B9 NOP
H6BA BCF PORTA,0 ;PORTA,0bit 出力OFF
;H6BB BSF PORTA,1 ;PORTA,1bit 出力ON
H6BB NOP
H6BC CALL H710 ;WAIT 0.0001s 100μs 0.1ms
H6BD CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6BE CALL H700 ;WAIT 0.00001s 10μs 0.01ms 7ミ ぐらい
H6BF CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C0 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C1 CALL H700 ;WAIT 0.00001s 10μs 0.01ms
H6C2 NOP
H6C3 MOVF MSL,0 ;音カウンタMSLをWへ格納
H6C4 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H6C5 MOVWF MSL ;WレジスタからMSLレジスタへデータを移動します
H6C6 BTFSS STATUS,C ;Cが1なら次の命令をスキップする バンクx指定
H6C7 GOTO H6B0 ;音ループへ戻る
H6C8 MOVF MSH,0 ;音カウンタMSHをWへ格納
H6C9 ADDLW H'1' ;Wへ1加算 オーバーフローした場合はCフラグに1がセットされる
H6CA MOVWF MSH ;WレジスタからMSHレジスタへデータを移動します
H6CB BTFSS MSH,3 ;カウンタが2048なら次の命令をスキップする
H6CC GOTO H6B0 ;音のループへ戻る
H6CD BCF PORTA,0 ;PORTA,0bit 出力OFF
H6CE BCF PORTA,1 ;PORTA,1bit 出力OFF
H6CF RETURN
;***************************
; Wait Subroutines
;***************************
;メインクロック 8MHz
;1命令サイクル4クロック
;1MHz 1,000,000Hz 1 / 1,000,000Hz = 0.000001秒
;8MHz 8,000,000Hz 1 / 8,000,000Hz = 0.000000125秒
;8MHzの時、1命令4クロック長さ 0.000000125秒*4クロック = 0.0000005秒
;0.0000005s / 500ns / 0.5μs / 0.0005ms
;****************************************************************
;20回繰り返すと (18)
;0.00001s / 10μs / 0.01ms
;****************************************************************
ORG_700 ORG 0x700
H700 CLRWDT ;ウォッチドックタイマのリセット 1
H701 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H702 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H703 MOVLW B'00000010' ;2 1
H704 MOVWF WAIT70 ;WをWAITへ格納 バンク0指定 1
H705 NOP ;NOP 1
H706 DECFSZ WAIT70,1 ; 結果が0だと次の命令がNOPになる 1(2)
H707 GOTO H705 ; 2 (NOP) 1
H708 RETURN ; 2 1 = 10 2 = 14 3 = 18 (2*4=8+10=18)
H709 NOP
H70A NOP
H70B NOP
H70C NOP
H70D NOP
H70E NOP
H70F NOP
;****************************************************************
;200回繰り返すと (198)
;0.0001s / 100μs / 0.1ms
;****************************************************************
ORG_710 ORG 0x710
H710 CLRWDT ;ウォッチドックタイマのリセット 1
H711 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H712 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H713 MOVLW B'01000111' ;47 1
H714 MOVWF WAIT71 ;WをWAITへ格納 バンク0指定 1
H715 NOP ;NOP 1
H716 DECFSZ WAIT71,1 ; 結果が0だと次の命令がNOPになる 1(2)
H717 GOTO H715 ; 2 (NOP) 1
H718 RETURN ; 2 1 = 10 2 = 14 3 = 18 (47*4=188+10=198)
H719 NOP
H71A NOP
H71B NOP
H71C NOP
H71D NOP
H71E NOP
H71F NOP
;****************************************************************
;2000回繰り返すと (1998)
;0.001s / 1000μs / 1ms
;****************************************************************
ORG_720 ORG 0x720
H720 CLRWDT ;ウォッチドックタイマのリセット 1
H721 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H722 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H723 MOVLW B'11111000' ;248 1
H724 MOVWF WAIT72 ;WをWAITへ格納 バンク0指定 1
H725 NOP ;NOP 1
H726 NOP ;NOP 1
H727 NOP ;NOP 1
H728 NOP ;NOP 1
H729 NOP ;NOP 1
H72A DECFSZ WAIT72,1 ; 結果が0だと次の命令がNOPになる 1(2)
H72B GOTO H725 ; 2 (NOP) 1
H72C RETURN ; 2 1 = 14 2 = 22 3 = 30 (248*8=1984+14=1998)
H72D NOP
H72E NOP
H72F NOP
;****************************************************************
;20000回繰り返すと 200 * 100 = 20000 (19998)
;0.01s / 10ms
;****************************************************************
ORG_730 ORG 0x730
H730 CLRWDT ;ウォッチドックタイマのリセット 1
H731 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H732 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H733 MOVLW B'11000010' ;194 1
H734 MOVWF WAIT73 ;WをWAITへ格納 バンク0指定 1
H735 CALL H700 ;20
H736 CALL H700 ;20
H737 CALL H700 ;20
H738 CALL H700 ;20
H739 CALL H700 ;20
H73A DECFSZ WAIT73,1 ; 結果が0だと次の命令がNOPになる 1(2)
H73B GOTO H735 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (194*103=19982 + 6 = 19988)
H73C NOP
H73D NOP
H73E NOP
H73F NOP
H740 NOP
H741 NOP
H742 NOP
H743 NOP
H744 NOP
H745 NOP
H746 RETURN ; 2
H747 NOP
H748 NOP
H749 NOP
H74A NOP
H74B NOP
H74C NOP
H74D NOP
H74E NOP
H74F NOP
;****************************************************************
;200000 (199998)
;0.1秒
;****************************************************************
ORG_750 ORG 0x750
H750 CLRWDT ;ウォッチドックタイマのリセット 1
H751 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H752 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H753 MOVLW B'11000111' ;199 1
H754 MOVWF WAIT74 ;WをWAITへ格納 バンク0指定 1
H755 CALL H710 ;200
H756 CALL H710 ;200
H757 CALL H710 ;200
H758 CALL H710 ;200
H759 CALL H710 ;200
H75A DECFSZ WAIT74,1 ; 結果が0だと次の命令がNOPになる 1(2)
H75B GOTO H755 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (199*1003=199597 + 6 = 199603)
;199998 - 199603 = 395
H75C CLRWDT ;ウォッチドックタイマのリセット 1
H75D BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H75E BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H75F MOVLW B'01011111' ;95 1
H760 MOVWF WAIT75 ;WをWAITへ格納 バンク0指定 1
H761 NOP ;NOP 1
H762 DECFSZ WAIT75,1 ; 結果が0だと次の命令がNOPになる 1(2)
H763 GOTO H761 ; 2 (NOP) 1
H764 NOP
H765 NOP
H766 NOP
H767 NOP
H768 NOP
H769 RETURN ; 2 1 = 10 2 = 14 3 = 18 (95*4=380+10=390)
H76A NOP
H76B NOP
H76C NOP
H76D NOP
H76E NOP
H76F NOP
;****************************************************************
;2000000 (1999998)
;1秒
;****************************************************************
ORG_770 ORG 0x770
H770 CLRWDT ;ウォッチドックタイマのリセット 1
H771 BCF STATUS,RP0 ;0 バンク0を選択する バンクxより 1
H772 BCF STATUS,RP1 ;0 バンク0を選択する バンクxより 1
H773 MOVLW B'11000111' ;199 1
H774 MOVWF WAIT76 ;WをWAITへ格納 バンク0指定 1
H775 CALL H720 ;2000
H776 CALL H720 ;2000
H777 CALL H720 ;2000
H778 CALL H720 ;2000
H779 CALL H720 ;2000
H77A DECFSZ WAIT76,1 ; 結果が0だと次の命令がNOPになる 1(2)
H77B GOTO H775 ; 2 (NOP) 1
;1 = 109 2 = 212 3 = 315 (199*10003=1990597 + 6 = 1990603)
;1999998 - 1990603 = 9395
H77C CALL H720 ;2000
H77D CALL H720 ;2000
H77E CALL H720 ;2000
H77F CALL H720 ;2000
;9395 - 8000 = 1395
H780 CALL H710 ;200
H781 CALL H710 ;200
H782 CALL H710 ;200
H783 CALL H710 ;200
H784 CALL H710 ;200
H785 CALL H710 ;200
;1395 - 1200 = 195
H786 CALL H700 ;20
H787 CALL H700 ;20
H788 CALL H700 ;20
H789 CALL H700 ;20
H78A CALL H700 ;20
H78B CALL H700 ;20
H78C CALL H700 ;20
H78D CALL H700 ;20
H78E CALL H700 ;20
;195 - 180 = 15
H78F NOP
H790 NOP
H791 NOP
H792 NOP
H793 NOP
H794 NOP
H795 NOP
H796 NOP
H797 NOP
H798 NOP
H799 NOP
H79A NOP
H79B NOP
H79C NOP
H79D NOP
H79E RETURN ; 2
H79F NOP
;****************************************************************
;プログラムメモリ ページ1 0800-0FFF 2kB
;****************************************************************
;****************************************************************
;プログラムメモリ ページ2 1000-17FF 2kB
;****************************************************************
;PIC16F88 プログラムメモリ未実装
;****************************************************************
;プログラムメモリ ページ3 1800-1FFF 2kB
;****************************************************************
;PIC16F88 プログラムメモリ未実装
END