前回に引き続き、LCDに温湿度表示を行うためのプログラムについてメモしていきます。

まずは、メインループですが、その前に、i2c、LCDの初期化設定を行います。
その後、メインループでLCDへの表示を行います。

温湿度センサー(AM2321)のi2c経由でのデータ読み込みを行います。
読み込んだデータは、16進表記になっているので、10進表記へ変換します。
LCDの2行目を指定したのち、温度データ、湿度データのLCDへの表示を行います。
続いて、RTCから時刻を読み出し、LCDへの表示を行っています。
400mSの時間稼ぎを行って、繰り返しのループとなっています。

.org    0xa000
start:                                          ;; main program
call    i2c_init                        ;i2c init
call    dely100u
call    lcd_init                        ;LCD init

main_loop:                                      ;main
call    am2321_read                     ;AM2321 data read
call    am2321_hex_to_dec               ;AM2321 read data hex to dec conversion

call    lcd_2line_set                   ;lcd 2 line top address set

ld      a," "
call    data_lcd8bitwrite

call    tmp_disp                        ;AM2321 Temperrature disp

ld      a," "
call    data_lcd8bitwrite
call    hum_disp                        ;AM2321 Humidity disp

call    time_disp                       ;RTC time disp
ld      b,200                           ;200ms dely
call    delym
ld      b,200                           ;200ms dely
call    delym
jp      main_loop

AM2321の呼び出しでは、前回のI2Cのバッファタイプの呼び出しルーチン及び、書き込みルーチンを使って、AM2321の温湿度データを読み込みします。

まずは、0x00のダミーデータを書き込みし、起こします。
1ms待った後、レジスター読み込み指令を書き込みします。
0x03,0x00,0x04の3バイトを書き込みします。
再度2ms待った後、
8バイトのデータを読み込みします。

am2321_read:
ld      e,TMP_ADDRESS                   ;AM2321 slave address set
ld      d,0x00                          ;data 0x00 write is nack
call    i2c_write

ld      b,0x01                          ;1ms dely
call    delym

ld      hl,AM2321_cmd_data              ;AM2321 data read setting
ld      b,0x03                          ;write data 3byte is 0x03 0x00 0x04
ld      e,TMP_ADDRESS                   ;AM2321 slave address set
call    i2c_buff_write                  ;i2c write

ld      b,0x02                          ;2ms dely
call    delym

ld      hl,AM2321_buff                  ;AM2321 read buff set
ld      b,0x08                          ;8bit read
ld      e,TMP_ADDRESS                   ;AM2321 slave address set
call    i2c_buff_read                   ;i2c read
ret

読み込んだAM2321のデータから、温度データ 2バイト、湿度データ2バイトを抽出し16進2桁から10進5桁に変換します。
その際、温度データの上位バイトの7bit目は、プラス、マイナスの符号を表記しているので、このビットをチェックします。マイナスの場合、”1”が立つのでチェンクしたのち”0”に戻します。

am2321_hex_to_dec:                              ;AM2321 read data hex to dec conversion
ld      de,AM2321_buff+0x02             ;AM2321 read Hum data buff to HL reg
ld      a,(de)
ld      h,a
inc     de
ld      a,(de)
ld      l,a
ld      de,Hum_dec_data                 ;HL hex  data to dec data
call    hex_to_dec

ld      de,AM2321_buff+0x04             ;AM2321 read Temp data buff to HL reg
ld      a,(de)
bit     7,a                             ;AM2321 Temp minus check
jr      nz,tmp_set01
ld      h,a
ld      a,"+"
ld      (Tmp_sin_data),a
jr      tmp_set02
tmp_set01:
res     7,a                             ;D7 "1" to mainus (-) set
ld      h,a
ld      a,"-"
ld      (Tmp_sin_data),a
tmp_set02:
inc     de
ld      a,(de)
ld      l,a
ld      de,Tmp_dec_data
call    hex_to_dec                      ;HL hex  data to dec data
ret

16進から10進に変換する方法として、10進での最高位一万の桁(ここでは10000))で割って行き、商と余りを求め、余りは次の千の桁(1000)で割っていくような手順としています。

