■まず、PIC16F877でステッピングモータを動かすプログラム
;16F877でステッピングモータ
;*********************************************
LIST P=PIC16F877 ;
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
;LVPがF877で新たに出現!
;(このプログラムでは関係なさそうなのになんでかこれを
; 設定しないと動作しない)
INCLUDE "P16f877.inc" ;標準ヘッダ定義ファイル
;のインクルード
;*********************************************
CNT EQU 020H ;出力パターン用カウンタ
WTEMP EQU 021H ;Wレジスタ待避
STTEMP EQU 022H ;STATUSレジスタ待避
INTTMCT EQU 023H ;割り込みタイマ設定値
TIMCNT EQU 024H ;タイマ用カウンタ
;***********************
; メインルーチン
;***********************
ORG 0 ;Reset Start
GOTO MAIN
ORG 04H ;Int
GOTO INTR
MAIN ;Initialize
BSF STATUS,RP0 ;バンク1へ切替
BCF INTCON,GIE ;割り込み禁止
MOVLW 07H ;
MOVWF OPTION_REG ;内部クロック、プリスケーラ1:256
MOVLW 01H
MOVWF TRISA ;ポートAをRA0入力、他は出力モードに設定
CLRF TRISB ;ポートBを出力モードに設定
MOVLW 80H
MOVWF TRISC ;ポートCをRC7入力、他は出力モードに設定
CLRF TRISD ;ポートDを出力モードに設定
CLRF TRISE ;ポートEを出力モードに設定
BCF STATUS,RP0 ;バンク0に戻す
MOVLW B'10010000' ;初期出力
MOVWF PORTD
MOVLW 0H ;COUNTER初期出力
MOVWF CNT
MOVLW 03CH ;タイマ値ロード
MOVWF TMR0 ;約500Hz
MOVWF INTTMCT ;タイマ値記憶
BSF INTCON,T0IE ;TMR0オーバーフロー割り込み発生許可
BSF INTCON,GIE ;割り込み許可
LOOP1
CALL TIM02
CALL TIM02
GOTO LOOP1
;***********************
;サブルーチン
;***********************
TABLE
ADDWF PCL,F
RETLW B'10010000'
RETLW B'00010000'
RETLW B'00110000'
RETLW B'00100000'
RETLW B'01100000'
RETLW B'01000000'
RETLW B'11000000'
RETLW B'10000000'
TIM02 ;約0.2mSECタイマ
MOVLW 0FFH
MOVWF TIMCNT
TIMLP NOP
DECFSZ TIMCNT,F
GOTO TIMLP
RETURN
;*********************************************************
;割り込み処理
INTR
BCF INTCON,T0IF ;割り込みフラグクリア
MOVF INTTMCT,W ;タイマ値ロード
SUBLW 0F5H ;◎タイマ値FB(5KHz)まではINCしていく
BTFSS STATUS,Z ; タイマ値と比較して同じならスキップ
INCF INTTMCT,F ; 違うなら(大きいなら)INC
MOVF INTTMCT,W
MOVWF TMR0 ;
MOVWF WTEMP ;レジスタ待避
SWAPF STATUS,W
MOVWF STTEMP
FWD ;正転カウント処理
MOVF CNT,W
SUBLW 07H
BTFSC STATUS,2
GOTO SET0 ;カウンタ値 7 なら 0 に
INCF CNT,F
GOTO INCED
SET0 MOVLW 0H
MOVWF CNT
INCED
PATTERN
MOVF CNT,W
CALL TABLE
MOVWF PORTD
SWAPF STTEMP,W ;レジスタ復帰
MOVWF STATUS
SWAPF WTEMP,F
SWAPF WTEMP,W
RETFIE
;*********************************************************
END
■次に別個にPIC16F877でLCD表示するプログラム
;LCD表示器 SC1602BS*B
;*********************************************
LIST P=PIC16F877 ;
INCLUDE "P16f877.inc" ;標準ヘッダ定義ファイル
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
;*********************************
TIMCNT EQU 020H ;タイマ用カウンタ
TIM5CNT EQU 021H
TIM1CNT EQU 022H
LCDDT EQU 023H ;LCD表示データ格納
LCDINST EQU 024H ;LCDインストラクション格納
ORG 0 ;Reset Start
;***********************
; メインルーチン
;***********************
MAIN ;Initialize
;ポート初期化
BSF STATUS,RP0 ;バンク1へ切替
MOVLW 07H
MOVWF ADCON1 ;A/D用ピンを全てデジタルI/Oに
;◎ADCON1レジスタは初期値は全てアナログ端子となっている
MOVLW 01H
MOVWF TRISA ;とりあえずポートAをRA0入力、他は出力モードに
CLRF TRISB ;とりあえずポートBを出力モードに設定
CLRF TRISC ;とりあえずポートCを出力モードに設定
CLRF TRISD ;とりあえずポートDを出力モードに設定
CLRF TRISE ;とりあえずポートEを出力モードに設定
BCF STATUS,RP0 ;バンク0に戻す
;LCD初期化
CALL TIM5 ;まず15msec以上待ち
CALL TIM5
CALL TIM5
CALL TIM5
MOVLW 030H
MOVWF PORTB
BCF PORTE,1 ;R/WをWに
BCF PORTE,2 ;RSをインストラクションに
BSF PORTE,0 ;E
NOP
BCF PORTE,0
CALL TIM5 ;4.1msec以上待ち
MOVLW 030H
MOVWF PORTB
BCF PORTE,1 ;R/WをWに
BCF PORTE,2 ;RSをインストラクションに
BSF PORTE,0 ;E
NOP
BCF PORTE,0
CALL TIM02 ;100μsec以上待ち
CALL TIM02
MOVLW 030H
MOVWF PORTB
BCF PORTE,1 ;R/WをWに
BCF PORTE,2 ;RSをインストラクションに
BSF PORTE,0 ;E
NOP
BCF PORTE,0
CALL TIM02
CALL TIM02
MOVLW 038H ;Function Set 8ビット 2行 5×7ドット
CALL LCDCMD
MOVLW 01H ;表示クリア
CALL LCDCMD
MOVLW 06H ;エントリーモード
CALL LCDCMD
MOVLW 0CH ;表示ON
CALL LCDCMD
;文字書き込み(いくらなんでもちょっと能なしすぎるプログラム(^^; )
;Yamatonmbo Kimura
;Kimura と Yamatombo を交互に表示
CHW
CALL LCDCLR ;表示クリア
CALL TOMBO
CALL LCD2L ;2行目へ
CALL KIMURA
CALL TIM1S
CALL LCDCLR
CALL KIMURA
CALL LCD2L
CALL TOMBO
CALL TIM1S
GOTO CHW
;***********************
;サブルーチン
;***********************
TOMBO ;表示Yamatombo
MOVLW 'Y'
CALL LCDDTW
MOVLW 'a'
CALL LCDDTW
MOVLW 'm'
CALL LCDDTW
MOVLW 'a'
CALL LCDDTW
MOVLW 't'
CALL LCDDTW
MOVLW 'o'
CALL LCDDTW
MOVLW 'm'
CALL LCDDTW
MOVLW 'b'
CALL LCDDTW
MOVLW 'o'
CALL LCDDTW
RETURN
KIMURA
MOVLW 'K' ;表示Kimura
CALL LCDDTW
MOVLW 'i'
CALL LCDDTW
MOVLW 'm'
CALL LCDDTW
MOVLW 'u'
CALL LCDDTW
MOVLW 'r'
CALL LCDDTW
MOVLW 'a'
CALL LCDDTW
RETURN
LCDDTW ;LCDデータ書き込み
;Wに書き込まれたデータ(1文字)を表示
MOVWF PORTB
BCF PORTE,1 ;R/WをW
BSF PORTE,2 ;RSをデータに
BSF PORTE,0 ;E
NOP
BCF PORTE,0
CALL LCDBUSY ;BUSYチェック
RETURN
LCDCMD ;LCDインストラクション書き込み
;Wレジスタに書き込まれたコマンドをLCDへ
MOVWF PORTB
BCF PORTE,1 ;R/WをW
BCF PORTE,2 ;RSをインストラクションに
BSF PORTE,0 ;E
NOP
BCF PORTE,0
CALL LCDBUSY ;BUSYチェック
RETURN
LCDCLR ;LCD表示クリア
MOVLW 01H
CALL LCDCMD
RETURN
LCD2L ;2行目へ
;◎データシートによると1行目と2行目はアドレスが連続していないで
;2行目の第1文字目は40(H)番地らしい
;(b'1*******'が表示アドレス書き込み *******を1000000として2行目先頭指令)
MOVLW 0C0H
CALL LCDCMD
RETURN
LCDBUSY ;LCD BUSYチェック
;やっかいなことにいちいちPORTBを入力に変えて
;さらにOPTIONレジスタで弱プルアップに設定
BSF STATUS,RP0 ;バンク1へ切替
MOVLW 0FFH ;ポートBを入力モードに設定
MOVWF TRISB
BCF STATUS,RP0 ;バンク0に戻す
BCF PORTE,2 ;RSをインストラクションに
BSF PORTE,1 ;R/WをR
BSF PORTE,0 ;E
NOP
BCF PORTE,0
MOVF PORTB,W
MOVWF LCDINST
BTFSC LCDINST,7 ;BUSYフラグチェック
GOTO LCDBUSY
BCF PORTE,1 ;R/WをWに戻しておく
BSF STATUS,RP0 ;バンク1へ切替
CLRF TRISB ;ポートBを出力モードに設定
BCF STATUS,RP0 ;バンク0に戻す
RETURN
TIM02 ;約0.2mSECタイマ
MOVLW 0FFH
MOVWF TIMCNT
TIMLP NOP
DECFSZ TIMCNT,F
GOTO TIMLP
RETURN
TIM5 ;約5msecタイマ
MOVLW 01AH
MOVWF TIM5CNT
TIM5LP CALL TIM02
DECFSZ TIM5CNT,F
GOTO TIM5LP
RETURN
TIM1S ;約1secタイマ
MOVLW 0C8H
MOVWF TIM1CNT
TIM1SLP CALL TIM5
DECFSZ TIM1CNT,F
GOTO TIM1SLP
RETURN
END