;**************************************************************** ; ; ステッピングモータ駆動プログラム ; 2008年11月06日 ;**************************************************************** ; 12F629でコントロール。内蔵4MHz ; 12F683用に作成したプログラムを移植した。 ;  ; GP3(4番ピン)がDIR入力 ; INT(5番ピン)がCLK入力 ; GP0(7番ピン)がX出力 ; GP1(6番ピン)がX出力 ; GP4(3番ピン)がX出力 ; GP5(2番ピン)がX出力 ; ; 単純な1-2相励磁。2相を励磁するときでも両方を100%励磁する。 ; X、XY、Y、Y-X、-X、-X-Y、-Y、-YX、の順に励磁するのが正転 ; ; 受け取るデータは方向データが先に確定してから、駆動パルスが来る前提になっている。 ; 全く同時なら良いが、方向データが駆動パルスより遅れて確定すると宜しくない。 ; ; PICの出力が1で駆動、0で非駆動 ; PICが5V駆動で、最近のFETならゲート直結でOK。 ; トランジスタならベース電流を検討して接続。 ; ;**************************************************** ;コンフィグレーションワードの設定 ;MPLABに対する、呪い的な宣言が続く所。しばらく使わないと忘れていて一番面倒。 LIST P=PIC12F629 ;「STATUSと書いてあったら何番地の事」とか、そんなデータをMPLABに覚えさせておく。 ;為に呪い的なファイルを指定しておく。 INCLUDE "P12F629.INC" ;MCLREピンはIOで使う。パワーアップタイマはON、ウォッチドッグタイマはOFF ;内蔵発振器を使って関係するピンはIOで使う。等と宣言しておく。 __CONFIG _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT ; ;**************************************************************** ;各定数をメモリ空間上に配置 W_TEMP EQU H'20' ;割り込み退避先 STATUS_TEMP EQU H'21' ;割り込み退避先 PCLATH_TEMP EQU H'22' ;割り込み退避先 OUTDATA EQU H'24' ;出力パターン TEMP EQU H'25' ;テンポラリな作業用 ;**************************************************************** ;ここからプログラム ;4番地から割込の事を書かなければ成らないので、ここは手短に書いておく ORG 0 ;0番地から以下の内容を書き込め goto START ;STARTへ飛ぶ ;**************************************************************** ;割り込み処理の部分 ORG 4 ;4番地から以下の内容を書き込む ;すなわち、割り込みが発生したら一律にここに飛んでくる INTRPT bcf INTCON,7 ;全割込を一時的に停止させておく。 movwf W_TEMP ;Wレジスタを退避 movf STATUS,w ; movwf STATUS_TEMP ;STATUSレジスタを退避 movf PCLATH,W ; movwf PCLATH_TEMP ;PCLATHレジスタを退避 call DIR call OUT movf PCLATH_TEMP,w ; movwf PCLATH ;PCLATHレジスタを戻す movf STATUS_TEMP,w ; movwf STATUS ;STATUSレジスタを戻す swapf W_TEMP,f swapf W_TEMP,w ;Wレジスタを戻す bcf INTCON,1 ;GP2/INT割込をリセットする retfie ;全割込を許可して元に戻る ;**************************************************************** ;初期設定の部分。1回しか通らない。 START BCF STATUS,RP0 MOVLW B'11111111' ;デジタルモード用の1をセット MOVWF CMCON ;コンパレータ不使用 MOVLW B'10010000' ; MOVWF INTCON ;set INT BSF STATUS,RP0 ;STATUSレジスタのRP0ビットを1に MOVLW B'00001100' ;2,3を入力に、他は出力にセット MOVWF TRISIO ; call 3FFh movf OSCCAL BCF STATUS,RP0 ;Bank0(Page0)に戻る movlw B'00000011' ;X相だけ励磁するパターン movwf OUTDATA ;初期値としてOUTDATAに転送しておく call OUT ;X相だけ励磁するパターンで、初期値を出力しておく。 ;**************************************************************** ;クロック入力の割込が入るまで、グルグル回って待つだけ。 MAIN nop goto MAIN ;**************************************************************** ;以下はサブルーチン ;**************************************************************** ;GPIO3番ピンの状態をチェックして、回転方向を決めてOUTDATAを1bit回転させる。 DIR btfsc GPIO,3 ;GPIO3をチェックして goto CW ;1ならCWへ飛ぶ CCW movf OUTDATA,w ;0ならここへ飛んでくる movwf TEMP rlf TEMP ;同じデータをあらかじめ回しておいてキャリーを発生させて rlf OUTDATA ;その状態で必要なデータを回すとキャリーも回ってくる。 goto DIR_END ;CWを実行せずに終わりに飛ぶ CW movf OUTDATA,w movwf TEMP rrf TEMP rrf OUTDATA DIR_END return ;**************************************************************** ;OUTDATAの状態に応じて、GPIOの4個のピンに駆動データを出力する。 ;1-2相励磁なので、OUTDATAの隣り合った2bitのorで1相を励磁することになる。 OUT X btfss OUTDATA,0 ;If outdata0 is 1 skip next bcf GPIO,0 btfsc OUTDATA,0 ;If outdata1 is 0 skip next bsf GPIO,0 btfsc OUTDATA,1 ;If outdata1 is 0 skip next bsf GPIO,0 Y btfss OUTDATA,2 ;If outdata2 is 1 skip next bcf GPIO,1 btfsc OUTDATA,2 ;If outdata2 is 0 skip next bsf GPIO,1 btfsc OUTDATA,3 ;If outdata3 is 0 skip next bsf GPIO,1 _X btfss OUTDATA,4 ;If outdata4 is 1 skip next bcf GPIO,4 btfsc OUTDATA,4 ;If outdata4 is 0 skip next bsf GPIO,4 btfsc OUTDATA,5 ;If outdata5 is 0 skip next bsf GPIO,4 _Y btfss OUTDATA,6 ;If outdata6 is 1 skip next bcf GPIO,5 btfsc OUTDATA,6 ;If outdata6 is 0 skip next bsf GPIO,5 btfsc OUTDATA,7 ;If outdata7 is 0 skip next bsf GPIO,5 return ;**************************************************************** END