hex_to_dec:                                     ;hex 2byte to dec conversion
ld      bc,0d10000                      ;division 10000
call    subtra

inc     de
ld      bc,0d1000                       ;division 1000
call    subtra

inc     de
ld      bc,0d100                        ;division 100
call    subtra

inc     de
ld      bc,0d10                         ;division 10
call    subtra

inc     de                              ;remainder
ld      a,l
ld      (de),a
ret

subtra:                                         ;division
xor     a
subtra_01:
inc     a
sbc     hl,bc
jr      nc,subtra_01
dec     a
add     hl,bc
ld      (de),a
ret

10進に変換されたデータをLCDへ表示します。
それぞれ、温度表示、湿度表示と分けています。

LCDへの温度表示

tmp_disp:                                      ;AM2321 read data disp
ld      a,(Tmp_sin_data)                ;AM2321 read TEMP data
call    data_lcd8bitwrite

ld      hl,Tmp_dec_data
inc     hl
inc     hl
ld      a,(hl)
cp      0x00
jr      nz,dec_disp
ld      a," "
call    data_lcd8bitwrite
jr      tem01
dec_disp:
call    bcd1
tem01:
inc     hl
ld      a,(hl)
call    bcd1
ld      a,"."
call    data_lcd8bitwrite
inc     hl
ld      a,(hl)
call    bcd1
ld      a,0xdf
call    data_lcd8bitwrite
ld      a,"C"
call    data_lcd8bitwrite
ret

LCDへの 湿度表示

hum_disp:                                       ;AM2321 read data disp
ld      hl,Hum_dec_data                 ;AM2321 read Hum data
inc     hl
inc     hl
ld      a,(hl)
call    bcd1
inc     hl
ld      a,(hl)
call    bcd1
ld      a,"."
call    data_lcd8bitwrite
inc     hl
ld      a,(hl)
call    bcd1
ld      a,"%"
call    data_lcd8bitwrite
ld      a,"R"
call    data_lcd8bitwrite
ld      a,"H"
call    data_lcd8bitwrite
ret

常温での表示を確認してみました。

今回のソースのまとめは次の通りです(ちょおと長くなりました)

        ;;z180 i/o port on i2c >> i2c LCD (KKHMF 1602 LCD +EasyWordMall 1602 LCD i2c i/F) amazon)
        ;;                     >> i2c RTC (RTC-864N akizuki denshi)
        ;;                     >> i2c Thermo-hygrometer ( AM2321 akizuki denshi)
        ;;        i2c-bus controller  PCA9564 (Digi-Key)
        ;;
        ;; Z8S180 cpu
        ;; 0000h -- ffffh
        ;; 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)
        ;;
        ;; lcd 1602 port
        ;;
        ;;      D0 > RS
        ;;      D1 > R/W
        ;;      D2 > E
        ;;      D3 > LED on/off
        ;;      D4 > DB4
        ;;      D5 > DB5
        ;;      D6 > DB6
        ;;      D7 > DB7        
        ;;
        ;; i2c slave address
        ;;      LCD i2c i/f  0x27
        ;;      RTC RTC-864N 0x51       
        ;;      TEM AM2321   0x5c       
        ;;
        ;; assembler
        ;;  program a000H
        ;;  data    program_end +
        ;;
        ;; assemblers  ASxxxx and ASlink V5.10
        ;; file name i2c_lcd_time_temp07.asm
        ;; $ asz80 -l -s -o i2c_lcd_time_temp07.asm
        ;; $ aslink -i i2c_lcd_time_temp07
        ;; $ monitor l command hex download i2c_lcd_time_temp07.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
 
 
I2CSTA  .equ    0x80    ;PCA9564 setting adress
I2CTO   .equ    0x80
I2CDAT  .equ    0x81
I2CADR  .equ    0x82
I2CCON  .equ    0x83

                        ;lcd setting
RS      .equ    0       ;command >0 :data transfer >1
RW      .equ    1       ;write >0 : read >1
EN      .equ    2       ;positive pulse
LED     .equ    3       ;back light off >0 : on >1

                        ;slave address setting
