Serial memory devices offer significant advantages over parallel devices in applications where lower data transfer rates are acceptable. In addition to requiring less board space, serial devices allow microcontroller I/O pins to be conserved. This is especially valuable when adding external memory to low pin count microcontrollers such as the Atmel AT89C1051 and AT89C2051. This application note presents a suite of
software routines which may be incorporated into a user’s application to allow an AT89C51 microcontroller to read and write AT24CXX serial EEPROMs. The software supports all members of the AT24CXX family, and may easily be modified for compatibility with any of the Atmel 8051-code compatible microcontrollers.
Hardware
A typical interconnection between an AT89CX051 microcontroller and an AT24CXX serial EEPROM is shown in Figure 1.
Figure 1:
As indicated in the figure, up to eight members of the AT24CXX family may share the bus, utilizing the same two microcontroller I/O pins. Each device on the bus must have its address inputs
(A0, A1, A2) hard-wired to a unique address. In the figure, the first device recognizes address zero (A0, A1, A2 tied low), whi le the eighth recognizes address seven (A0, A1, A2 tied high). Not all members of the AT24CXX family recognize all three address inputs, limiting the number of some devices which may be present to less than eight. The exact number of devices of each type which may share the bus is shown in
Table 1.
Table 1:
Assembly Language Program:
This code is written in ProgStudio. This code is tested
software routines which may be incorporated into a user’s application to allow an AT89C51 microcontroller to read and write AT24CXX serial EEPROMs. The software supports all members of the AT24CXX family, and may easily be modified for compatibility with any of the Atmel 8051-code compatible microcontrollers.
Hardware
A typical interconnection between an AT89CX051 microcontroller and an AT24CXX serial EEPROM is shown in Figure 1.
Figure 1:
As indicated in the figure, up to eight members of the AT24CXX family may share the bus, utilizing the same two microcontroller I/O pins. Each device on the bus must have its address inputs
(A0, A1, A2) hard-wired to a unique address. In the figure, the first device recognizes address zero (A0, A1, A2 tied low), whi le the eighth recognizes address seven (A0, A1, A2 tied high). Not all members of the AT24CXX family recognize all three address inputs, limiting the number of some devices which may be present to less than eight. The exact number of devices of each type which may share the bus is shown in
Table 1.
Table 1:
Assembly Language Program:
INCLUDE 89C51.MC ;-----------------------AT24CXXX --------------------------- ;24CXXX connections to microcontroller SDA EQU P0.0 ; serial data SCL EQU P0.1 ; serial clock ;----------------------------------------------------------- ; Register definitions. DATA EQU 01h ; data ADDR_HI EQU 03h ; address higher ADDR_LO EQU 02h ; address lower BUFFER EQU 04h ; read data buffer ;----------------------------------------------------------- on_reset: CLR C ; clear error flag MOV A,#00H ; device address MOV ADDR_HI,#00H ; address higher byte MOV ADDR_LO,#10H ; address lower byte MOV DATA,#45H ; data to be writen CALL write_byte ;----------------------------------------------------------- ; I2C WRITING ;----------------------------------------------------------- write_byte: ; AT24Cxx Byte Write function. ; Called with programmable address in A, byte address in ; register pair ADDR_HI:ADDR_LO(R3:R2), data in register R1. ; Does not wait for write cycle to complete. ; Returns CY set to indicate that the bus is not available ; or that the addressed device failed to acknowledge. ; Destroys A. call start JC x49 ; abort if bus not available RL A ; programmable address to bits 3:1 ORL A,#A0H ; add fixed address CLR acc.0 ; specify write operation call shout ; send device address JC x48 ; abort if no acknowledge MOV A,ADDR_HI ; send high byte of address call shout ; JC x48 ; abort if no acknowledge MOV A,ADDR_LO ; send low byte of address call shout ; JC x48 ; abort if no acknowledge MOV A,DATA ; get data call shout ; send data call i2c_delay ; self write cycle JC x48 ; abort if no acknowledge CLR C ; clear error flag x48: call STOP call i2c_delay x49: RET ;----------------------------------------------------------- ; I2C READING ;----------------------------------------------------------- read_block: ; Read from one byte to one page of data from an AT24Cxx. ; Performs a Random Read which is extended into a Sequential Read ; when more than one byte is read. Called with programmable address ; in A, address of first byte in register pair R3:R2, ; Returns data in BUFFER. Returns CY set to indicate that the bus is ; not available or that the addressed device failed to acknowledge. ; Destroys A, R1, R0. ; Send dummy write command to address first byte. Call start JC x35 ; abort if bus not available RL A ; programmable address to bits 3:1 ORL A,#A0H ; add fixed address MOV R0, A ; save copy of device address CLR acc.0 ; specify write operation call shout ; send device address JC x34 ; abort if no acknowledge MOV A,ADDR_HI ; send high byte of address call shout ; JC x34 ; abort if no acknowledge MOV A,ADDR_LO ; send low byte of address call shout ; JC x34 ; abort if no acknowledge ; Send read command and receive data. call start ; second start for read JC x34 ; abort if bus not available MOV A, R0 ; get device address SETB acc.0 ; specify read operation call shout ; send device address JC x34 ; abort if no acknowledge x31: call shin ; receive data byte call NAK ; do not acknowledge last byte jmp x33 ; done x33: CLR C ; clear error flag MOV BUFFER,A ; get data in buffer x34: call stop x35: RET ;----------------------------------------------------------- ; SHIFT OUT A BYTE TO I2C ;----------------------------------------------------------- shout: ; Shift out a byte to the AT24Cxx, most significant bit first. ; SCL, SDA expected low on entry. Return with SCL low. ; Called with data to send in A. ; Returns CY set to indicate failure by slave to acknowledge. ; Destroys A. PUSH B MOV B, #8 ; bit counter x42: RLC A ; move bit into CY MOV SDA, C ; output bit NOP ; enforce SCL low and data setup SETB SCL ; raise clock NOP ; enforce SCL high NOP ; NOP ; NOP ; CLR SCL ; drop clock DJNZ B, x42 ; next bit SETB SDA ; release SDA for ACK NOP ; enforce SCL low and tAA NOP ; SETB SCL ; raise ACK clock NOP ; enforce SCL high NOP ; NOP ; NOP ; MOV C, SDA ; get ACK bit CLR SCL ; drop ACK clock POP B RET ;----------------------------------------------------------- ; SHIFT IN A BYTE FROM I2C ;----------------------------------------------------------- shin: ; Shift in a byte from the AT24Cxx, most significant bit first. ; SCL expected low on entry. Return with SCL low. ; Returns received data byte in A. SETB SDA ; make SDA an input PUSH B MOV B, #8 ; bit count x43: NOP ; enforce SCL low and data setup NOP ; NOP ; SETB SCL ; raise clock NOP ; enforce SCL high NOP ; MOV C, SDA ; input bit RLC A ; move bit into byte CLR SCL ; drop clock DJNZ B, x43 ; next bit POP B RET ;----------------------------------------------------------- ; I2C ACKNOWLEDGE ;----------------------------------------------------------- ACK: ; Clock out an acknowledge bit (low). ; SCL expected low on entry. Return with SCL, SDA low. CLR SDA ; ACK bit NOP ; enforce SCL low and data setup NOP ; SETB SCL ; raise clock NOP ; enforce SCL high NOP ; NOP ; NOP ; CLR SCL ; drop clock RET ;----------------------------------------------------------- ; I2C NO ACKNOWLEDGE ;----------------------------------------------------------- NAK: ; Clock out a negative acknowledge bit (high). ; SCL expected low on entry. Return with SCL low, SDA high. SETB SDA ; NAK bit NOP ; enforce SCL low and data setup NOP ; SETB SCL ; raise clock NOP ; enforce SCL high NOP ; NOP ; NOP ; CLR SCL ; drop clock RET ;----------------------------------------------------------- ; I2C START PULSE ;----------------------------------------------------------- start: ; Send START, defined as high-to-low SDA with SCL high. ; Return with SCL, SDA low. ; Returns CY set if bus is not available. SETB SDA NOP NOP NOP SETB SCL ; Verify bus available. CALL i2c_delay JNB SDA, x40 ; jump if not high NOP NOP JNB SCL, x40 ; jump if not high NOP ; enforce setup delay and cycle delay CLR SDA NOP ; enforce hold delay NOP ; NOP ; NOP ; NOP ; CLR SCL CLR C ; clear error flag JMP x41 x40: SETB C ; set error flag x41: RET ;----------------------------------------------------------- ; I2C STOP PULSE ;----------------------------------------------------------- Stop: ; Send STOP, defined as low-to-high SDA with SCL high. ; SCL expected low on entry. Return with SCL, SDA high. CLR SDA NOP ; enforce SCL low and data setup nop SETB SCL NOP ; enforce setup delay NOP NOP NOP NOP SETB SDA RET ;---------------------------------------------------------- i2c_delay: MOV R7,#FFH i2cloop: NOP NOP NOP DJNZ R7, i2cloop RET ;----------------------------------------------------------
This code is written in ProgStudio. This code is tested
No comments:
Post a Comment