*#cpu ATMEL 89C2051 ;PRXSDA EQU proxyoffs * 2 ;PRXSCL EQU proxyoffs * 2 + 1 PRXRESET EQU 7 SDARBIT EQU P3.7 SCLRBIT EQU P3.5 ORG $0000 AJMP *+$0032 * Interrupt area DS $0032-2 MOV SP,#?stk -1 LCALL main forever SJMP forever main MOV R0,#pcf8574table MOV R1,#15 lp1 MOV [R0],#255 INC R0 DJNZ R1,lp1 MOV proxyadres,#0 MOV proxyoffs,#0 MOV SERReadPtrR,#SERReadBuf MOV SERReadPtrW,#SERReadBuf MOV SERWritePtrR,#SERWriteBuf MOV SERWritePtrW,#SERWriteBuf ORL IE,#90H ACALL serinit ACALL I2C_INIT MOV DPTR,#infotxt ACALL putstr ACALL PRXI2C_INIT mloop ; "?I2C" -> "?[I2C]Ok" ACALL getch CJNE A,#'?',?noinfo ACALL cmdinfo SJMP mloop ?noinfo ; Find chip ; "ZAA" -> "ZO" or "ZX" ; AA = Adres CJNE A,#'Z',?nofind ACALL cmdfind SJMP mloop ?nofind ; Read data ; "RAA" -> "RDD" or "RX" ; AA = Adres DD = Data CJNE A,#'R',?noread ACALL cmdread SJMP mloop ?noread ; Write data ; "WAADDDDDDDDDD" -> "WO" or "WX" ; AA = Adres DD = Data CJNE A,#'W',?nowrite ACALL cmdwrite SJMP mloop ?nowrite ; Write single bit ; "SABV" -> "SO" or "SX" ; A = Adres (0..F) B = Bitnummer (0..7) V = Value (0..1) CJNE A,#'S',?nobit ACALL cmdbit SJMP mloop ?nobit ; Read data over proxy ; "NPPAA" -> "NDD" or "NX" ; P = Proxy(Adres,Offset) AA = Adres DD = Data CJNE A,#'N',?noprxread ACALL cmdprxread SJMP mloop ?noprxread ; Find chip over proxy ; "XPPAA" -> "XO" or "XX" ; P = Proxy(Adres,Offset) AA = Adres CJNE A,#'X',?noprxfind ACALL cmdprxfind SJMP mloop ?noprxfind ; Write data over proxy ; "MPPAADDDDDDDDDD" -> "MO" or "MX" ; P = Proxy(Adres,Offset) AA = Adres CJNE A,#'M',?noprxwrite ACALL cmdprxwrite SJMP mloop ?noprxwrite ; Read Special data over proxy (MSP3410 compatible) ; "UPPAASSHHLL" -> "UHHLL" or "UX" ; P = Proxy(Adres,Offset) AA = Adres CJNE A,#'U',?noprxdblread ACALL cmdprxdblread SJMP mloop ?noprxdblread SJMP mloop RET serinit ; 19200 baud... ORL PCON,#80H ; Set SMOD MOV TMOD,#%00100000 MOV TH1,#-3 MOV TL1,#-3 MOV TCON,#%01001011 MOV SCON,#%01010000 RET ; Write a character to the serial port output buffer ; Input: A putch PUSH 1 PUSH 2 PUSH A MOV A,SERWritePtrW MOV R1,A INC A CJNE A,#SERWriteBuf+16,?PU1 MOV A,#SERWriteBuf ?PU1 CJNE A,SERWritePtrR,?PU2 SJMP ?PU1 ?PU2 MOV R2,A POP A MOV [R1],A MOV SERWritePtrW,R2 JB SCON.3,?PU3 SETB SCON.1 ?PU3 POP 2 POP 1 RET putstr CLR A MOVC A,[A+DPTR] INC DPTR CJNE A,#0,?putstr RET ?putstr ACALL putch SJMP putstr ; Check if character received ; Output: A ; Output: Carry if received chkch PUSH 0 MOV A,SERReadPtrR CJNE A,SERReadPtrW,?CH1 MOV A,#-1 POP 0 CLR C RET ?CH1 MOV R0,A MOV A,[R0] INC R0 CJNE R0,#SERReadBuf+20,?CH2 MOV R0,#SERReadBuf ?CH2 MOV SERReadPtrR,R0 POP 0 SETB C RET ; Check if character received ; Output: A getch ACALL chkch JNC getch RET ; converteer HEX code (B,A) in ascii character -> A ; Result: A hextoasc PUSH 0 CLR C SUBB A,#30H PUSH A SUBB A,#10 POP A JC ?hextoasc1 SUBB A,#7 ?hextoasc1 MOV R0,A MOV A,B CLR C SUBB A,#30H PUSH A SUBB A,#10 POP A JC ?hextoasc2 SUBB A,#7 ?hextoasc2 SWAP A ORL A,R0 POP 0 RET ; converteer ascii character to HEX: Transmit meteen ; Input A asctohex PUSH A PUSH A SWAP A ACALL ?asctohexbyte POP A ACALL ?asctohexbyte POP A RET ?asctohexbyte ANL A,#0FH PUSH A CLR C SUBB A,#10 POP A JC ?asctohexbyte2 ADD A,#7 ?asctohexbyte2 ADD A,#30H ACALL putch RET cmdinfo ACALL getch CJNE A,#'I',?cmdinfoend ACALL getch CJNE A,#'2',?cmdinfoend ACALL getch CJNE A,#'C',?cmdinfoend ACALL getch CJNE A,#13,?cmdinfoend MOV DPTR,#identtxt ACALL putstr ?cmdinfoend RET ; Find I2C device. cmdfind PUSH A ; First get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch CJNE A,#13,?cmdfind3 POP A ACALL putch MOV A,#0 ; WRITE MODE ACALL I2C_ADRES ; Start transfer JNC ?cmdfind ; NO ACK (Chip NOT found) MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdfind2 ?cmdfind MOV A,#'O' ACALL putch MOV A,#13 ACALL putch ?cmdfind2 ACALL I2C_STOP RET ?cmdfind3 POP A SJMP ?cmdfind2 ; Read I2C device. cmdread PUSH A ; First get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch CJNE A,#13,?cmdread4 POP A ACALL putch MOV A,#1 ; Read MODE ACALL I2C_ADRES ; Start transfer JNC ?cmdread ; NO ACK (Chip NOT found) ?cmdread3 MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdread2 ?cmdread MOV A,#1 ; No ACK ACALL I2C_READ JC ?cmdread3 MOV A,R0 ACALL asctohex MOV A,#13 ACALL putch ?cmdread2 ACALL I2C_STOP ACALL I2C_START ACALL I2C_STOP RET ?cmdread4 POP A SJMP ?cmdread2 ; Write I2C device. cmdwrite ; Format: "WAADDDDDDDDDD" ; First get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R1,A MOV A,#0 ; Write MODE ACALL I2C_ADRES ; Start transfer JNC ?cmdwrite ; NO ACK (Chip NOT found) ?cmdwrite3 MOV A,#'W' ACALL putch MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdwriteexit ?cmdwrite PUSH 1 POP 0 ACALL I2C_SEND JC ?cmdwrite3 ?cmdwritelp ; check of er nog een character volgt. ACALL getch JNC ?cmdwritesk1 CJNE A,#13,?cmdwritemr1 SJMP ?cmdwritesk1 ?cmdwritemr1 MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ACALL I2C_SEND JC ?cmdwrite3 SJMP ?cmdwritelp ?cmdwritefn1 ?cmdwritesk1 MOV A,#'W' ACALL putch MOV A,#'O' ACALL putch MOV A,#13 ACALL putch ?cmdwriteexit ACALL I2C_STOP RET cmdbit ; First get hex adress (2 characters) ACALL getch MOV B,#'0' ; Convert it to char. ACALL hextoasc MOV R0,A ACALL getch MOV B,#'0' ACALL hextoasc MOV R1,A ACALL getch MOV B,#'0' ACALL hextoasc MOV R2,A ACALL getch CJNE A,#13,?cmdbit ACALL prxbit JC ?cmdbiterr MOV A,#'S' ACALL putch MOV A,#'O' ACALL putch SJMP ?cmdbit ?cmdbiterr MOV A,#'S' ACALL putch MOV A,#'X' ACALL putch ?cmdbit MOV A,#13 ACALL putch RET cmdprxread PUSH A ; First get hex Proxy adress (2 character) MOV B,#'0' ACALL getch ; Convert it to char. ACALL hextoasc MOV proxyadres,A MOV B,#'0' ACALL getch ; Convert it to char. ACALL hextoasc MOV proxyoffs,A ; Then get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch CJNE A,#13,?cmdprxread2 MOV A,#'N' ACALL putch MOV A,#1 ; Read MODE ACALL PRXI2C_ADRES ; Start transfer JNC ?cmdprxread ; NO ACK (Chip NOT found) ?cmdprxread3 MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdprxread2 ?cmdprxread MOV A,#1 ; No ACK ACALL PRXI2C_READ JC ?cmdprxread3 MOV A,R0 ACALL asctohex MOV A,#13 ACALL putch ?cmdprxread2 ACALL PRXI2C_STOP ACALL PRXI2C_START ACALL PRXI2C_STOP POP A RET ; Find I2C device. cmdprxfind PUSH A ; First get hex Proxy adress (1 character) ACALL getch MOV B,#'0' ; Convert it to char. ACALL hextoasc MOV proxyadres,A MOV B,#'0' ACALL getch ; Convert it to char. ACALL hextoasc MOV proxyoffs,A ; Then get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch CJNE A,#13,?prxcmdfind2 MOV A,#'X' ACALL putch MOV A,#0 ; WRITE MODE ACALL PRXI2C_ADRES ; Start transfer JNC ?prxcmdfind ; NO ACK (Chip NOT found) MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?prxcmdfind2 ?prxcmdfind MOV A,#'O' ACALL putch MOV A,#13 ACALL putch ?prxcmdfind2 ACALL PRXI2C_STOP POP A RET ; Write I2C device. cmdprxwrite ; Format: "MPPAADDDDDDDDDD" ; First get hex Proxy adress (1 character) ACALL getch MOV B,#'0' ; Convert it to char. ACALL hextoasc MOV proxyadres,A MOV B,#'0' ACALL getch ; Convert it to char. ACALL hextoasc MOV proxyoffs,A ; Then get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R1,A MOV A,#0 ; Write MODE ACALL PRXI2C_ADRES ; Start transfer JNC ?cmdprxwrite ; NO ACK (Chip NOT found) ?cmdprxwrite3 MOV A,#'M' ACALL putch MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdprxwriteexit ?cmdprxwrite PUSH 1 POP 0 ACALL PRXI2C_SEND JC ?cmdprxwrite3 ?cmdprxwritelp ; check of er nog een character volgt. zoja dan memory of zo. ACALL getch JNC ?cmdprxwritesk1 CJNE A,#13,?cmdprxwritemr1 SJMP ?cmdprxwritesk1 ?cmdprxwritemr1 MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ACALL PRXI2C_SEND JC ?cmdprxwrite3 SJMP ?cmdprxwritelp ?cmdprxwritesk1 MOV A,#'M' ACALL putch MOV A,#'O' ACALL putch MOV A,#13 ACALL putch ?cmdprxwriteexit ACALL PRXI2C_STOP RET ; Read Special data over proxy I2C device. cmdprxdblread ; Read Special data over proxy (MSP3410 compatible) ; "UPPAASSHHLL" -> "UHHLL" or "UX" ; P = Proxy(Adres,Offset) AA = Adres ACALL getch MOV B,#'0' ; Convert it to char. ACALL hextoasc MOV proxyadres,A MOV B,#'0' ACALL getch ; Convert it to char. ACALL hextoasc MOV proxyoffs,A ; Then get hex adress (2 characters) ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ; Adres MOV I2CADRES,A ; store it somewhere safe... ; First data ; Sub Adress ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R1,A MOV A,#0 ; Write MODE ACALL PRXI2C_ADRES ; Start transfer JNC ?cmdprxdblread ; NO ACK (Chip NOT found) ?cmdprxdblread3 MOV A,#'U' ACALL putch MOV A,#'X' ACALL putch MOV A,#13 ACALL putch SJMP ?cmdprxdblreadexit ?cmdprxdblread PUSH 1 POP 0 ACALL PRXI2C_SEND JC ?cmdprxdblread3 ; Addr byte high ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ACALL PRXI2C_SEND JC ?cmdprxdblread3 ; Addr byte low ACALL getch MOV B,A ACALL getch ; Convert it to char. ACALL hextoasc MOV R0,A ACALL PRXI2C_SEND JC ?cmdprxdblread3 ; Again a start condition to switch to read mode... MOV R0,I2CADRES MOV A,#1 ; Read MODE ACALL PRXI2C_ADRES ; Start transfer MOV A,#'U' ACALL putch ; Data byte high MOV A,#0 ; ACK ACALL PRXI2C_READ MOV A,R0 ACALL asctohex ; Data byte low MOV A,#1 ; No ACK ACALL PRXI2C_READ MOV A,R0 ACALL asctohex MOV A,#13 ACALL putch ?cmdprxdblreadexit ACALL PRXI2C_STOP ACALL PRXI2C_START ACALL PRXI2C_STOP RET ; Input R0 = PCF8574 Adres (0..15), R1 = Bitnummer (0..7), R2 = Value (0..1) prxbit PUSH 3 PUSH 4 MOV A,#pcf8574table ADD A,R0 ; Add offset PUSH 0 MOV R0,A MOV A,[R0] ; Read Table content PUSH 0 POP 4 ; Store Offset pointer awhile MOV R3,A ; Store value POP 0 MOV A,R0 CLR C SUBB A,#8 JC ?prxclrbit1 ; He het is een PCF8574A MOV A,R0 ADD A,#38H-8 SJMP ?prxclrbit2 ?prxclrbit1 MOV A,R0 ADD A,#20H ?prxclrbit2 MOV R0,A MOV A,#0 ; Write MODE ACALL I2C_ADRES ; Start transfer JC ?prxclrbiterr MOV DPTR,#MASKER CJNE R2,#0,?prxclrbit3 ; Reset bit MOV A,R1 MOVC A,[A+DPTR] CPL A ANL A,R3 SJMP ?prxclrbit4 ?prxclrbit3 ; Set bit MOV A,R1 MOVC A,[A+DPTR] ORL A,R3 ?prxclrbit4 ; Store value in table PUSH 4 POP 0 MOV [R0],A MOV R0,A ACALL I2C_SEND CLR C SJMP ?prxclrbitok ?prxclrbiterr SETB C ?prxclrbitok ACALL I2C_STOP ACALL I2C_START ACALL I2C_STOP POP 4 POP 3 RET clrsda PUSH PSW PUSH A PUSH 0 PUSH 1 MOV R0,proxyadres ; MOV R1,#PRXSDA MOV A,proxyoffs ; * 2 RL A ANL A,#7 MOV R1,A MOV R2,#0 ACALL prxbit POP 1 POP 0 POP A POP PSW RET setsda PUSH PSW PUSH A PUSH 0 PUSH 1 ACALL PRXSLOW MOV R0,proxyadres ; MOV R1,#PRXSDA MOV A,proxyoffs ; * 2 RL A ANL A,#7 MOV R1,A MOV R2,#1 ACALL prxbit POP 1 POP 0 POP A POP PSW RET clrscl PUSH PSW PUSH A PUSH 0 PUSH 1 ACALL PRXSLOW MOV R0,proxyadres ; MOV R1,#PRXSCL MOV A,proxyoffs ; * 2 RL A INC A ANL A,#7 MOV R1,A MOV R2,#0 ACALL prxbit POP 1 POP 0 POP A POP PSW RET setscl PUSH PSW PUSH A PUSH 0 PUSH 1 MOV R0,proxyadres ; MOV R1,#PRXSCL MOV A,proxyoffs ; * 2 RL A INC A ANL A,#7 MOV R1,A MOV R2,#1 ACALL prxbit POP 1 POP 0 POP A POP PSW RET ; result : Carry: 0 or 1 and SDARBIT 0 or 1 getsda PUSH A PUSH 3 PUSH 1 PUSH 0 ACALL PRXSLOW MOV DPTR,#MASKER MOV A,proxyoffs RL A MOVC A,[A+DPTR] MOV R3,A MOV A,proxyadres CLR C SUBB A,#8 JC ?getsda1 ; Heck, it's a PCF8574A MOV A,proxyadres ADD A,#38H-8 SJMP ?getsda2 ?getsda1 MOV A,proxyadres ADD A,#20H ?getsda2 MOV R0,A MOV A,#1 ; Read MODE ACALL I2C_ADRES ; Start transfer JC ?getsdaerr MOV A,#1 ; No ACK ACALL I2C_READ ?getsdaerr PUSH PSW ACALL I2C_STOP ACALL I2C_START ACALL I2C_STOP POP PSW MOV A,R0 ANL A,R3 CLR C CLR SDARBIT CJNE A,3,?getsda3 SETB C SETB SDARBIT ?getsda3 POP 0 POP 1 POP 3 POP A RET ; result : Carry: 0 or 1 and SCLRBIT 0 or 1 getscl PUSH A PUSH 3 PUSH 1 PUSH 0 ACALL PRXSLOW MOV DPTR,#MASKER MOV A,proxyoffs RL A INC A MOVC A,[A+DPTR] MOV R3,A MOV A,proxyadres CLR C SUBB A,#8 JC ?getscl1 ; Heck, it's a PCF8574A MOV A,proxyadres ADD A,#38H-8 SJMP ?getscl2 ?getscl1 MOV A,proxyadres ADD A,#20H ?getscl2 MOV R0,A MOV A,#1 ; Read MODE ACALL I2C_ADRES ; Start transfer JC ?getsclerr MOV A,#1 ; No ACK ACALL I2C_READ ?getsclerr PUSH PSW ACALL I2C_STOP ACALL I2C_START ACALL I2C_STOP POP PSW MOV A,R0 ANL A,R3 CLR C CLR SCLRBIT CJNE A,3,?getscl3 SETB C SETB SCLRBIT ?getscl3 POP 0 POP 1 POP 3 POP A RET ;****************************************************************************** ;** ** ;** I2C-BUS CONTROLLER V1.00 by PE1MTH ** ;** Theo Gosselink JR. ** ;** ** ;** Last update : 17-10-1999 ** ;** ** ;****************************************************************************** ;** ** ;** P1_6 -> SCL ** ;** P1_7 -> SDA ** ;** ** ;** ** ;** ** ;** ** ;** ** ;** ** ;****************************************************************************** ;>>>>> SCL = 96H -> P1.6 ;>>>>> SDA = 97H -> P1.7 SCL: EQU P1.6 SDA: EQU P1.7 ;>>>>> PCF8574 = 8 BIT I/O EXTENDER (PIO) ;>>>>> PCF8573 = CLOCK CALENDER PCF8574: EQU 20H XR24C02: EQU 50H TSA5511: EQU 61H I2C_START: CLR SCL SETB SDA JB SDA,I2C_STRT_1 SJMP I2C_START I2C_STRT_1: SETB SCL JNB SCL,I2C_STRT_1 ; IF SCL ACTIVE THEN MULTI-MASTER ACTIVE NOP CLR SDA NOP CLR SCL RET I2C_STOP: CLR SDA NOP NOP SETB SCL NOP NOP SETB SDA RET ;******************************************** ;** ** ;** I2C_ADRES ** ;** ** ;** A = 0 : WRITE , A = 1 : READ ** ;** R0 -> ADRES ** ;** ** ;** RETOUR : ** ;** C <- ACK 0 = ACK 1 = NO ACK ** ;******************************************** I2C_ADRES: PUSH 1 PUSH A MOV A,R0 POP 0 ACALL I2C_START MOV R1,#8 RL A ORL A,#1 CJNE R0,#0,I2C_ADRES1 ANL A,#0FEH I2C_ADRES1: RLC A SETB SDA JC I2C_ADRES2 CLR SDA I2C_ADRES2: ACALL I2C_CLOCK DJNZ R1,I2C_ADRES1 SETB SDA NOP NOP CLR C JNB SDA,I2C_ADRES3 SETB C ; ACALL I2C_ACK I2C_ADRES3: ACALL I2C_CLOCK POP 1 RET I2C_CLOCK: NOP SETB SCL ; Got to wait until SCL is really high... ?I2C_CLOCK: JNB SCL,?I2C_CLOCK NOP CLR SCL NOP RET ;******************************************** ;** ** ;** I2C_SEND ** ;** ** ;** R0 -> DATA ** ;** C <- ACK ** ;** ** ;******************************************** I2C_SEND: PUSH 1 MOV A,R0 MOV R1,#8 I2C_SEND1: RLC A SETB SDA JC I2C_SEND2 CLR SDA I2C_SEND2: ACALL I2C_CLOCK DJNZ R1,I2C_SEND1 SETB SDA NOP CLR C JNB SDA,I2C_SEND3 SETB C ; ACALL I2C_ACK I2C_SEND3: ACALL I2C_CLOCK POP 1 RET ;******************************************** ;** ** ;** I2C_READ ** ;** ** ;** A -> ACK 0 = ACK 1 = NO ACK ** ;** R0 <- DATA ** ;** ** ;******************************************** I2C_READ: PUSH 1 PUSH A CLR SCL NOP SETB SDA NOP MOV R1,#8 I2C_READ1: SETB SCL NOP CLR C JNB SDA,I2C_READ2 SETB C I2C_READ2: RLC A CLR SCL NOP DJNZ R1,I2C_READ1 MOV R0,A POP A CJNE A,#0,I2C_READ3 ;** SEND ACK ! ** CLR SDA I2C_READ3: NOP SETB SCL POP 1 RET ;******************************************** ;** ** ;** I2C_ACK ** ;** ** ;** A -> ACK 0 = ACK 1 = NO ACK ** ;** ** ;** IF NO ACK THEN PRINT ERROR... ** ;** ** ;******************************************** I2C_ACK: RET ;******************************************** ;** ** ;** I2C_INIT ** ;** ** ;******************************************** I2C_INIT: ACALL I2C_START ACALL I2C_STOP ; SETUP I2C_BUS VERKEER (EERSTE KEER) RET ;*************************************************** ;** ** ;** Proxy I2C ** ;** ** ;*************************************************** PRXI2C_START: ACALL clrscl ACALL setscl ACALL clrscl ACALL clrscl ACALL setsda ACALL getsda JC PRXI2C_STRT_1 SJMP PRXI2C_START PRXI2C_STRT_1 ACALL setscl ACALL clrsda ACALL clrscl RET PRXI2C_STOP: ACALL clrsda ACALL setscl ACALL setsda RET ;******************************************** ;** ** ;** I2C_ADRES ** ;** ** ;** A = 0 : WRITE , A = 1 : READ ** ;** R0 -> ADRES ** ;** ** ;** RETOUR : ** ;** C <- ACK 0 = ACK 1 = NO ACK ** ;******************************************** PRXI2C_ADRES: PUSH 1 PUSH A MOV A,R0 POP 0 ACALL PRXI2C_START MOV R1,#8 RL A ORL A,#1 CJNE R0,#0,PRXI2C_ADRES1 ANL A,#0FEH PRXI2C_ADRES1: RLC A ACALL setsda JC PRXI2C_ADRES2 ACALL clrsda PRXI2C_ADRES2: ACALL PRXI2C_CLOCK DJNZ R1,PRXI2C_ADRES1 ACALL setsda ACALL setscl ; Got to wait until SCL is really high... ?PRXI2C_CLOCKW: ACALL getscl JNB SCLRBIT,?PRXI2C_CLOCKW ACALL getsda ACALL clrscl CLR C JNB SDARBIT,PRXI2C_ADRES3 SETB C PRXI2C_ADRES3 POP 1 RET PRXI2C_CLOCK: ACALL setscl NOP ACALL clrscl RET ;******************************************** ;** ** ;** I2C_SEND ** ;** ** ;** R0 -> DATA ** ;** C <- ACK ** ;** ** ;******************************************** PRXI2C_SEND: PUSH 1 MOV A,R0 MOV R1,#8 PRXI2C_SEND1: RLC A ACALL setsda JC PRXI2C_SEND2 ACALL clrsda PRXI2C_SEND2: ACALL PRXI2C_CLOCK DJNZ R1,PRXI2C_SEND1 ACALL setsda CLR C ACALL getsda ACALL PRXI2C_CLOCK CLR C JNB SDARBIT,PRXI2C_SEND3 SETB C PRXI2C_SEND3: POP 1 RET ;******************************************** ;** ** ;** I2C_READ ** ;** ** ;** A -> ACK 0 = ACK 1 = NO ACK ** ;** R0 <- DATA ** ;** ** ;******************************************** PRXI2C_READ: PUSH 1 PUSH A ACALL clrscl ACALL setsda MOV R1,#8 PRXI2C_READ1: ACALL setscl ACALL getsda CLR C JNB SDARBIT,PRXI2C_READ2 SETB C PRXI2C_READ2: RLC A ACALL clrscl DJNZ R1,PRXI2C_READ1 MOV R0,A POP A CJNE A,#0,PRXI2C_READ3 ;** SEND ACK ! ** ACALL clrsda PRXI2C_READ3: NOP ACALL setscl POP 1 RET ;******************************************** ;** ** ;** I2C_ACK ** ;** ** ;** A -> ACK 0 = ACK 1 = NO ACK ** ;** ** ;** IF NO ACK THEN PRINT ERROR... ** ;** ** ;******************************************** PRXI2C_ACK: RET ;******************************************** ;** ** ;** I2C_INIT ** ;** ** ;******************************************** PRXI2C_INIT: ACALL PRXI2C_START ACALL PRXI2C_STOP ; SETUP I2C_BUS VERKEER (EERSTE KEER) RET PRXSLOW RET PUSH 5 PUSH 6 MOV R5,#100 ?PRXSLOW1 MOV R6,#0 ?PRXSLOW2 INC DPTR DJNZ R6,?PRXSLOW2 DJNZ R5,?PRXSLOW1 POP 6 POP 5 RET ; ***** SERIAL INTERRUPT SERVER ?SI1 EQU * ORG 23H LJMP ?SI1 ORG ?SI1 PUSH PSW PUSH ACC PUSH 0 ;*** Check for receiver data JNB SCON.0,?SI3 ; Sorry, no data to receive MOV R0,SERReadPtrW CLR SCON.0 MOV [R0],SBUF INC R0 CJNE R0,#SERReadBuf+20,?SI2 MOV R0,#SERReadBuf ?SI2 MOV SERReadPtrW,R0 ;*** Check for transmit data ?SI3 JNB SCON.1,?SI3A ; Sorry, no data to transmit CLR SCON.1 ; Stop ontvanger MOV A,SERWritePtrR CJNE A,SERWritePtrW,?SI4 ; Nog wat te zenden? CLR SCON.3 ; Stop zender ?SI3A POP 0 POP ACC POP PSW RETI ?SI4 MOV R0,A MOV SBUF,[R0] INC R0 CJNE R0,#SERWriteBuf+16,?SI5 MOV R0,#SERWriteBuf ?SI5 MOV SERWritePtrR,R0 SETB SCON.3 ; Start zender SJMP ?SI3A infotxt STR '[RS232<->I2C]MTH' DB 13,0 identtxt STR '?[I2C]Ok' DB 13,0 MASKER DB 1,2,4,8,16,32,64,128,128 ORG $0008 SERReadPtrR DS 1 SERReadPtrW DS 1 SERReadBuf DS 20 SERWritePtrR DS 1 SERWritePtrW DS 1 SERWriteBuf DS 16 pcf8574table DS 16 proxyadres DS 1 proxyoffs DS 1 I2CADRES DS 1 ?stk EQU * ; End of allocated memory