LCD_ADDRESS     .equ    0x27    ;LCD i2c slave address
RTC_ADDRESS     .equ    0x51    ;RTC i2c slave address
TMP_ADDRESS     .equ    0x5C    ;TMP i2c slave address

                        ;monitor call address setting
disp_a_hex      .equ    0x07b1
putchar         .equ    0x07fe
cr              .equ    0x016d
 
        .area   TEST (ABS)
 
        .org    0xa000
start:                                          ;; main program
        call    i2c_init                        ;i2c init
        call    dely100u
        call    lcd_init                        ;LCD init

main_loop:                                      ;main
        call    am2321_read                     ;AM2321 data read
        call    am2321_hex_to_dec               ;AM2321 read data hex to dec conversion

        call    lcd_2line_set                   ;lcd 2 line top address set

        ld      a," "
        call    data_lcd8bitwrite
 
        call    tmp_disp                        ;AM2321 Temperrature disp
                
        ld      a," "
        call    data_lcd8bitwrite
        call    hum_disp                        ;AM2321 Humidity disp

        call    time_disp                       ;RTC time disp
        ld      b,200                           ;200ms dely
        call    delym
        ld      b,200                           ;200ms dely
        call    delym
        jp      main_loop

am2321_hex_to_dec:                              ;AM2321 read data hex to dec conversion
        ld      de,AM2321_buff+0x02             ;AM2321 read Hum data buff to HL reg
        ld      a,(de)
        ld      h,a
        inc     de
        ld      a,(de)
        ld      l,a
        ld      de,Hum_dec_data                 ;HL hex  data to dec data  
        call    hex_to_dec

        ld      de,AM2321_buff+0x04             ;AM2321 read Temp data buff to HL reg
        ld      a,(de)
        bit     7,a                             ;AM2321 Temp minus check
        jr      nz,tmp_set01
        ld      h,a
        ld      a,"+"
        ld      (Tmp_sin_data),a
        jr      tmp_set02
tmp_set01:
        res     7,a                             ;D7 "1" to mainus (-) set
        ld      h,a
        ld      a,"-"
        ld      (Tmp_sin_data),a
tmp_set02:
        inc     de                              
        ld      a,(de)
        ld      l,a
        ld      de,Tmp_dec_data
        call    hex_to_dec                      ;HL hex  data to dec data
        ret

am2321_read:
        ld      e,TMP_ADDRESS                   ;AM2321 slave address set
        ld      d,0x00                          ;data 0x00 write is nack
        call    i2c_write

        ld      b,0x01                          ;1ms dely
        call    delym



        ld      hl,AM2321_cmd_data              ;AM2321 data read setting
        ld      b,0x03                          ;write data 3byte is 0x03 0x00 0x04
        ld      e,TMP_ADDRESS                   ;AM2321 slave address set
        call    i2c_buff_write                  ;i2c write

        ld      b,0x02                          ;2ms dely
        call    delym

        ld      hl,AM2321_buff                  ;AM2321 read buff set
        ld      b,0x08                          ;8bit read
        ld      e,TMP_ADDRESS                   ;AM2321 slave address set
        call    i2c_buff_read                   ;i2c read
        ret

hum_disp:                                       ;AM2321 read data disp
        ld      hl,Hum_dec_data                 ;AM2321 read Hum data
        inc     hl
        inc     hl
        ld      a,(hl)
        call    bcd1
        inc     hl
        ld      a,(hl)
        call    bcd1
        ld      a,"."
        call    data_lcd8bitwrite 
        inc     hl
        ld      a,(hl)
        call    bcd1
        ld      a,"%"
        call    data_lcd8bitwrite
        ld      a,"R"
        call    data_lcd8bitwrite
        ld      a,"H"
        call    data_lcd8bitwrite
        ret


 tmp_disp:                                      ;AM2321 read data disp
        ld      a,(Tmp_sin_data)                ;AM2321 read TEMP data  
        call    data_lcd8bitwrite
        
        ld      hl,Tmp_dec_data
        inc     hl
        inc     hl
        ld      a,(hl)
        cp      0x00
        jr      nz,dec_disp
        ld      a," "
        call    data_lcd8bitwrite
        jr      tem01
dec_disp:
        call    bcd1
