SDA         BIT P1.0        ; I2C DATA
SCL         BIT P1.1        ; I2C CLOCK

DATA_I2C    EQU 2FH         ;Bit addressing DATA buffer for I2C bus
ADDR_I2C    EQU 30H         ;Address buffer for I2C bus
ADDR_A3A0   EQU 34H         ;REAL ADDRESS FROM 0-7 OF I2C

I2C_ACK     BIT PSW.5       ;I2C Acknowledge Flag  0= Not acknowledge
I2C_ALL     BIT PSW.1       ;If send data complete this falg will be = 1

;
EN_LCD      BIT DATA_I2C.3  ;BIT 3 of DATA_I2C
RS_LCD      BIT DATA_I2C.2  ;BIT 2 OF DATA_I2C


;******************************************************************************
;           MAIN PROGRAM
;******************************************************************************
            ; LCD is  CONNECT TO PCF8754 at address 7EHS
            ; 4 BIT INTERFACE

MAIN:       MOV SP,#128-24
            ACALL INIT_LCD
            MOV A,#01H    ;CLEAR LCD
            ACALL WR_INS_LCD
            MOV A,#00H    ;Start address at 00
            ACALL SET_DDRAM
            MOV DPTR,#MESSAGE
            ACALL WR_L_LCD
            MOV A,#40H
            ACALL SET_DDRAM
            MOV DPTR,#MESSAGE1
            ACALL WR_L_LCD


MESSAGE:    DB  'Test20lineLCDby..I2C',020H
MESSAGE1:   DB  'www.mcu.cz',020H
NUMBER_TAB: DB  030H,031H,032H,033H,034H,035H,036H,037H,038H,039H


;******************************************************************************
;           LCDC Routines
;******************************************************************************
            ; INITIAL LCD

INIT_LCD:   MOV A,#33H
            ACALL WR_INS_LCD
            MOV A,#32H
            ACALL WR_INS_LCD
            MOV A,#28H    ;FUNCTION SET
            ACALL WR_INS_LCD
            MOV A,#06H    ;ENTRY MODE
            ACALL WR_INS_LCD
            MOV A,#01H    ;CLEAR DISPLAY
            ACALL WR_INS_LCD
            MOV A,#0CH    ;08H Display OFF ,no cursor and not blink (0Ch for ON)
            ACALL WR_INS_LCD  ;If 0fH then blink and show cursor
            RET


            ; SET ADDRESS OF DDRAM
            ; INPUT = A

SET_DDRAM:  SETB  ACC.7
            ACALL WR_INS_LCD
            RET


            ; SET ADDRESS OF CGRAM
            ; INPUT = A

SET_CGRAM:  CLR ACC.7
            SETB  ACC.6
            ACALL WR_INS_LCD
            RET


            ; WRITE LINE LCD  DIGIT=20
            ; INPUT = DPTR
            ; REG   = R5  A , DPTR

WR_L_LCD:   PUSH  05H     ;PUSH R5
            MOV R5,#00      ;NUMBER OF DIGIT
            CLR A     ;CLEAR A
WR_LINE_1:  MOVC  A,@A+DPTR
            ACALL WR_CH_LCD
            INC R5
            MOV A,R5
            CJNE  A,#20,WR_LINE_1   ;CHECK FOR  20 DIGIT COMPLETE
            POP 05H     ;POP  R5
            RET


            ; write DATA to DDRAM
            ; REG = ACC
            ; INPUT = ACC

WR_CH_LCD:  PUSH  ACC
            ANL A,#0F0H
            MOV ADDR_A3A0,#07H
            MOV DATA_I2C,A
            SETB  RS_LCD
            ACALL WR_8574
            ACALL ENABLE_LCD
            POP ACC
            SWAP  A
            ANL A,#0F0H
            MOV DATA_I2C,A
            SETB  RS_LCD
            ACALL WR_8574
            ACALL ENABLE_LCD
            RET


            ; WRITE instruction to LCD USE PCF8574 at address 7EH
            ; REG   = A
            ; INPUT = A

