??? 04/04/07 15:37 Read: times |
#136607 - Working code... Responding to: ???'s previous message |
Hello Asif,
Here is a piece of working code which was used along with C, hope it solves your problem.This was used with an AT89C51 and AT24C04. If I can recall correctly, I put this together from Philips and Atmel application notes. You can you use the assembler portion alone with modificaton. $NOMOD51 $INCLUDE (REG515.INC) NAME I2C ;name of the program module ;FILE NAME - I2C.A51 ;----------------------------------------------------------------------------- ; THIS MODULE CONTAINS THE I2C DRIVER ROUTINES ; 27/08/98,07/12/98 ;----------------------------------------------------------------------------- ?PR?ReadWriteI2c?I2C SEGMENT CODE ;segment for program code ?DT?ReadWriteI2c?I2C SEGMENT DATA OVERLAYABLE ;segment for local variables ?BI?ReadWriteI2c?I2C SEGMENT BIT OVERLAYABLE ;segment for local bit var PUBLIC _ReadWriteI2c ;public symbols PUBLIC ?_ReadWriteI2c?BYTE ;for 'C' PUBLIC ?_ReadWriteI2c?BIT ;function calls RSEG ?DT?ReadWriteI2c?I2C ;segment for local variables ?_ReadWriteI2c?BYTE: ;start of parameter passing ;segment i2c_slave_address: ds 1 i2c_register_address: ds 1 write_i2c_data: ds 1 RSEG ?BI?ReadWriteI2c?I2C ;segment for local bit var ?_ReadWriteI2c?BIT: ;start of parameter passing ;segment read_write_flag: dbit 1 ;---------------------------------------------------------------------------- ; I2C PORT PIN DEFINITIONS ;---------------------------------------------------------------------------- SDA EQU P3.6 SCL EQU P3.7 RSEG ?PR?ReadWriteI2c?I2C USING 0 _ReadWriteI2c: ;---------------------------------------------------------------------------- ; 08/12/98 ; CHECK WHETHER READ OR WRITE ; IF CY = 1 THEN IT IS READ, IF CY = 0 THEN IT IS WRITE ;---------------------------------------------------------------------------- JB CY, READ_I2C_REGISTER JMP WRITE_I2C_REGISTER ;---------------------------------------------------------------------------- ; LOW LEVEL I2C MACROS ;---------------------------------------------------------------------------- SET_SCL MACRO SETB SCL JNB SCL,$ BIT_DELAY ENDM CLEAR_SCL MACRO CLR SCL BIT_DELAY ENDM EMIT_CLOCK MACRO SET_SCL CLEAR_SCL ENDM START MACRO SETB SDA SET_SCL CLR SDA BIT_DELAY CLEAR_SCL ENDM STOP MACRO CLR SDA SET_SCL SETB SDA BIT_DELAY ENDM BIT_DELAY MACRO NOP NOP ;NOP ;04/02/2003 for 24Mhz ENDM ;---------------------------------------------------------------------------- ; I2C SUBROUTINES ;---------------------------------------------------------------------------- XMIT_BYTE: ;ACC CONTAINS BYTE TO TRANSMIT ;CY= 0 IF SEQUENCE COMPLETES ;CY= 1 IF UNABLE TO TRANSMIT MOV R1,#8 ;8 BITS TO SEND XB1: RLC A MOV SDA, C ;PUT BIT ON PIN EMIT_CLOCK ;EMIT CLOCK PULSE DJNZ R1,XB1 ;LOOP UNTIL DONE ;SETUP TO ACK FROM SLAVE DEVICE SETB SDA ;RELEASE DATA PIN SET_SCL ;SCL HIGH JNB SDA,XB2 ;JUMP IF ACK SEEN CLEAR_SCL ;DROP SCL SETB C ;SET ERROR CODE RET XB2: CLEAR_SCL ;DROP SCL CLR C ;SET COMPLETION CODE RET ;---------------------------------------------------------------------------- REC_BYTE: ;RECEIVE A BYTE OVER THE I2C BUS ;ACC CONTAINS RECEIVED BYTE ;CY IS DUMMIED UP WITH A 0 MOV R1,#8 ;8 BITS TO RECEIVE RB1: SET_SCL ;SCL HIGH MOV C,SDA ;PICK BIT OFF A PIN RLC A CLEAR_SCL ;SCL LOW DJNZ R1,RB1 ;MORE BITS TO RECEIVE? CLR C ;MUST COMPLETE OK RET ;---------------------------------------------------------------------------- ; TRANMIT ADDRESS AND DATA REGISTERED BYTE OVER I2C BUS ; R7 CONTAINS SLAVE ADDRESS ; R5 CONTAINS REGISTER ADDRESS ; R3 CONTAINS DATA BYTE ; CY = 0 IF SEQUENCE COMPLETES ; CY = 1 IF UNABLE TO TRANSMIT ;---------------------------------------------------------------------------- XD_FAULT: ;BUS FAULTL SETB C ;SET ERROR CODE RET WRITE_I2C_REGISTER: JNB SCL,XD_FAULT JNB SDA,XD_FAULT ;JUMP IF BUS FAULT MOV A,R7 ;SETUP SLAVE ADDRESS CLR ACC.0 ;INDICATE WRITE OPERATION START ;SET START CONDITION ACALL XMIT_BYTE ;SEND SLAVE ADDRESS JC XD2 ;JUMP ON ERROR MOV A,R5 ;SETUP REGISTER ADDRESS ACALL XMIT_BYTE ;SEND REGISTER ADDRESS JC XD2 ;JUMP ON ERROR MOV A,R3 ;SETUP DATA BYTE ACALL XMIT_BYTE ;GO SEND ; SET STOP CONDITION, RETURN CODE IS ALREADY IN CY XD2: STOP ;SET STOP CONDITION RET ;---------------------------------------------------------------------------- ; TRANSMIT ADDRESS AND RECEIVE REGISTERED DATA BYTE OVER I2C BUS ; R7 CONTAINS SLAVE ADDRESS ; R5 CONTAINS REGISTER ADDRESS ; CY = 0 IF SEQUENCE COMPLETES ; CY = 1 IF UNABLE TO RECEIVE ; R3 CONTAINS RECEIVED BYTE IF CY = 0 ;---------------------------------------------------------------------------- RD_FAULT: SETB C ;SET ERROR CONDITION RET READ_I2C_REGISTER: JNB SCL,RD_FAULT JNB SDA,RD_FAULT ;JUMP IF BUS FAULT MOV A,R7 ;SETUP SLAVE ADDRESS CLR ACC.0 ;INDICATE READ OPERATION START PUSH ACC ACALL XMIT_BYTE ;SEND SLAVE ADDRESS POP ACC JC RD3 ;JUMP ON ERROR XCH A,R5 ;SET UP REGISTER ADDRESS ACALL XMIT_BYTE ;SEND REGISTER ADDRESS JC RD3 ;JUMP ON ERROR START ;SET REPEATED START MOV A,R7 ;SETUP SLAVE ADDRESS SETB ACC.0 ;INDICATE READ OPERATION ACALL XMIT_BYTE ;SEND SLAVE ADDRESS AGAIN JC RD3 ;JUMP ON ERROR RD1: ACALL REC_BYTE ;GO RECEIVE MOV R7,A ;STORE DATE BYTE ;SEQUENCE COMPLETE, RETURN CODE IS ALREADY IN CY RD2: SETB SDA ;SET SDA IDLE EMIT_CLOCK ;EMIT CLOCK PULSE RD3: STOP ;SET STOP CONDITION RET END John. |