tem01:
        inc     hl
        ld      a,(hl)
        call    bcd1
        ld      a,"."
        call    data_lcd8bitwrite 
        inc     hl
        ld      a,(hl)
        call    bcd1
        ld      a,0xdf
        call    data_lcd8bitwrite 
        ld      a,"C"
        call    data_lcd8bitwrite
        ret


hex_to_dec:                                     ;hex 2byte to dec conversion    
        ld      bc,0d10000                      ;division 10000
        call    subtra

        inc     de
        ld      bc,0d1000                       ;division 1000
        call    subtra

        inc     de
        ld      bc,0d100                        ;division 100
        call    subtra

        inc     de      
        ld      bc,0d10                         ;division 10
        call    subtra

        inc     de                              ;remainder
        ld      a,l
        ld      (de),a
        ret

subtra:                                         ;division
        xor     a
subtra_01:
        inc     a
        sbc     hl,bc
        jr      nc,subtra_01
        dec     a
        add     hl,bc
        ld      (de),a
        ret


time_disp: 
        ld      d,0x51                  ;i2c slave address set d reg
        ld      b,0x00
        ld      hl,rtc_buff             ;i2c receive data in buff set
loop:                                   ;rtc 8564 read register 0x00 to 0x0f
        ld      e,b                     ;i2c slave register set e reg
        call    i2c_read                ;i2c slave receive call
        cp      0xff                    ;a reg 0xff receive err
        jr      z,i2c_err_disp
        ld      (hl),e                  ;i2c slave data in e reg
        inc     hl
        inc     b
        ld      a,b
        cp      0x10                    ;end rtc 8564 register
        jr      nz,loop

        call    lcd_1line_set                   

        ld      a," "
        call    data_lcd8bitwrite       ;LCD putchar up data    
;        ld      a,0x20                  ;Years 20 set
;        call    bcd2
;        ld      a,(rtc_buff+0x08)       ;Years ?? i2c read data set
;        call    bcd2
;        ld      a,"/"
;       call    data_lcd8bitwrite       ;LCD putchar up data
        ld      a,(rtc_buff+0x07)       ;Months ?? i2c read data set
        and     0x1f
        call    bcd2
        ld      a,"/"
        call    data_lcd8bitwrite       ;LCD putchar up data
        ld      a,(rtc_buff+0x05)       ;Days ?? i2c read data set
        and     0x3f
        call    bcd2
        ld      a," "
        call    data_lcd8bitwrite       ;LCD putchar up data
        ld      a,(rtc_buff+0x04)       ;Hours  ?? i2c  read data set
        and     0x3f
        call    bcd2
        ld      a,":"
        call    data_lcd8bitwrite       ;LCD putchar up data
        ld      a,(rtc_buff+0x03)       ;Minutes ?? i2c read data set
        and     0x7f
        call    bcd2
        ld      a,":"
        call    data_lcd8bitwrite       ;LCD putchar up data
        ld      a,(rtc_buff+0x02)       ;Seconds ?? i2c read data set
        and     0x7f
        call    bcd2
;       call    cr
        ret

i2c_err_disp:                           ;i2c err disp
        call    cr
        ld      a,"e"
        call    putchar
        ld      a,"r"
        call    putchar
        ld      a,"r"
        call    putchar
        call    cr
        ret
bcd2:                                   ;bcd to putchar         
        push    af                      ; up bcd (7:4)
        rlca
        rlca
        rlca
        rlca
        and     0x0f
        or      0x30
        call    data_lcd8bitwrite       ;LCD putchar up data
        pop     af
bcd1:
        and     0x0f                    ;down data (3:0)
        or      0x30
        call    data_lcd8bitwrite       ;LCD putchar down data
        ret

lcd_1line_set:                          ;a reg:output char
        ld      a,0x80                  ;0x80 + 0x00(1 line top address)
        call    lcd8bitwrite            ; 1 line set
        ret
lcd_2line_set:
        ld      a,0xc0                  ;0x80 + 0x40(2 line top address)
        call    lcd8bitwrite            ; 2 line set
        ret     
        

i2c_read:
        ld      a,0xe4                  ;;Master Receiver Mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 STA=1
