; Copyright 2005 Yasuhiro Kanzaki ; Filename: f877090.asm リスト9-1 * list p=16f877A ; プロセッサを定義する #include ; インクルード・ファイルを読み込む __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF &_CPD_OFF ;***** 変数の定義域 b2a_tmp equ 20h count_str equ 21h LCDPORT equ PORTE RS equ 0 RW equ 1 E equ 2 ;********************************************************************** ORG 000h ; リセット時の開始アドレス main ; 初期化ルーチンLCD関連の初期化 bcf STATUS,RP0 ; バンク0を選択 clrf PORTD ; PORTDレジスタをクリアして0とする bsf STATUS,RP0 ; バンク1を選択 clrf TRISD ; ポートDを出力として設定する clrf TRISE ; ポートEを出力として設定する movlw 04h ; ポートA,ポートEの設定 movwf ADCON1 bcf STATUS,RP0 ; バンク0設定 clrf PORTD ; ポートDの出力をクリア clrf PORTE ; ポートBの出力をクリア ;タイマ0の初期化 bsf STATUS,RP0 ; バンク1を選択 bcf OPTION_REG,T0CS ; タイマ0 プリスケーラ256 bcf OPTION_REG,PSA ; プリスケーラはタイマ0 bcf STATUS,RP0 ; 以上で初期設定 完了 call inilcd8 ; LCDドライバの初期化 ;表示処理 movlw 01h ; LCDのクリア call cmdwrt ; コマンド書き込み movlw 80h+4dh ; ACは4dhにセット call cmdwrt ; コマンド DDRAMアドレスをセット2行目を指示 movlw 'V' ; V プログラム・バージョンのV call dtawrt ; データ書き出し movlw 01h ; バージョン・ナンバをセット call b2asub ; HEX表示で書き出し movlw 80h+0h ; アドレス セット  call cmdwrt ; 入力アドレスを1行目の先頭 movf STATUS,w ; ステータス・レジスタの内容を call b2asub ; HEX2桁で表示 movlw 80h+05h ; アドレス セット call cmdwrt ; コマンド書き込み movf PIR2,w ;  call b2asub ; ; リスト9-1 にColumn 1の文字列表示処理を追加した部分   movlw 80h+40h ;  call cmdwrt movlw tbl2-tbl1 call lcdstr1 ;******  追加分の終わり balop1 nop ; goto balop1 ; ;タイマ処理サブルーチン0.1ms Wレジスタに01ms単位の計数値をセット MAX 255 tm01 bcf INTCON,T0IF ; sublw 0FFh ; movwf TMR0 ; stmlp btfss INTCON,T0IF ; goto stmlp ; bcf INTCON,T0IF ; return ; ;LCDドライバーの初期化8ビットポート inilcd8 movlw d'150' ; call tm01 ; 電源立ち上げ後15ms以上確保するため movlw 30h ; コマンド 30hを出力 call cmdwrtw ; コマンド 30hを出力 movlw d'41' ; call tm01 ; 4.1msの時間待ち movlw 30h ; call cmdwrtw ; コマンド 30hを出力 movlw 1 ; call tm01 ; 100μsの待ち movlw 30h ; コマンド 30hを出力 call cmdwrtw ; movlw 1 ; call tm01 ; 100μsの待ち movlw b'00111000' ; 初期化 8ビット 2行 call cmdwrt movlw b'00001111' ; display on/off on call cmdwrt movlw b'00000001' ; clears display call cmdwrt movlw b'00000110' ; entry mode set call cmdwrt return ; busy check LCDドライバの処理中のチェック bsychk bsf STATUS,RP0 ; バンク1を設定 comf TRISD,f ; ポートDを入力に設定のコード bcf STATUS,RP0 ; バンク0 を設定 bsf LCDPORT,RW ; コマンド読み取りなのでRでHにする bsyrp: bcf LCDPORT,RS ; コマンドなのでLでクリアする bcf LCDPORT,E ; ループで戻った時Lにするため bsf LCDPORT,E ; E信号をHにする nop ; 時間待ち btfsc PORTD,7 ; Busy フラグのチェック goto bsyrp ; フラグがオンの時繰り返す bcf LCDPORT,E ; E信号をLにする bcf LCDPORT,RW ; WRITEに変更 bsf STATUS,RP0 ; バンク1を設定 clrf TRISD ; ポートDを出力に設定 bcf STATUS,RP0 ; バンク0 を設定 return ; 一バイトデータの値をHEX表示でLCDに書き込む b2asub movwf b2a_tmp ; 表示データを保存 swapf b2a_tmp,w ; 上下のニブルを入れ替え call bacon ; 下位4ビットを 文字コードに変換 call dtawrt ; 変換されたデータをLCDに出力 movf b2a_tmp,w ; 保存したデータをWレジスタにセット call bacon ; 下位4ビットを 文字コードに変換 call dtawrt ; 変換されたデータをLCDに出力 return ; ;コマンド書き込みルーチン cmdwrt call bsychk ; Busyフラグがオフまで待つ cmdwrtw bcf LCDPORT,RW ; WRITEでL bcf LCDPORT,RS ; コマンドでRSはL movwf PORTD ; ポートDにコマンドを出力 bsf LCDPORT,E ; Eをオン bcf LCDPORT,E ; Eをオフ return ; ; 文字コードをデータとしてLCDに書き込む,文字が表示される dtawrt: call bsychk ; Busyフラグがオフまで待つ bcf LCDPORT,RW ; WRITEでL bsf LCDPORT,RS ; データでRSはH movwf PORTD ; データを出力 bsf LCDPORT,E ; Eをオン bcf LCDPORT,E ; Eをオフ return ; ; 0からFの4ビットの値を文字コードに変換する bacon andlw 0Fh ; 上位のビットをクリアする addwf PCL,f ;  dt "0123456789ABCDEF" ; dtはこの書式も利用できる ; 文字列の表示サブルーチン  リスト9-1に新たに追加した部分 ; Column・・・1 文字列表示サブルーチン で示したサブルーチン ;  lcdstr1 movwf count_str strlp1 movf count_str,W call str010 andlw 0FFH btfsc STATUS,Z return call dtawrt incf count_str,f ; 本文では,fが抜けています.格納先の指定がないと goto strlp1 ; デフォルトではレジスタに格納され,fと解釈されます str010 addwf PCL,F ; ,fを外して確認してみてください tbl1 dt "LCD TEST Pgm",0h tbl2 dt "debug mode",00h END