;16F877 USART受送信
;*********************************************
LIST P=PIC16F877 ;
INCLUDE "P16f877.inc" ;標準ヘッダ定義ファイル
__CONFIG _HS_OSC & _PWRTE_ON & _WDT_OFF & _LVP_OFF
;*********************************************
WTEMP EQU 021H ;Wレジスタ待避
INTTMCT EQU 022H ;割り込みタイマ設定値
TIMCNT EQU 023H ;タイマ用カウンタ
TIM2CNT EQU 024H
TIM5CNT EQU 025H
TIM1CNT EQU 026H
LCDDT EQU 027H ;LCD表示データ格納
LCDINST EQU 028H ;LCDインストラクション格納
LOOPCNT EQU 029H ;受信データクリア用カウンタ
SENDCNT EQU 02AH ;送信文字数
TBPOINT EQU 02BH ;テーブル処理ポインタ
;***********************
; メインルーチン
;***********************
ORG 0 ;Reset Start
;*********************************************************
;初期処理
BSF STATUS,RP0 ;バンク1へ切替
BCF INTCON,GIE ;割り込み禁止
MOVLW 07H
MOVWF ADCON1 ;A/D割り当て用ピンはすべてデジタル
MOVLW 01H
MOVWF TRISA ;とりあえずポートAをRA0入力、他は出力モード設定
CLRF TRISB ;とりあえずポートBを出力モードに設定
CLRF TRISD ;とりあえずポートDを出力モードに設定
CLRF TRISE ;とりあえずポートEを出力モードに設定
MOVLW 080H
MOVWF TRISC ;ポートC RC7を入力、他を出力モードに設定(*2001-1-7 下記に追記)
MOVLW 024H ;8ビット、送信イネーブル、非同期
;高速ボーレート選択
MOVWF TXSTA ;
MOVLW 081H ;SPBRG=129(9600)
MOVWF SPBRG
BCF STATUS,RP0 ;バンク0に戻す
MOVLW 090H ;シリアルピン、8ビット、連続受信
MOVWF RCSTA
;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
CALL LCDCLR ;表示クリア
MAIN
MOVLW 0A0H ;バッファ先頭
MOVWF FSR ;ポインタ初期化
MOVLW 32 ;LCD表示は32文字表示
MOVWF LOOPCNT
SPLOOP MOVLW 020H ;SP文字
MOVWF INDF
INCF FSR,F
DECFSZ LOOPCNT,F
GOTO SPLOOP
MOVLW 0A0H ;バッファ先頭
MOVWF FSR ;ポインタ初期化
MOVLW 32 ;LCD表示は32文字表示
MOVWF LOOPCNT
;受信
RCV BTFSS PIR1,RCIF ;受信レジスタチェック
GOTO RCV
;エラーチェック
BTFSC RCSTA,FERR ;フレーミングエラーチェック
GOTO ERR1
BTFSC RCSTA,OERR ;オーバーランエラーチェック
GOTO ERR2
;データ格納
MOVF RCREG,W ;RCREG読み込み
MOVWF WTEMP ;W 待避
SUBLW 0DH ;CRチェック
BTFSC STATUS,Z
GOTO DPLY ;CRならLCD表示へ(CRは表示しない)
MOVF WTEMP,W ;W 復帰
MOVWF INDF ;INDIRECT REG 書き込み(ポインタ処理)
CKBUFF INCF FSR,F ;ポインタ+1
DECFSZ LOOPCNT,F
GOTO RCV
GOTO DPLY
SPLP MOVLW 020H ;SP文字
MOVWF INDF
INCF FSR,F
DECFSZ LOOPCNT,F
GOTO SPLP
;エラー処理
ERR1 ;フレーミングエラー
MOVF RCREG,W ;RCREG読み込みで更新(FERRリセット)
MOVLW '.' ;エラー文字
MOVWF INDF
GOTO CKBUFF
ERR2 ;オーバーランエラー
BCF RCSTA,CREN ;CRENクリアでリセット
BSF RCSTA,CREN ;戻しておく
MOVLW '.' ;エラー文字
MOVWF INDF
GOTO CKBUFF
;LCD表示
DPLY CALL LCDCLR ;LCD表示クリア
MOVLW 0A0H ;表示データ用汎用レジスタ先頭
MOVWF FSR
MOVLW 010H ;1行分16バイト
MOVWF LOOPCNT
LCDLOOP MOVF INDF,W
CALL LCDDTW ;LCDデータ書き込み
INCF FSR,F
DECFSZ LOOPCNT,F
GOTO LCDLOOP
MOVLW 010H ;2行目分16バイト
MOVWF LOOPCNT
CALL LCD2L ;2行目先頭へ
LCDLP2 MOVF INDF,W
CALL LCDDTW
INCF FSR,F
DECFSZ LOOPCNT,F
GOTO LCDLP2
;アンサー
SND ;テーブル上の文字を順次送信
CLRF TBPOINT
MOVLW 4
MOVWF SENDCNT ;送信文字数カウンタ(4文字)
LPSND MOVF TBPOINT,W
CALL TABLE
CALL SEND
INCF TBPOINT,F
DECFSZ SENDCNT,F
GOTO LPSND
GOTO MAIN
TABLE ADDWF PCL,F
RETLW 'O'
RETLW 'K'
RETLW '!'
RETLW 0DH ;CR
;***********************
;サブルーチン
;***********************
;***************************************************
;送信
SEND
MOVWF WTEMP ;待避
BSF STATUS,RP0 ;BANK1
LPSEND BTFSS TXSTA,TRMT ;TSR空チェック
GOTO LPSEND
BCF STATUS,RP0 ;BANK0
MOVF WTEMP,W
MOVWF TXREG
RETURN
;***************************************************
;LCDデータ書き込み
LCDDTW ;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
;************************************************************
;タイマ
TIM20 ;約20μSECタイマ
MOVLW 012H
MOVWF TIMCNT
TIMLP
DECFSZ TIMCNT,F
GOTO TIMLP
RETURN
TIM02 RETURN ;デバッグ用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;約0.2mSECタイマ
MOVLW 0FFH
MOVWF TIM2CNT
TIM2LP NOP
DECFSZ TIM2CNT,F
GOTO TIM2LP
RETURN
TIM5 RETURN ;デバッグ用!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
;約5msecタイマ
MOVLW 01AH
MOVWF TIM5CNT
TIM5LP CALL TIM02
DECFSZ TIM5CNT,F
GOTO TIM5LP
RETURN
;*********************************************************
END