i2c_r_si01:  
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a     
        jr      z,i2c_r_si01
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x08
        jp      nz,i2c_r_err
        in0     a,(I2CDAT)
        ld      a,d                     ;set slave addres set a reg
        sla     a                       ;carry flag set at write mode
                                        ;slave address + write
        out0    (I2CDAT),a              ;sleve address set
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0

i2c_r_si02:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_r_si02

        in0     a,(I2CSTA)              ;;Address+W has been trasimited
        cp      0x18                    ;;ACK has been received
        jr      nz,i2c_r_err

        ld      a,e                     ;;read slave register set 
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
i2c_r_si04:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_r_si04

        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x28                    ;ACK has been received
        jr      nz,i2c_r_err

        ld      a,0xe4                  ;not stop signal is startting
        out0    (I2CCON),a              ; AA=1 ENSIO=1 STA=1 STO=0
i2c_r_si05:
        in0     a,(I2CCON)              ;SI=1 ?
        bit     3,a
        jr      z,i2c_r_si05
        ld      a,d                     ;read  slave address d reg 
        scf                             ;set read mode bit0=1
        RLA     
        out0    (I2CDAT),a              ;set slave address
        ld      a,0xc4                  ;send data
        out0    (I2CCON),a
i2c_r_si06:
        in0     a,(I2CCON)
        bit     3,a                     ;SI=1 ?
        jr      z,i2c_r_si06


        in0     a,(I2CSTA)              ;Address+R has been transmitted
        cp      0x40                    ;ACK has been received
        jr      nz,i2c_r_err


        ld      a,0x44                  ;Reset SI And AA bit
        out0    (I2CCON),a              ;AA=0 ENSIO=1 STA=0 STO=0
i2c_r_si07:
        in0     a,(I2CCON)
        bit     3,a                     ;SI=1 ?
        jr      z,i2c_r_si07

                                
        in0     a,(I2CSTA)              ;Data has been received
        cp      0x58                    ;NACK has been returned
        jr      nz,i2c_r_err

        in0     a,(I2CDAT)              ;Received Data read a reg
        ld      e,a
        ld      a,0xd4                  ;Generate STOP command
        out     (I2CCON),a              ;AA=1 ENSIO=1 STA=0 STO=1

i2c_stop_loop:
        in0     a,(I2CCON)
        bit     4,a                     ;STO=0 ?
        jr      nz,i2c_stop_loop
        in0     a,(I2CSTA)
        cp      0xf8                    ;reset or STOP command
        jr      nz,i2c_r_err
        xor     a
        ret
;
i2c_r_err:
        ld      a,0xff
        ret

i2c_buff_read:                          ;;buff >> HL reg
                                        ;;buff size >> B reg
                                        ;;Slave Address C reg

        ld      a,0xe4                  ;;Master Receiver Mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 STA=1
i2c_br_si01:  
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a     
        jr      z,i2c_br_si01
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x08
        jp      nz,i2c_br_err
        in0     a,(I2CDAT)
 
        ld      a,e                     ;read  slave address d reg 
        scf                             ;set read mode bit0=1
        RLA     
        out0    (I2CDAT),a              ;set slave address
        ld      a,0xc4                  ;send data
        out0    (I2CCON),a
i2c_br_si06:
        in0     a,(I2CCON)
        bit     3,a                     ;SI=1 ?
        jr      z,i2c_br_si06


        in0     a,(I2CSTA)              ;Address+R has been transmitted
        cp      0x40                    ;ACK has been received
        jr      nz,i2c_br_err

        dec     b
        jr      z,i2c_br_next_end

i2c_br_next:
        ld      a,0xc4                  ;Reset SI And AA bit
        out0    (I2CCON),a              ;AA=0 ENSIO=1 STA=0 STO=0
i2c_br_si07:
        in0     a,(I2CCON)
        bit     3,a                     ;SI=1 ?
        jr      z,i2c_br_si07

                                
        in0     a,(I2CSTA)              ;Data has been received
        cp      0x50                    ;data-ACK has been returned
        jr      nz,i2c_br_err

        in0     a,(I2CDAT)              ;Received Data read a reg
        ld      (HL),a
        inc     hl
        djnz    i2c_br_next

