共2条
1/1 1 跳转至页
89CXX,EEPROM,AT24CXX,ATMEL 分享:89CXX单片机与EEPROM-AT24CXX汇编程序-来自ATMEL官方
问
NAME Control_AT24Cxx
; This collection of routines allows an AT89C2051 microcontroller to read
; and write the AT24Cxx family of serial CMOS EEPROMS. This version of the
; code is compatible only with the AT89C2051 due to the location of the
; data buffer and stack in RAM. The code may be modified to work with the
; AT89C1051 by relocating or resizing the buffer and stack to fit into the
; smaller amount of RAM available in the AT89C1051. Note that the minimum
; size of the buffer is determined by the page size of the AT24Cxx.
;
; All five AT24Cxx device operations are supported. Byte Write, Current
; Address Read and Random Read are implemented by the functions WRITE_BYTE,
; READ_CURRENT and READ_RANDOM, respectively. Page Write and Sequential Read
; are special cases of functions WRITE_BLOCK and READ_BLOCK, respectively.
; WRITE_BLOCK and READ_BLOCK process from one byte to the number of bytes
; in a page and transfer data between the AT24Cxx and the RAM buffer.
;
; The code supports multiple AT24Cxx devices per bus, each with a unique
; address determined by the wiring of the address pins (A0, A1, A2). The
; three-bit programmable address is passed to the WRITE_BYTE, READ_CURRENT,
; READ_RANDOM, WRITE_BLOCK and READ_BLOCK functions, where it is combined
; with the AT24Cxx fixed address (FADDR) and used to address a device on the
; bus. Refer to the AT24Cxx family data sheets for additional information on
; device addressing.
;
; Functions BYTE_FILL, VERIFY_BYTE_FILL, PAGE_FILL and VERIFY_PAGE_FILL are
; artifacts from the debug process and serve to illustrate the use of the
; device read and write functions with an AT24C64. To modify the code for a
; different member of the AT24Cxx family, simply redefine the values of SIZE
; (the number of bytes per device) and PSIZE (the number of bytes per page).
; To change the fill value, redefine FILL. To change the programmable portion
; of the device address, redefine PADDR to a value from zero to seven.
;
; The code meets all AT24Cxx family timing requirements when executed by an
; AT89Cx051 microcontroller with a 12 MHz clock. Code modifications may be
; required if a faster clock is substituted.
FADDR EQU 0a0h ; fixed address for AT24Cxx EEPROMs
PADDR EQU 0 ; programmable address (0..7)
SIZE EQU 2000h ; bytes per AT24C64
PSIZE EQU 32 ; bytes per page for AT24C64
FILL EQU 55h ; example fill value
; Register definitions.
index EQU r0 ; buffer pointer
kount EQU r1 ; byte count register
zdata EQU r1 ; data register
addr_lo EQU r2 ; 2-byte address register
addr_hi EQU r3 ;
; Microcontroller connections to AT24Cxx serial bus lines.
SCL BIT p1.2 ; serial clock
SDA BIT p1.3 ; serial data
DSEG AT 20H
ORG 40H
buffer: DS PSIZE ; storage for read/write data
ORG 60H ; stack origin
stack: DS 20H ; stack depth
CSEG
ORG 0000H ; power on/reset vector
jmp on_reset
ORG 0003H ; external interrupt 0 vector
reti ; undefined
ORG 000BH ; timer 0 overflow vector
reti ; undefined
ORG 0013H ; external interrupt 1 vector
reti ; undefined
ORG 001BH ; timer 1 overflow vector
reti ; undefined
ORG 0023H ; serial I/O interrupt vector
reti ; undefined
ORG 0080H ; begin code space
USING 0 ; register bank zero
on_reset:
mov sp, #(stack-1) ; initialize stack pointer
; Initialize AT24Cxx serial bus lines.
setb SDA ; high
setb SCL ; high
call byte_fill
jc fault
call verify_byte_fill
jc fault
call page_fill
jc fault
call verify_page_fill
jc fault
fault:
jmp $
byte_fill:
; Fill every byte in an AT24Cxx with the same value.
; Writes one address at a time (page mode is not used).
; Returns CY set to indicate write timeout.
; Destroys A, B, DPTR, XDATA, ADDR_HI:ADDR_LO.
mov zdata, #FILL ; set up fill data
mov dptr, #0 ; initialize address pointer
x51:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov b, #120 ; retry counter
x52:
mov a, #PADDR ; programmable address
call write_byte ; try to write
jnc x53 ; jump if write OK
djnz b, x52 ; try again
setb c ; set timeout error flag
jmp x54 ; exit
x53:
inc dptr ; advance address pointer
; mov a, dpl ; check low byte
; cjne a, #(LOW SIZE), x51 ; jump if not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x51 ; jump if not last
clr c ; clear error flag
x54:
ret
verify_byte_fill:
; Verify that all bytes in an AT24Cxx match a fill value.
; Reads and verifies one byte at a time (page mode is not used).
; Performs a Random Read function to initialize the internal
; address counter and checks the contents of the first address.
; Then performs multiple Current Address Read functions to step
; through the remaining addressess.
; Returns CY set to indicate read timeout or compare fail.
; Destroys A, B, DPTR.
mov dptr, #0 ; initialize address pointer/counter
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov b, #120 ; retry counter
x81:
mov a, #PADDR ; programmable address
call read_random ; try to read
jnc x82 ; jump if read OK
djnz b, x81 ; try again
jmp x86 ; set error flag and exit
x82:
cjne a, #FILL, x86 ; jump if compare error
jmp x85 ; do remaining addresses
x83:
mov a, #PADDR
call read_current
jc x87 ; jump if read fails
cjne a, #FILL, x86 ; jump if compare error
x85:
inc dptr ; advance address pointer
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x83 ; jump if not last
clr c ; clear error flag
jmp x87 ; exit
x86:
setb c ; set error flag
x87:
ret
page_fill:
; Fill every byte in an AT24Cxx with the same value.
; Writes one page at a time.
; Returns CY set to indicate write timeout.
; Destroys A, B, DPTR, KOUNT, INDEX, ADDR_HI:ADDR_LO.
; First fill buffer.
mov b, #PSIZE ; bytes per page
mov index, #buffer ; point to buffer
x61:
mov @index, #FILL ; put fill value in buffer
inc index ; advance pointer
djnz b, x61 ; next byte
; Copy buffer to device, one page at a time.
mov dptr, #0 ; initialize address pointer
x62:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov kount, #PSIZE ; bytes per page
mov b, #120 ; retry counter
x63:
mov a, #PADDR ; programmable address
call write_block ; try to write
jnc x64 ; jump if write OK
djnz b, x63 ; try again
setb c ; set timeout error flag
jmp x66 ; exit
x64:
; Add page size to address pointer.
mov a, dpl ; get low byte
add a, #PSIZE ; add page size
mov dpl, a ; save low byte
jnc x65 ; jump if high byte not affected
inc dph ; increment high byte
x65:
; cjne a, #(LOW SIZE), x62 ; jump if low byte not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x62 ; jump if not last
clr c ; clear error flag
x66:
ret
verify_page_fill:
; Verify that all bytes in an AT24Cxx match a fill value.
; Reads and verifies one page at a time.
; Returns CY set to indicate read timeout or compare fail.
; Destroys A, B, DPTR, KOUNT, INDEX, ADDR_HI:ADDR_LO.
; Copy device page to buffer.
mov dptr, #0 ; initialize address pointer
x71:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov kount, #PSIZE ; bytes per page
mov b, #120 ; retry counter
x72:
mov a, #PADDR ; programmable address
call read_block ; try to read
jnc x74 ; jump if read OK
djnz b, x72 ; try again
x73:
setb c ; set error flag
jmp x77 ; exit
x74:
; Verify buffer contents.
mov b, #PSIZE ; bytes per page
mov index, #buffer ; point to buffer
x75:
cjne @index, #FILL, x73 ; jump if compare fails
inc index ; advance pointer
djnz b, x75 ; next byte
; Add page size to address pointer.
mov a, dpl ; get low byte
add a, #PSIZE ; add page size
mov dpl, a ; save low byte
jnc x76 ; jump if high byte not affected
inc dph ; increment high byte
x76:
; cjne a, #(LOW SIZE), x71 ; jump if low byte not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x71 ; jump if not last
clr c ; clear error flag
x77:
ret
write_block:
; Write from one byte to one page of data to an AT24Cxx.
; Called with programmable address in A, address of first byte
; in register pair ADDR_HI:ADDR_LO, data in BUFFER, byte count
; in register KOUNT.
; 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, KOUNT, INDEX.
call start
jc x38 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
clr acc.0 ; specify write operation
call shout ; send device address
jc x37 ; abort if no acknowledge
mov a, addr_hi ; send high byte of address
call shout ;
jc x37 ; abort if no acknowledge
mov a, addr_lo ; send low byte of address
call shout ;
jc x37 ; abort if no acknowledge
mov index, #buffer ; point to buffer
x36:
mov a, @index ; get data
call shout ; send data
jc x37 ; abort if no acknowledge
inc index ; advance buffer pointer
djnz kount, x36 ; next byte
clr c ; clear error flag
x37:
call stop
x38:
ret
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 ADDR_HI:ADDR_LO,
; byte count in register KOUNT.
; 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, KOUNT, INDEX.
; 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, #FADDR ; add fixed address
mov index, 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, index ; get device address
setb acc.0 ; specify read operation
call shout ; send device address
jc x34 ; abort if no acknowledge
mov index, #buffer ; point to buffer
x31:
call shin ; receive data byte
mov @index, a ; save data
cjne kount, #1, x32 ; jump if not last byte
call NAK ; do not acknowledge last byte
jmp x33 ; done
x32:
call ACK ; acknowledge byte
inc index ; advance buffer pointer
djnz kount, x31 ; next byte
x33:
clr c ; clear error flag
x34:
call stop
x35:
ret
write_byte:
; AT24Cxx Byte Write function.
; Called with programmable address in A, byte address in
; register pair ADDR_HI:ADDR_LO, data in register XDATA.
; 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, #FADDR ; 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, zdata ; get data
call shout ; send data
jc x48 ; abort if no acknowledge
clr c ; clear error flag
x48:
call stop
x49:
ret
read_current:
; AT24Cxx Current Address Read function.
; Called with programmable address in A. Returns data in A.
; Returns CY set to indicate that the bus is not available
; or that the addressed device failed to acknowledge.
call start
jc x45 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
setb acc.0 ; specify read operation
call shout ; send device address
jc x44 ; abort if no acknowledge
call shin ; receive data byte
call NAK ; do not acknowledge byte
clr c ; clear error flag
x44:
call stop
x45:
ret
read_random:
; AT24Cxx Random Read function.
; Called with programmable address in A, byte address in
; register pair ADDR_HI:ADDR_LO. Returns data in A.
; Returns CY set to indicate that the bus is not available
; or that the addressed device failed to acknowledge.
push b
mov b, a ; save copy of programmable address
; Send dummy write command to set internal address.
call start
jc x47 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
clr acc.0 ; specify write operation
call shout ; send device address
jc x46 ; abort if no acknowledge
mov a, addr_hi ; send high byte of address
call shout ;
jc x46 ; abort if no acknowledge
mov a, addr_lo ; send low byte of address
call shout ;
jc x46 ; abort if no acknowledge
; Call Current Address Read function.
mov a, b ; get programmable address
call read_current
jmp x47 ; exit
x46:
call stop
x47:
pop b
ret
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
setb SCL
; Verify bus available.
jnb SDA, x40 ; jump if not high
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
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
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
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
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
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
END
答 1: 老兄,很明显这是汇编不是C被骗,本来还想看看ATMEL的官方的C51的I2C程序代码呢
; This collection of routines allows an AT89C2051 microcontroller to read
; and write the AT24Cxx family of serial CMOS EEPROMS. This version of the
; code is compatible only with the AT89C2051 due to the location of the
; data buffer and stack in RAM. The code may be modified to work with the
; AT89C1051 by relocating or resizing the buffer and stack to fit into the
; smaller amount of RAM available in the AT89C1051. Note that the minimum
; size of the buffer is determined by the page size of the AT24Cxx.
;
; All five AT24Cxx device operations are supported. Byte Write, Current
; Address Read and Random Read are implemented by the functions WRITE_BYTE,
; READ_CURRENT and READ_RANDOM, respectively. Page Write and Sequential Read
; are special cases of functions WRITE_BLOCK and READ_BLOCK, respectively.
; WRITE_BLOCK and READ_BLOCK process from one byte to the number of bytes
; in a page and transfer data between the AT24Cxx and the RAM buffer.
;
; The code supports multiple AT24Cxx devices per bus, each with a unique
; address determined by the wiring of the address pins (A0, A1, A2). The
; three-bit programmable address is passed to the WRITE_BYTE, READ_CURRENT,
; READ_RANDOM, WRITE_BLOCK and READ_BLOCK functions, where it is combined
; with the AT24Cxx fixed address (FADDR) and used to address a device on the
; bus. Refer to the AT24Cxx family data sheets for additional information on
; device addressing.
;
; Functions BYTE_FILL, VERIFY_BYTE_FILL, PAGE_FILL and VERIFY_PAGE_FILL are
; artifacts from the debug process and serve to illustrate the use of the
; device read and write functions with an AT24C64. To modify the code for a
; different member of the AT24Cxx family, simply redefine the values of SIZE
; (the number of bytes per device) and PSIZE (the number of bytes per page).
; To change the fill value, redefine FILL. To change the programmable portion
; of the device address, redefine PADDR to a value from zero to seven.
;
; The code meets all AT24Cxx family timing requirements when executed by an
; AT89Cx051 microcontroller with a 12 MHz clock. Code modifications may be
; required if a faster clock is substituted.
FADDR EQU 0a0h ; fixed address for AT24Cxx EEPROMs
PADDR EQU 0 ; programmable address (0..7)
SIZE EQU 2000h ; bytes per AT24C64
PSIZE EQU 32 ; bytes per page for AT24C64
FILL EQU 55h ; example fill value
; Register definitions.
index EQU r0 ; buffer pointer
kount EQU r1 ; byte count register
zdata EQU r1 ; data register
addr_lo EQU r2 ; 2-byte address register
addr_hi EQU r3 ;
; Microcontroller connections to AT24Cxx serial bus lines.
SCL BIT p1.2 ; serial clock
SDA BIT p1.3 ; serial data
DSEG AT 20H
ORG 40H
buffer: DS PSIZE ; storage for read/write data
ORG 60H ; stack origin
stack: DS 20H ; stack depth
CSEG
ORG 0000H ; power on/reset vector
jmp on_reset
ORG 0003H ; external interrupt 0 vector
reti ; undefined
ORG 000BH ; timer 0 overflow vector
reti ; undefined
ORG 0013H ; external interrupt 1 vector
reti ; undefined
ORG 001BH ; timer 1 overflow vector
reti ; undefined
ORG 0023H ; serial I/O interrupt vector
reti ; undefined
ORG 0080H ; begin code space
USING 0 ; register bank zero
on_reset:
mov sp, #(stack-1) ; initialize stack pointer
; Initialize AT24Cxx serial bus lines.
setb SDA ; high
setb SCL ; high
call byte_fill
jc fault
call verify_byte_fill
jc fault
call page_fill
jc fault
call verify_page_fill
jc fault
fault:
jmp $
byte_fill:
; Fill every byte in an AT24Cxx with the same value.
; Writes one address at a time (page mode is not used).
; Returns CY set to indicate write timeout.
; Destroys A, B, DPTR, XDATA, ADDR_HI:ADDR_LO.
mov zdata, #FILL ; set up fill data
mov dptr, #0 ; initialize address pointer
x51:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov b, #120 ; retry counter
x52:
mov a, #PADDR ; programmable address
call write_byte ; try to write
jnc x53 ; jump if write OK
djnz b, x52 ; try again
setb c ; set timeout error flag
jmp x54 ; exit
x53:
inc dptr ; advance address pointer
; mov a, dpl ; check low byte
; cjne a, #(LOW SIZE), x51 ; jump if not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x51 ; jump if not last
clr c ; clear error flag
x54:
ret
verify_byte_fill:
; Verify that all bytes in an AT24Cxx match a fill value.
; Reads and verifies one byte at a time (page mode is not used).
; Performs a Random Read function to initialize the internal
; address counter and checks the contents of the first address.
; Then performs multiple Current Address Read functions to step
; through the remaining addressess.
; Returns CY set to indicate read timeout or compare fail.
; Destroys A, B, DPTR.
mov dptr, #0 ; initialize address pointer/counter
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov b, #120 ; retry counter
x81:
mov a, #PADDR ; programmable address
call read_random ; try to read
jnc x82 ; jump if read OK
djnz b, x81 ; try again
jmp x86 ; set error flag and exit
x82:
cjne a, #FILL, x86 ; jump if compare error
jmp x85 ; do remaining addresses
x83:
mov a, #PADDR
call read_current
jc x87 ; jump if read fails
cjne a, #FILL, x86 ; jump if compare error
x85:
inc dptr ; advance address pointer
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x83 ; jump if not last
clr c ; clear error flag
jmp x87 ; exit
x86:
setb c ; set error flag
x87:
ret
page_fill:
; Fill every byte in an AT24Cxx with the same value.
; Writes one page at a time.
; Returns CY set to indicate write timeout.
; Destroys A, B, DPTR, KOUNT, INDEX, ADDR_HI:ADDR_LO.
; First fill buffer.
mov b, #PSIZE ; bytes per page
mov index, #buffer ; point to buffer
x61:
mov @index, #FILL ; put fill value in buffer
inc index ; advance pointer
djnz b, x61 ; next byte
; Copy buffer to device, one page at a time.
mov dptr, #0 ; initialize address pointer
x62:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov kount, #PSIZE ; bytes per page
mov b, #120 ; retry counter
x63:
mov a, #PADDR ; programmable address
call write_block ; try to write
jnc x64 ; jump if write OK
djnz b, x63 ; try again
setb c ; set timeout error flag
jmp x66 ; exit
x64:
; Add page size to address pointer.
mov a, dpl ; get low byte
add a, #PSIZE ; add page size
mov dpl, a ; save low byte
jnc x65 ; jump if high byte not affected
inc dph ; increment high byte
x65:
; cjne a, #(LOW SIZE), x62 ; jump if low byte not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x62 ; jump if not last
clr c ; clear error flag
x66:
ret
verify_page_fill:
; Verify that all bytes in an AT24Cxx match a fill value.
; Reads and verifies one page at a time.
; Returns CY set to indicate read timeout or compare fail.
; Destroys A, B, DPTR, KOUNT, INDEX, ADDR_HI:ADDR_LO.
; Copy device page to buffer.
mov dptr, #0 ; initialize address pointer
x71:
mov addr_lo, dpl ; set up address
mov addr_hi, dph ;
mov kount, #PSIZE ; bytes per page
mov b, #120 ; retry counter
x72:
mov a, #PADDR ; programmable address
call read_block ; try to read
jnc x74 ; jump if read OK
djnz b, x72 ; try again
x73:
setb c ; set error flag
jmp x77 ; exit
x74:
; Verify buffer contents.
mov b, #PSIZE ; bytes per page
mov index, #buffer ; point to buffer
x75:
cjne @index, #FILL, x73 ; jump if compare fails
inc index ; advance pointer
djnz b, x75 ; next byte
; Add page size to address pointer.
mov a, dpl ; get low byte
add a, #PSIZE ; add page size
mov dpl, a ; save low byte
jnc x76 ; jump if high byte not affected
inc dph ; increment high byte
x76:
; cjne a, #(LOW SIZE), x71 ; jump if low byte not last
mov a, dph ; check high byte
cjne a, #(HIGH SIZE), x71 ; jump if not last
clr c ; clear error flag
x77:
ret
write_block:
; Write from one byte to one page of data to an AT24Cxx.
; Called with programmable address in A, address of first byte
; in register pair ADDR_HI:ADDR_LO, data in BUFFER, byte count
; in register KOUNT.
; 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, KOUNT, INDEX.
call start
jc x38 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
clr acc.0 ; specify write operation
call shout ; send device address
jc x37 ; abort if no acknowledge
mov a, addr_hi ; send high byte of address
call shout ;
jc x37 ; abort if no acknowledge
mov a, addr_lo ; send low byte of address
call shout ;
jc x37 ; abort if no acknowledge
mov index, #buffer ; point to buffer
x36:
mov a, @index ; get data
call shout ; send data
jc x37 ; abort if no acknowledge
inc index ; advance buffer pointer
djnz kount, x36 ; next byte
clr c ; clear error flag
x37:
call stop
x38:
ret
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 ADDR_HI:ADDR_LO,
; byte count in register KOUNT.
; 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, KOUNT, INDEX.
; 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, #FADDR ; add fixed address
mov index, 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, index ; get device address
setb acc.0 ; specify read operation
call shout ; send device address
jc x34 ; abort if no acknowledge
mov index, #buffer ; point to buffer
x31:
call shin ; receive data byte
mov @index, a ; save data
cjne kount, #1, x32 ; jump if not last byte
call NAK ; do not acknowledge last byte
jmp x33 ; done
x32:
call ACK ; acknowledge byte
inc index ; advance buffer pointer
djnz kount, x31 ; next byte
x33:
clr c ; clear error flag
x34:
call stop
x35:
ret
write_byte:
; AT24Cxx Byte Write function.
; Called with programmable address in A, byte address in
; register pair ADDR_HI:ADDR_LO, data in register XDATA.
; 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, #FADDR ; 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, zdata ; get data
call shout ; send data
jc x48 ; abort if no acknowledge
clr c ; clear error flag
x48:
call stop
x49:
ret
read_current:
; AT24Cxx Current Address Read function.
; Called with programmable address in A. Returns data in A.
; Returns CY set to indicate that the bus is not available
; or that the addressed device failed to acknowledge.
call start
jc x45 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
setb acc.0 ; specify read operation
call shout ; send device address
jc x44 ; abort if no acknowledge
call shin ; receive data byte
call NAK ; do not acknowledge byte
clr c ; clear error flag
x44:
call stop
x45:
ret
read_random:
; AT24Cxx Random Read function.
; Called with programmable address in A, byte address in
; register pair ADDR_HI:ADDR_LO. Returns data in A.
; Returns CY set to indicate that the bus is not available
; or that the addressed device failed to acknowledge.
push b
mov b, a ; save copy of programmable address
; Send dummy write command to set internal address.
call start
jc x47 ; abort if bus not available
rl a ; programmable address to bits 3:1
orl a, #FADDR ; add fixed address
clr acc.0 ; specify write operation
call shout ; send device address
jc x46 ; abort if no acknowledge
mov a, addr_hi ; send high byte of address
call shout ;
jc x46 ; abort if no acknowledge
mov a, addr_lo ; send low byte of address
call shout ;
jc x46 ; abort if no acknowledge
; Call Current Address Read function.
mov a, b ; get programmable address
call read_current
jmp x47 ; exit
x46:
call stop
x47:
pop b
ret
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
setb SCL
; Verify bus available.
jnb SDA, x40 ; jump if not high
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
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
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
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
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
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
END
答 1: 老兄,很明显这是汇编不是C被骗,本来还想看看ATMEL的官方的C51的I2C程序代码呢
共2条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
与电子爱好者谈读图二被打赏50分 | |
【FRDM-MCXN947评测】Core1适配运行FreeRtos被打赏50分 | |
【FRDM-MCXN947评测】双核调试被打赏50分 | |
【CPKCORRA8D1B评测】---移植CoreMark被打赏50分 | |
【CPKCORRA8D1B评测】---打开硬件定时器被打赏50分 | |
【FRDM-MCXA156评测】4、CAN loopback模式测试被打赏50分 | |
【CPKcorRA8D1评测】--搭建初始环境被打赏50分 | |
【FRDM-MCXA156评测】3、使用FlexIO模拟UART被打赏50分 | |
【FRDM-MCXA156评测】2、rt-thread MCXA156 BSP制作被打赏50分 | |
【FRDM-MCXN947评测】核间通信MUTEX被打赏50分 |