;16F877でステッピングモータとLCD同時操作
;*********************************************
LIST P=PIC16F877 ;
INCLUDE "P16f877.inc" ;標準ヘッダ定義ファイル
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
;*********************************************
CNT EQU 020H ;出力パターン用カウンタ
WTEMP EQU 021H ;Wレジスタ待避
STTEMP EQU 022H ;STATUSレジスタ待避
INTTMCT EQU 023H ;割り込みタイマ設定値
TIMCNT EQU 024H ;タイマ用カウンタ
TIM5CNT EQU 025H
TIM1CNT EQU 026H
LCDDT EQU 027H ;LCD表示データ格納
LCDINST EQU 028H ;LCDインストラクション格納
;***********************
; メインルーチン
;***********************
ORG 0 ;Reset Start
GOTO MAIN
ORG 04H ;Int
GOTO INTR
MAIN ;Initialize
BSF STATUS,RP0 ;バンク1へ切替
BCF INTCON,GIE ;割り込み禁止
MOVLW 07H
MOVWF ADCON1 ;A/D用ピンを全てデジタルI/Oに
MOVLW 07H ;
MOVWF OPTION_REG ;内部クロック、プリスケーラ1:256
MOVLW 01H
MOVWF TRISA ;とりあえずポートAをRA0入力、他は出力モード設定
CLRF TRISB ;とりあえずポートBを出力モードに設定
CLRF TRISC ;とりあえずポートCを出力モードに設定
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 ;割り込み許可
;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
;文字書き込み(いくらなんでもちょっと能なしすぎるプログラム(^^; )
;MotorとRun を交互に表示
CHW
CALL LCDCLR ;表示クリア
CALL TOMBO
CALL LCD2L ;2行目へ
CALL KIMURA
CALL TIM1S
CHW2 CALL LCDCLR
CALL KIMURA
CALL LCD2L
CALL TOMBO
CALL TIM1S
GOTO CHW
;***********************
;サブルーチン
;***********************
TOMBO ;表示Motor
MOVLW 'M'
CALL LCDDTW
MOVLW 'o'
CALL LCDDTW
MOVLW 't'
CALL LCDDTW
MOVLW 'o'
CALL LCDDTW
MOVLW 'r'
CALL LCDDTW
RETURN
KIMURA
MOVLW 'R' ;表示Run
CALL LCDDTW
MOVLW 'u'
CALL LCDDTW
MOVLW 'n'
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
;*********************************************************
;割り込み処理
INTR
BCF INTCON,T0IF ;割り込みフラグクリア
MOVWF WTEMP ;レジスタ待避
SWAPF STATUS,W
MOVWF STTEMP
BCF STATUS,RP0 ;バンク0に戻す
;◎メインプログラム中でバンク切り替えをし、かつ割り込みの中で
; STATUSをチェックするので互いに影響を及ぼさないようにここで
; バンク0にしておく
;(復帰についてはレジスタ復帰するので考慮不要)
MOVF INTTMCT,W ;タイマ値ロード
SUBLW 0F5H ;◎タイマ値FB(5KHz)まではINCしていく
BTFSS STATUS,Z ; タイマ値と比較して同じならスキップ
INCF INTTMCT,F ; 違うなら(大きいなら)INC
MOVF INTTMCT,W
MOVWF TMR0 ;
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
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'
;*********************************************************
END