今回実際にi2c通信(出力のみ^^;)できるようにしたいと思います。
接続するのは、キャラクター表示の液晶に接続してみました
ソフト的には、出力のみで受信機能は実装していません^^
液晶表示器は、手持ちにあった ストロベリーリナックスのSB1602Bを使用しました。
電源は、3.3V動作です。
i2c接続の液晶であれば、電圧とi2cアドレス/初期設定のコマンドを変更するだけで他の製品を使えると思います。
液晶との接続は、VDD(3.3V)、SDA、SCL、VSSの4本接続します。SDAとSCL端子にはプルアップ
抵抗を忘れずに接続します。(条件によると思いますが今回は 1.2KΩでプルアップしました)
また、液晶のRST(リセット端子)はVDDに接続しています。
z180側は、16MHz水晶で、内部クロックを16MHzにソフト的に設定変更しています。(デフォルトでは、内部クロック 8MHz動作となります)
時間稼ぎのディレールーチンが必要となりますので、ソフト的に作成しています(タイマー割り込みは今回は使用していません)
内部クロックをを変更する場合は、 ディレールーチンのパラメータD100Uも変更します。
プログラムの中には、RTS0端子を使用して、ディレールーチンの時間を確認するプログラムをコメントアウトしています。
ソフト構成は、PCA9564のアプリケーションノートAN10148を参考にしました。
LCDのi2cアドレスは、プログラム中に埋め込みされていますので、デバイスにより変更する必要があります。
[asm] ;;;; Z8S180 i/o port on i2c >> i2c LCD (SB1602B)
;;
;; Z8S180 cpu
;; 0000h -- 7fffh
;; External clock 16MHz
;;
;; i2c-bus controller PCA9564
;;
;; i/o address
;; I2CSTA i/o 0x80(r)
;; I2CTO i/o 0x80(w)
;; I2CDTA i/o 0x81(r/w)
;; I2CADR i/o 0x82(r/w)
;; I2CCON i/o 0x83(r/w)
;;
;;
;; assembler
;; program 0000H
;; data 1000H
;;
;; assemblers ASxxxx and ASlink V5.10
;; file name i2c.asm
;; $ asz80 -l -s -o i2c.asm
;; $ aslink -i i2c
;; $ sudo python hexwrite.py i2c.ihx
.z180
        ;; dely timing set in 100uS
D100U   .equ    65      ;;clock in 16MHz set
;D100U  .equ    26      ;;clock in 8MHz set
;D100U  .equ    138     ;;clock in 32MHz set
CNTLA0  .equ    0x00
CCR     .equ    0x1f
CMR     .equ    0x1e
I2CSTA  .equ    0x80    ;PCA9564 setting adress
I2CTO   .equ    0x80
I2CDAT  .equ    0x81
I2CADR  .equ    0x82
I2CCON  .equ    0x83
.area TEST (ABS)
        .org    0x0000
        jp      start
        .org    0x0100
start:  ld      sp,0x9000
;
        nop
        nop
;       in0     a,(CMR)
;       set     7,a             ;XTAL*2
;       out0    (CMR),a
        in0     a,(CCR)
        set     7,a             ;XTAL/1         ;;External clock XTAL=16MHz
        out0    (CCR),a
;
        nop
        nop
;
;loop:  in0     a,(CNTLA0)      ;; dely testing program 100uS output RTS0
;       set     4,a
;       out0    (CNTLA0),a
;       call    dely100u
;       in0     a,(CNTLA0)
;       res     4,a
;       out0    (CNTLA0),a
;       call    dely100u
;       jr      loop
;
;; main program
        ld      de,data1
        call    i2c_write       ;;i2c LCD init1
        ld      b,250           ;;250ms dely
        call    delym
        ld      b,250           ;;250ms dely
        call    delym
        ld      de,data2        ;;i2c LCD init2
        call    i2c_write
        ld      b,10            ;;10mS dely
        call    delym
        ld      de,data3        ;;i2c LCD disp
        call    i2c_write
halt
i2c_write:
        LD      A,0xff                  ;;Timout Register
        out0    (I2CTO),a
        ld      a,0x64                  ;;Own Address
        out0    (I2CADR),a
        ld      a,0x44                  ;;Enable Serial io
        out0    (I2CCON),a
        call    dely500u                ;; 500u Wite
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
Transm:
        ld      a,0xe4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 STA=1
loop1:  in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,loop1
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x08
        jp      nz,start
        ld      a,0x07c                 ;; slave adress 0x3e + 0(write)
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
loop2:  in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,loop2
loop3:
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x18
        jr      nz,loop3
                                        ;; DE reg = buffer adress
                                        ;; end buffer is "00"
data_write:
        ld      a,(DE)                  ;; write data (DE) is I2CDAT
        cp      0xff
        jr      z,data_write_end
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
data_w1:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,data_w1
data_w2:
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x28
        jr      nz,data_w2
        inc     de
        jr      data_write
data_write_end:
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x28
        jp      nz,data_write_end
        ld      a,0xD4                  ;;Generate STOP mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
D_W_ST0:
        in0     a,(I2CCON)              ;; STO=0 ?
        bit     4,a
        jr      nz,D_W_ST0
        ret
delym:                                  ;; B reg set *1mS dely
        push    bc
delyml: call    dely1m
        djnz    delyml
        pop     bc
        ret
dely1m:                                 ;; 1mS dely
        push    bc
        call    dely500u
        call    dely500u
        pop     bc
        ret
dely500u:                               ;; 500uS dely
        push    bc
        ld      b,5
dd5:    call dely100u
        djnz    dd5
        pop     bc
        ret
dely100u:                               ;; 100uS dely
        push    bc
        ld      b,D100U
l100u:  djnz    l100u
        pop     bc
        ret
.org 0x1000 ;; data
data1:
	.db	0x00		;; i2C LCD (SB1602B) init
	.db	0x38
	.db	0x39
	.db	0x14
	.db	0x70
	.db	0x56
	.db	0x6c
	.db	0xff    	;; data end
data2:
	.db	0x00    	;; i2C LCD (SB1602B) init
	.db	0x38
	.db	0x0d
	.db	0x01
	.db	0xff 		;; data end
data3:
	.db	0x40    	;; i2c led disp data
	.db	'H
	.db	'e
	.db	'l
	.db	'l
	.db	'o
	.db	0x20
	.db	'Z
	.db	'8
	.db	'0
	.db	0x20
	.db	'W
	.db	'o
	.db	'r
	.db	'l
	.db	'd
	.db	'!
	.db	0xff		;; data end
	.end
[/asm]
									
                    