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