;***** I2C_XS_LCD.sub ***************************************************** ; ; PCF8574 I2C IF モジュール使用 LCD 制御サブルーチン (ソフトウエア I2C 版) ; ; (I2CxLcd_Cmd, I2CxLcd_Data, I2CxLcd_Init, I2CxLcd_Disp) ; ; Copyright (C) 2020-2021 by M.Yamamoto. All rights reserved. ; ; ( coding: Ver. 0.00 2020/12/10 by M.Yamamoto ) ; coding: Ver. 1.00 2020/12/15 ; update: Ver. 1.01 2021/01/01 I2Cルーチンを別ファイルに分離 ; update: Ver. 1.02 2021/01/14 マクロ命令 Disp_I2CxLcd を変更 ; update: Ver. 1.03 2021/01/19 変数名を変更 ; bugfix: Ver. x.xx ; ;******************************************************* PicAsm 0257 ****** ;<使用外部ルーチン> ;(i2c_start, i2c_stop, i2c_byte_send, i2c_byte_reciv, i2c_ack, i2c_nack) ;(wait_xxms, wait_100us, wait_40us) ;<使用レジスタ> ;lcdtmp ;LCD への出力データの一時保存 ;lcdtmp2 ; ;cntrbuf ; ;lcd_addr_high ;書き込みデータの high アドレス ;lcd_addr_low ;書き込みデータの low アドレス ;========================================================================== ; 定数の定義 ;========================================================================== LcdAddr equ h'27' ;I2C IF モジュール(PCF8574) のスレーブアドレス ;LcdAddr equ h'3f' ;I2C IF モジュール(PCF8574A)のスレーブアドレス _RS equ 0 ;LCD RS: レジスタ選択信号 _RW equ 1 ;LCD R/W: 読み出し/書き込み選択信号 _E equ 2 ;LCD E: 動作起動信号 _BL equ 3 ;バックライト LED ON/OFF 制御 _BF equ 7 ;LCD ビジーフラグ ;========================================================================== ; マクロ命令定義 ;========================================================================== ; I2C IF モジュール LCD メッセージデータ表示マクロ Disp_I2CxLcd macro @com,@msg,@x #if @com != 0 movlw @com call I2CxLcd_Cmd ;I2C LCD へコマンドを出力 #endif #if @x != 0 movlw high @msg ;メッセージデータの先頭 high アドレス movwf lcd_addr_high ; movlw low @msg ;メッセージデータの先頭 low アドレス movwf lcd_addr_low ; #endif call I2CxLcd_Disp ;メッセージデータ1行表示 endm ;Disp_I2CxLcd macro @com,@msg,@x ; movlw @com ; call I2CxLcd_Cmd ;I2C LCD へコマンドを出力 ; #if @x == 0 ; #else ; movlw high @msg ;メッセージデータの先頭 high アドレス ; movwf lcd_addr_high ; ; movlw low @msg ;メッセージデータの先頭 low アドレス ; movwf lcd_addr_low ; ; #endif ; call I2CxLcd_Disp ;メッセージデータ1行表示 ; endm ;========================================================================== ; I2C IF モジュール LCD へコマンドを出力 ;========================================================================== ;使用レジスタ: lcdtmp, cntrbuf ;入力: W reg: コマンド I2CxLcd_Cmd bcf cntrbuf,_RS ;RS = 0 (コマンドモードに設定) goto i2cxlcd01 ;========================================================================== ; I2C IF モジュール LCD へデータを出力 ;========================================================================== ;使用レジスタ: lcdtmp, cntrbuf ;入力: W reg: データ I2CxLcd_Data bsf cntrbuf,_RS ;RS = 1 (データモードに設定) nop i2cxlcd01 bcf cntrbuf,_RW ;R/W = 0 (書き込みモードに設定) movwf lcdtmp ;コマンド/データを一時保存 call i2c_start ;スタートコンディション movlw LcdAddr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movf lcdtmp,W ; call I2CxLcd_Out ;上位4ビットを転送 swapf lcdtmp,W ; call I2CxLcd_Out ;下位4ビットを転送 call i2c_stop ;ストップコンディション ;; call I2CxLcd_Busy ;LCD ビジーチェック call wait_40us return ;========================================================================== ; I2C IF モジュール LCD へ4ビット一回の送出 ;========================================================================== ; DB7, DB6, DB5, DB4, BL, E, R/W, RS ;BL: バックライト LED ;使用レジスタ: cntrbuf, lcdtmp2 ;入力: W reg: コマンド/データ I2CxLcd_Out andlw h'f0' ;上位4ビットデータ iorwf cntrbuf,W ;コントロールとOR movwf lcdtmp2 ;Wレジスタの内容を一時保存 ; movf lcdtmp2,W ;コマンド/データ、E = 0 (動作起動信号の設定:L) call i2c_byte_send ;1 バイト送信 movf lcdtmp2,W ;コマンド/データ iorlw 1 << _E ;コマンド/データ、E = 1 (動作起動信号の設定:Hでストローブ) call i2c_byte_send ;1 バイト送信 movf lcdtmp2,W ;コマンド/データ、E = 0 (動作起動信号の設定:Lに戻す) call i2c_byte_send ;1 バイト送信 return ;========================================================================== ; I2C IF モジュール LCD の初期設定 ;========================================================================== ;使用外部ルーチン: wait_xxms, wait_100us I2CxLcd_Init clrf cntrbuf ;bit0: RS = 0 (コマンドモードに設定) ;bit1: R/W = 0 (書き込みモードに設定) ;bit2: E = 0 (動作起動信号の設定) ;bit3: BL = 0 (バックライト LED = OFF に設定) movlw 15 call wait_xxms ;wait 15ms (15ms以上を確保) movlw b'00110000' ;ファンクションセット(8bitモードに設定) call I2CxLcd_CmdIni ;上位4ビットを転送 movlw 5 call wait_xxms ;wait 5ms (4.1ms以上を確保) movlw b'00110000' ;ファンクションセット(8bitモードに設定) call I2CxLcd_CmdIni ;上位4ビットを転送 call wait_100us movlw b'00110000' ;ファンクションセット(8bitモードに設定) call I2CxLcd_CmdIni ;上位4ビットを転送 call wait_100us movlw b'00100000' ;ファンクションセット(4bitモードに設定) call I2CxLcd_CmdIni ;上位4ビットを転送 call wait_100us ;ここから 4bitモード movlw b'00101000' ;ファンクションセット call I2CxLcd_Cmd ;DL=0: 4bit, N=1: 2行, F=0: 5x7ドット movlw b'00001000' ;表示オン/オフコントロール call I2CxLcd_Cmd ;D=0: 表示オフ, C=0: カーソル非表示, B=0: 非ブリンク movlw b'00000001' ;表示クリア call I2CxLcd_Cmd ; movlw b'00000110' ;エントリーモードセット call I2CxLcd_Cmd ;I/D=1: アドレスを+1しカーソルは右移動,S=0: 非シフト bsf cntrbuf,_BL ;バックライト LED = ON に設定 return I2CxLcd_CmdIni movwf lcdtmp ;コマンドを一時保存 call i2c_start ;スタートコンディション movlw LcdAddr << 1 ;スレーブアドレス call i2c_byte_send ;1 バイト送信 movf lcdtmp,W ; call I2CxLcd_Out ;上位4ビットを転送 call i2c_stop ;ストップコンディション return ;========================================================================== ; I2C IF モジュール LCD 1行メッセージ表示 ;========================================================================== ;使用レジスタ: lcd_addr_low, lcd_addr_high ;<使用例> movlw h'80' ;表示位置の DDRAM のアドレスをセット ; call I2CxLcd_Cmd ;LCD へコマンドを出力 ; movlw high st_msg ;メッセージデータの先頭 high アドレス ; movwf lcd_addr_high ; ; movlw low st_msg ;メッセージデータの先頭 low アドレス ; movwf lcd_addr_low ; ; call I2CxLcd_Disp ;メッセージデータ1行表示 ; : ;st_msg dt " LCD 1602 Clock ",0 I2CxLcd_Disp call lcdtbl_read ;テーブルデータの読み出し bcf PCLATH,3 ;ページ 0 に戻す bcf PCLATH,4 incf lcd_addr_low,F ;読み出すデータの low アドレスの更新 btfsc STATUS,Z ;オーバーフローした場合は incf lcd_addr_high,F ;読み出すデータの high アドレスの更新 addlw 0 btfsc STATUS,Z ;h'00' か? goto i2cxldsp01 ;Yes call I2CxLcd_Data ;LCD へデータを1文字出力 goto I2CxLcd_Disp i2cxldsp01 return ; テーブルデータの1文字読み出し lcdtbl_read movf lcd_addr_high,W ;読み出すデータの high アドレス movwf PCLATH movf lcd_addr_low,W ;読み出すデータの low アドレス movwf PCL ;=============================================================== end ======