WR_INS_LCD: PUSH  ACC   ;Keep A
            ANL A,#0F0H
            MOV ADDR_A3A0,#07H    ;Select address of PCF 8574 to LCD
            MOV DATA_I2C,A
            ACALL WR_8574
            ACALL ENABLE_LCD
            POP ACC
            SWAP  A
            ANL A,#0F0H
            MOV DATA_I2C,A
            ACALL WR_8574


            ; ENABLE PULSE FOR LCD INPUT = A

ENABLE_LCD: SETB  EN_LCD
            ACALL WR_8574
            CLR EN_LCD
            ACALL WR_8574
            RET

;******************************************************************************
;           I2C Routines
;******************************************************************************

            ; Write Data to PCF8574A,PCF8574AP
            ; I/P = DATA_I2C , ADDR_A3A0
            ; *ADDR_CH can has value 0-7

WR_8574:    MOV ADDR_I2C,#70H
            ACALL ADJ_ADDR

START_WR:   ACALL I2C_CONN    ;START WRITE DATA TO I2C DEVICE
START_WR_1: ACALL I2C_D_WR
            ACALL I2C_STOP
            RET


            ; ADJUST ADDRESS OF I2C FOR 7 BIT ADDRESSING
            ; I/P = ADDR_A0A3
            ; O/P = ADDR_I2C
            ; REG = ACC
            ; Example:
            ;   ADDR_I2C:   0100 1110
            ;   ADDR_A3A0:  0000 0011

ADJ_ADDR:   PUSH  ACC
            ANL ADDR_I2C,#0F1H    ;YYYY 000Y
            MOV A,ADDR_A3A0
            ANL A,#07H      ;0000 0XXX
            RL  A     ;0000 XXX0
            ANL A,#0EH      ;0000 XXX0
            ADD A,ADDR_I2C
            MOV ADDR_I2C,A    ;YYYY XXXY
            POP ACC
            RET


            ; WRITE DATA TO I2C PHERIFERAL
            ; REG = R4 , ACC ,CARRY FLAG
            ; INPUT = DATA_I2C

I2C_D_WR:   PUSH  ACC
            MOV A,DATA_I2C
            SJMP  I2C_SEND


            ; Connect and Send data to I2C Device
            ; I/P = ADDR_I2C
            ; O/P = I2C_ACK
            ; REG = R5 ACC

I2C_CONN:   PUSH  ACC     ;Addressing to I2C Device
            MOV A,ADDR_I2C
            ACALL I2C_START   ;Start connect


            ;SEND Data to I2C

I2C_SEND:   PUSH  05H     ;PUSH R5
            MOV R5,#08
I2C_SEND_1: RLC A     ;MOV BIT to Carry FLAG
            MOV SDA,C
            ACALL I2C_CLK     ;CLOCK TO SEND ONE BIT
            DJNZ  R5,I2C_SEND_1   ;Decrease R5 BY ONE
            SETB  SDA     ;Complete Send Eight Bit
            ACALL I2C_DELAY
            SETB  SCL
            ACALL I2C_DELAY
            JB  SDA,I2C_SEND_2    ;Jump if Device not Acknowledge
            SETB  I2C_ACK     ;Device Acknowledge
I2C_SEND_2: CLR SCL
            POP 05H
            POP ACC
            RET


            ; I2C Start Condition
            ; O/P = I2C_ALL

I2C_START:  SETB  SDA
            SETB  SCL
            CLR I2C_ALL
            ACALL I2C_DELAY
            CLR SDA
            ACALL I2C_DELAY
            CLR SCL
            RET


            ; I2C Stop Condition
            ; O/P = I2C_ALL

I2C_STOP:   CLR SDA
            SETB  SCL
            ACALL I2C_DELAY
            SETB  SDA
            SETB  I2C_ALL
            RET


            ; Clock pulse for I2C

I2C_CLK:    SETB  SCL
            ACALL I2C_DELAY
            CLR SCL
            RET


            ; Delay time at system clock 12 MHz

I2C_DELAY:  PUSH  02H
            MOV R2,#02H
            DJNZ  R2,$
            POP 02H
            RET

END


Vytisknout stránku

Zpátky Zpátky
© DH servis 2002 -