i2c_br_next_end:

        ld      a,0x44                  ;Reset SI And AA bit
        out0    (I2CCON),a              ;AA=0 ENSIO=1 STA=0 STO=0
i2c_br_si08:
        in0     a,(I2CCON)
        bit     3,a                     ;SI=1 ?
        jr      z,i2c_br_si08

                                
        in0     a,(I2CSTA)              ;Data has been received
        cp      0x58                   ;data-ACK has been returned
        jr      nz,i2c_br_err

        in0     a,(I2CDAT)              ;Received Data read a reg
        ld      (HL),a


        ld      a,0xd4                  ;Generate STOP command
        out     (I2CCON),a              ;AA=1 ENSIO=1 STA=0 STO=1

i2c_br_stop_loop:
        in0     a,(I2CCON)
        bit     4,a                     ;STO=0 ?
        jr      nz,i2c_br_stop_loop
        in0     a,(I2CSTA)
        cp      0xf8                    ;reset or STOP command
        jr      nz,i2c_br_err
        xor     a
        ret
;
i2c_br_err:
        ld      a,0xff
        ret

lcd_init:                                       ;LCD init(4bit mode)

        ld      a,0x03
        call    lcd4bitwrite

        ld      b,0x05                   ;;5ms dely
        call    delym

        ld      a,0x03                          
        call    lcd4bitwrite

        ld      a,0x03
        call    lcd4bitwrite

        ld      a,0x02                          ;;4 bit mode 
        call    lcd4bitwrite

        ld      a,0x28                          ;function set
        call    lcd8bitwrite                    ;4bit bus,2 line ,1 line=8
  
        ld      a,0x0c                          ;disp on,under cursor off,block cursor off
        call    lcd8bitwrite

        ld      a,0x01                          ;disp clr
        call    lcd8bitwrite
        
        ld      b,0x02                          ;;2mS dely 
        call    delym

        ld      a,0x06                          ;disp address incrmant on,disp shift off
        call    lcd8bitwrite
        
;       ld      a,0x02                          ;cursor home set
;       call    lcd8bitwrite

;       ld      b,0x02                          ;;2ms dely
;       call    delym

        ret

i2c_init:
        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
        ret 

lcd8bitwrite:                   ;command mode 8bit data LCD output
        push    af                      ;
        rrca                            ;8bit data upper 4bit data LED output
        rrca
        rrca
        rrca
        call    lcd4bitwrite            ;command mode 4bit data LCD output
        pop     af                      ;8bit data low 4bit data LED output
        call    lcd4bitwrite            ;command mode 4bit data LCD output      
        ret

lcd4bitwrite:                   ;command mode 4bit data LCD output
        rlca                            ;4bit data upper 4bit set
        rlca
        rlca
        rlca
        res     RS,a                    ;LCD Command mode
        res     RW,a                    ;LCD Write mode
        res     EN,a                    ;LCD EN low
        set     LED,a                   ;LCD back light LED ON

        push    af
        ld      d,a                     ;i2c write data set
        ld      e,LCD_ADDRESS           ;i2c slave address set
        call    i2c_write               ;i2c write

        pop     af
        set     EN,a                    ;LCD EN high
        push    af
        ld      d,a
        ld      e,LCD_ADDRESS           ;i2c slave address set
        call    i2c_write               ;i2c write

        pop     af
        res     EN,a                    ;LCD EN low
        ld      d,a
        ld      e,LCD_ADDRESS           ;i2c slave address set          
        call    i2c_write               ;i2c write
        ret

data_lcd8bitwrite:                      ;data mode 8bit data LCD output
        push    af
        rrca                            ;8bit data upper 4bit data LED output
        rrca
        rrca
        rrca
        call    data_lcd4bitwrite       ;command mode 4bit data LCD output
        pop     af                      ;8bit data low 4bit data LED output
        call    data_lcd4bitwrite       ;command mode 4bit data LCD output
        ret

