; PIC16F84A ; clock:20MHz ; ; LCDを4ビットで制御 ; ; PICのピン接続 ; RB0 LCD DB4 ; RB1 LCD DB5 ; RB2 LCD DB6 ; RB3 LCD DB7 ; ; RA0 LCD R/W (6:Read/Write) ; RA1 LCD E (5:Enable Signal) ; RA2 LCD RS (4:Register Select) ; ; 使用タイマ(プログラムループ) ; 15mS LCDパワーオンリセット待ち ; 5mS LCD初期化ルーチン ; 1mS LCD初期化ルーチン ; 50uS LCD初期化ルーチン,書き込み待ち ; LIST P=PIC16F84A INCLUDE P16F84A.INC __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF CBLOCK 020h save_st ;STATUSのセーブ save_w ;W-regのセーブ CNT15mS ;15mSカウンタ CNT5mS ;5mSカウンタ CNT1mS ;1mSカウンタ CNT50uS ;50μSカウンタ char ;LCD表示データ ENDC RW EQU 00h ;LCD R/W E EQU 01h ;LCD Enable RS EQU 02h ;LCD Register Select BUSY EQU 03h ;BUSY FLAG (PORTB,3) ; ==================== 初期処理 ===================== org 0 init BSF STATUS,RP0 ;■バンク1に切替え MOVLW 0F8h MOVWF TRISA ;RA0-2は出力 MOVLW 0F0h MOVWF TRISB ;RB0-3は出力 BCF STATUS,RP0 ;■バンク0に切替え CLRF PORTA CLRF PORTB CALL LCD_init ;LCD 初期化 ; ==================== メイン処理 ===================== main CALL LCD_home ;カーソルを1行目の先頭に MOVLW 'H' CALL LCD_write MOVLW 'e' CALL LCD_write MOVLW 'l' CALL LCD_write MOVLW 'l' CALL LCD_write MOVLW 'o' CALL LCD_write MOVLW ',' CALL LCD_write CALL LCD_2line ;カーソルを2行目の先頭に MOVLW 'w' CALL LCD_write MOVLW 'o' CALL LCD_write MOVLW 'r' CALL LCD_write MOVLW 'l' CALL LCD_write MOVLW 'd' CALL LCD_write MOVLW '!' CALL LCD_write CLRF PORTA CLRF PORTB SLEEP GOTO main ;================= LCD表示をクリアする =================== LCD_clear MOVLW 01h CALL LCD_command RETURN ;================= LCDのカーソル位置を先頭に戻す ========= LCD_home MOVLW 02h CALL LCD_command RETURN ;================= LCDのカーソル位置を2行目の先頭に ===== LCD_2line MOVLW 0C0h CALL LCD_command RETURN ;================= LCDのディスプレイをONにする ========= LCD_on MOVLW 0Ch CALL LCD_command RETURN ;================= LCDのディスプレイとカーソルをONにする == LCD_on_cur MOVLW 0Eh CALL LCD_command RETURN ;================= LCDのディスプレイをOFFにする ======= LCD_off MOVLW 08h CALL LCD_command RETURN ;================= LCDにデータを送る ===================== LCD_write MOVWF char CALL LCD_BF_wait ;LCD busy 解除待ち BCF PORTA,RW ;R/W=0(Write) BSF PORTA,RS ;RS=1(Data) MOVLW 0F0h ;PORTBの下位4ビットを ANDWF PORTB,F ; クリア SWAPF char,W ;上位 ANDLW 0Fh ;4ビットを IORWF PORTB,F ;PORTB(3-0)にセット(PORTB(7-4)はそのまま) BSF PORTA,E ;LCDにデータ書き込み NOP BCF PORTA,E MOVLW 0F0h ;PORTBの下位4ビットを ANDWF PORTB,F ; クリア MOVF char,W ;下位 ANDLW 0Fh ;4ビットを IORWF PORTB,F ;PORTB(3-0)にセット(PORTB(7-4)はそのまま) BSF PORTA,E ;LCDにデータ書き込み NOP BCF PORTA,E RETURN ;================= LCDにコマンドを送る =================== LCD_command MOVWF char CALL LCD_BF_wait ;LCD busy 解除待ち BCF PORTA,RW ;R/W=0(Write) BCF PORTA,RS ;RS=0(Command) MOVLW 0F0h ;PORTBの下位4ビットを ANDWF PORTB,F ; クリア SWAPF char,W ;上位 ANDLW 0Fh ;4ビットを IORWF PORTB,F ;PORTB(3-0)にセット(PORTB(7-4)はそのまま) BSF PORTA,E ;LCDにデータ書き込み NOP BCF PORTA,E MOVLW 0F0h ;PORTBの下位4ビットを ANDWF PORTB,F ; クリア MOVF char,W ;下位 ANDLW 0Fh ;4ビットを IORWF PORTB,F ;PORTB(3-0)にセット(PORTB(7-4)はそのまま) BSF PORTA,E ;LCDにデータ書き込み NOP BCF PORTA,E RETURN ;================= LCD Busy 解除待ち ======================== LCD_BF_wait BCF PORTA,E BCF PORTA,RS ;RS=0(Control) BSF PORTA,RW ;R/W=1(Read) Busy Flag read BSF STATUS,RP0 ;■バンク1に切替え MOVLW 0FFh MOVWF TRISB ;RB0-7は入力 BCF STATUS,RP0 ;■バンク0に切替え BSF PORTA,E ;LCD上位4ビット読み込み NOP BTFSS PORTB,BUSY ;LCD Busy ? GOTO LCD_BF_wait1 ; No BCF PORTA,E NOP BSF PORTA,E ;LCD下位4ビット読み飛ばし NOP BCF PORTA,E GOTO LCD_BF_wait LCD_BF_wait1 BSF PORTA,E ;LCD下位4ビット読み飛ばし NOP BCF PORTA,E BSF STATUS,RP0 ;■バンク1に切替え MOVLW 0F0h ;RB0-3は出力 MOVWF TRISB BCF STATUS,RP0 ;■バンク0に切替え RETURN ;================= LCD初期化 ================================ LCD_init CALL wait15ms ;15mS待つ BCF PORTA,RW ;R/W=0 BCF PORTA,RS ;RS=0 BCF PORTA,E ;E=0 MOVLW 0F0h ;PORTBの上位4ビットを ANDWF PORTB,W ;取り出す(変更しないように) IORLW 03h ;下位4ビットに'3'をセット MOVWF PORTB BSF PORTA,E ;ファンクションセット(1回目) NOP BCF PORTA,E CALL wait5ms ;5mS待つ MOVLW 0F0h ;PORTBの上位4ビットを ANDWF PORTB,W ;取り出す(変更しないように) IORLW 03h ;下位4ビットに'3'をセット MOVWF PORTB BSF PORTA,E ;ファンクションセット(2回目) NOP BCF PORTA,E CALL wait5ms ;5mS待つ MOVLW 0F0h ;PORTBの上位4ビットを ANDWF PORTB,W ;取り出す(変更しないように) IORLW 03h ;下位4ビットに'3'をセット MOVWF PORTB BSF PORTA,E ;ファンクションセット(3回目) NOP BCF PORTA,E CALL wait5ms ;5mS待つ MOVLW 0F0h ;PORTBの上位4ビットを ANDWF PORTB,W ;取り出す(変更しないように) IORLW 02h ;4ビットモード MOVWF PORTB ;に BSF PORTA,E ;設定 NOP BCF PORTA,E CALL wait1ms ;1mS待つ MOVLW 028h ;4ビットモード,2行表示,7ドット CALL LCD_command CALL LCD_off ;ディスプレイOFF CALL LCD_clear ;LCDクリア MOVLW 06h ; CALL LCD_command ;カーソルモードセット (Increment) CALL LCD_on ;ディスプレイON,カーソルOFF RETURN ;================= 15mS WAIT ================================ wait15ms MOVLW d'3' MOVWF CNT15mS wait15ms_loop CALL wait5ms DECFSZ CNT15mS,F GOTO wait15ms_loop RETURN ;================= 5mS WAIT ================================= wait5ms MOVLW d'100' MOVWF CNT5mS wait5ms_loop CALL wait50us DECFSZ CNT5mS,F GOTO wait5ms_loop RETURN ;================= 1mS WAIT ================================= wait1ms MOVLW d'20' MOVWF CNT1mS wait1ms_loop CALL wait50us DECFSZ CNT1mS,F GOTO wait1ms_loop RETURN ;================= 50μS WAIT =============================== wait50us ; 1サイクル(4クロック):0.2μS ; 50μS=0.2μS×250サイクル MOVLW d'82' ;1 MOVWF CNT50uS ;1 wait50us_loop DECFSZ CNT50uS,F ;1 GOTO wait50us_loop ;2 RETURN ;2+1 END