第15週プログラム 
■まず、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