这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » 89CXX,EEPROM,AT24CXX,ATMEL 分享:89CXX单片机与E

共2条 1/1 1 跳转至

89CXX,EEPROM,AT24CXX,ATMEL 分享:89CXX单片机与EEPROM-AT24CXX汇编程序-来自ATMEL官方

院士
2006-09-17 18:14:16     打赏
89CXX,EEPROM,AT24CXX,ATMEL 分享:89CXX单片机与EEPROM-AT24CXX汇编程序-来自ATMEL官方



关键词: 89CXX     EEPROM     AT24CXX     ATME    

院士
2006-12-22 22:43:00     打赏
2楼
问         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程序代码呢

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]