data_lcd4bitwrite:                      ;data mode 4bit data LCD output
        rlca
        rlca
        rlca
        rlca
        set     RS,a                    ;LCD RS data mode
        res     RW,a                    ;LCD write mode
        res     EN,a                    ;LCD EN low
        set     LED,a                   ;LCD back light LED ON

        push    af
        ld      d,a                     ;i2c write data set
        ld      e,LCD_ADDRESS           ;i2c slave address set
        call    i2c_write               ;i2c write      
 
        pop     af
        set     EN,a                    ;LCD EN high
        push    af
        ld      d,a                     ;i2c write data set
        ld      e,LCD_ADDRESS           ;i2c slave address set
        call    i2c_write               ;i2c write

        pop     af
        res     EN,a                    ;LCD EN low
        ld      d,a                     ;i2c write data set     
        ld      e,LCD_ADDRESS           ;i2c slave address set
        call    i2c_write               ;i2c write
        ret

i2c_write:
        ld      a,0xe4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 STA=1
i2c_w_loop1:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a    
        jr      z,i2c_w_loop1
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x08
        jp      nz,err
        in      a,(I2CDAT)
        ld      a,e                     ;;Slave address set
        sla     a
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
i2c_w_loop2:  in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_w_loop2

        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x20                    ;;Write data N-ACK
        jr      z,data_w_stop           ;;go to Stop mode
        cp      0x18
        jr      nz,err
                                        ;; DE reg = buffer adress
                                        ;; end buffer is "00
        ld        a,d                      ;; write data Areg is I2CDAT
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
i2c_w_loop3:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_w_loop3

        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x28
        jr      nz,err
data_w_stop:        
        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
        in         a,(I2CSTA)
        cp         0xf8
        jr         nz,err
        ret

err:    
        call    disp_a_hex                                      ;; err 
        call    cr
        ld      a,"E"
        call    putchar
        ld      a,"r"
        call    putchar
        ld      a,"r"
        call    putchar
        call    cr
        ret

i2c_buff_write:                         ;;write buff data >> HL reg
                                        ;;write buff size >> B reg
                                        ;;slave address >> E reg

        ld      a,0xe4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 STA=1
i2c_bw_loop1:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a    
        jr      z,i2c_bw_loop1
        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x08
        jp      nz,err
        in      a,(I2CDAT)
        ld      a,e                     ;;Slave address set
        sla     a
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
i2c_bw_loop2:  in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_bw_loop2

        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x20                    ;;Write data N-ACK
        jr      z,data_bw_stop          ;;go to Stop mode
        cp      0x18
        jr      nz,err
                                        ;; HL reg = buffer adress
i2c_bw_next:                                        ;; end buffer is "00
        ld      a,(hl)                  ;; write data Areg is I2CDAT
        out0    (I2CDAT),a
        ld      a,0xc4                  ;;Slave recciver mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
i2c_bw_loop3:
        in0     a,(I2CCON)              ;; SI=1 ?
        bit     3,a
        jr      z,i2c_bw_loop3

        in0     a,(I2CSTA)              ;;Poll from transmission finished
        cp      0x28
        jr      nz,err

        inc     hl
        djnz    i2c_bw_next

data_bw_stop:        
        ld      a,0xD4                  ;;Generate STOP mode
        out0    (I2CCON),a              ;; AA=1 ENSIO=1 SI=0
D_bW_ST0:
        in0     a,(I2CCON)              ;; STO=0 ?
        bit     4,a
        jr      nz,D_bW_ST0
        in         a,(I2CSTA)
        cp         0xf8
        jr         nz,err
        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
    
;; data

AM2321_cmd_data:
        .db     0x03
        .db     0x00
        .db     0x04
 

rtc_buff:
        .ds     16

AM2321_buff:
        .ds     8
Hum_dec_data:
        .ds     5
Tmp_dec_data:
        .ds     5
Tmp_sin_data:
        .ds     1
    .end
AM2321, LCD, RTC-8564, Z8S180, I2Cの関連記事
  • Z80(TMPZ84C015)に萌えたい。I2Cソフト:LCD+RTC+温度表示
  • Z80(Z8S180)に萌えたい LCDに温湿度表示(AM2321)その2
  • Z80(Z8S180)に萌えたい LCDに温湿度表示(AM2321)その1
おすすめの記事
Z80
前回のI/Oポートに SPI接続できるSDカードを接続したいと思います。 SDカード自体が3.3V動作なので、電圧変換が必要になります。 変...