📄 avr_100_accessing_the_eeprom.asm
字号:
;**** A P P L I C A T I O N N O T E A V R 1 0 0 ************************
;*
;* Title: Accessing the EEPROM
;* Version: 2.0
;* Last updated: 98.06.15
;* Target: AT90Sxxxx (All AVR Devices)
;*
;* Support E-mail: avr@atmel.com
;*
;* DESCRIPTION
;* This Application note shows how to read data from and write data to the
;* EEPROM. Both random access and sequential access routines are listed.
;* The code is written for 8515, to modify for 4414,2313,2323... apply the
;* following changes:
;* - Remove all entries to EEARH
;* - Rename EEARL to EEAR
;*
;* To modify for 1200, apply the changes above, and change the code
;* as commented inside the routines
;*
;*
;***************************************************************************
.include "8515def.inc"
rjmp RESET ;Reset Handle
;***************************************************************************
;*
;* EEWrite
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* programs the EEPROM with register variable "EEdwr" at address "EEawr:EEawr"
;*
;* Number of words :1200 ; 5 + return
;* :8515 ; 7 + return
;* Number of cycles :1200 ; 8 + return (if EEPROM is ready)
;* :8515 ; 11 + return (if EEPROM is ready)
;* Low Registers used :None
;* High Registers used: ;3 (EEdwr,EEawr,EEawrh)
;*
;***************************************************************************
;***** Subroutine register variables
.def EEdwr =r16 ;data byte to write to EEPROM
.def EEawr =r17 ;address low byte to write to
.def EEawrh =r18 ;address high byte to write to
;***** Code
EEWrite:
sbic EECR,EEWE ;if EEWE not clear
rjmp EEWrite ; wait more
; out EEAR,EEawr ;output address for 1200, commented out !
; the two following lines must be replaced with the line above if 1200 is used
out EEARH,EEawrh ;output address high for 8515
out EEARL,EEawr ;output address low for 8515
out EEDR,EEdwr ;output data
sbi EECR,EEMWE ;set master write enable, remove if 1200 is used
sbi EECR,EEWE ;set EEPROM Write strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
ret
;***************************************************************************
;*
;* EERead
;*
;* This subroutine waits until the EEPROM is ready to be programmed, then
;* reads the register variable "EEdrd" from address "EEardh:EEard"
;*
;* Number of words :1200 ; 5 + return
;* :8515 ; 6 + return
;* Number of cycles :1200 ; 8 + return (if EEPROM is ready)
;* :8515 ; 9 + return (if EEPROM is ready)
;* Low Registers used :1 (EEdrd)
;* High Registers used: :2 (EEard,EEardh)
;*
;***************************************************************************
;***** Subroutine register variables
.def EEdrd =r0 ;result data byte
.def EEard =r17 ;address low to read from
.def EEardh =r18 ;address high to read from
;***** Code
EERead:
sbic EECR,EEWE ;if EEWE not clear
rjmp EERead ; wait more
; out EEAR,EEard ;output address for 1200, commented out !
; the two following lines must be replaced with the line above if 1200 is used
out EEARH,EEardh ;output address high for 8515
out EEARL,EEard ;output address low for 8515
sbi EECR,EERE ;set EEPROM Read strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
in EEdrd,EEDR ;get data
ret
;***************************************************************************
;*
;* EEWrite_seq
;*
;* This subroutine increments the EEPROM address by one and waits until the
;* EEPROM is ready for programming. It then programs the EEPROM with
;* register variable "EEdwr_s".
;* Number of words :1200 ; 7 + return
;* :8515 ; 10 + return
;* Number of cycles :1200 ; 10 + return (if EEPROM is ready)
;* :8515 ; 15 + return (if EEPROM is ready)
;* Low Registers used :None
;* High Registers used: :3 (EEdwr_s,EEwtmp,EEwtmph)
;*
;***************************************************************************
;***** Subroutine register variables
.def EEwtmp =r24 ;temporary storage of address low byte
.def EEwtmph =r25 ;temporary storage of address high byte
.def EEdwr_s =r18 ;data to write
;***** Code
EEWrite_seq:
sbic EECR,EEWE ;if EEWE not clear
rjmp EEWrite_seq ; wait more
; Write sequence for 1200
; in EEwtmp,EEAR ;get address for 1200, commented out !
; inc EEwtmp ;increment address 1200, commented out !
; out EEAR,EEwtmp ;output address 1200
; Write sequence for 8515, must be replaced with the lines above if 1200 is used
in EEwtmp,EEARL ;get address low 8515
in EEwtmph,EEARH ;get address high 8515
adiw EEwtmp,0x01 ;increment address 8515
out EEARL,EEwtmp ;output address 8515
out EEARH,EEwtmph ;output address 8515
out EEDR,EEdwr_s ;output data
sbi EECR,EEMWE ;set master write enable, remove if 1200 is used
sbi EECR,EEWE ;set EEPROM Write strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
ret
;***************************************************************************
;*
;* EERead_seq
;*
;* This subroutine increments the address stored in EEAR and reads the
;* EEPROM into the register variable "EEdrd_s".
;* Number of words :1200 ; 5 + return
;* :8515 ; 7 + return
;* Number of cycles :1200 ; 8 + return (if EEPROM is ready)
;* :8515 ; 11 + return (if EEPROM is ready)
;* Low Registers used :1 (EEdrd_s)
;* High Registers used: :2 (EErtmp,EErtmph)
;*
;***************************************************************************
;***** Subroutine register variables
.def EErtmp =r24 ;temporary storage of low address
.def EErtmph =r25 ;temporary storage of high address
.def EEdrd_s =r0 ;result data byte
;***** Code
EERead_seq:
sbic EECR,EEWE ;if EEWE not clear
rjmp EERead_seq ; wait more
; The above sequence for EEWE = 0 can be skipped if no write is initiated.
; Read sequence for 1200
; in EErtmp,EEAR ;get address for 1200, commented out !
; inc EErtmp ;increment address 1200, commented out !
; out EEAR,EErtmp ;output address 1200
; Read sequence for 8515, must be replaced with the lines above if 1200 is used
in EErtmp,EEARL ;get address low 8515
in EErtmph,EEARH ;get address high 8515
adiw EErtmp,0x01 ;increment address 8515
out EEARL,EErtmp ;output address 8515
out EEARH,EErtmph ;output address 8515
sbi EECR,EERE ;set EEPROM Read strobe
;This instruction takes 4 clock cycles since
;it halts the CPU for two clock cycles
in EEdrd_s,EEDR ;get data
ret
;****************************************************************************
;*
;* Test/Example Program
;*
;****************************************************************************
;***** Main Program Register variables
.def counter =r19
.def temp =r20
;***** Code
RESET:
;***** Initialize stack pointer
;* Initialize stack pointer to highest address in internal SRAM
;* Comment out for devices without SRAM
ldi r16,high(RAMEND) ;High byte only required if
out SPH,r16 ;RAM is bigger than 256 Bytes
ldi r16,low(RAMEND)
out SPL,r16
;***** Program a random location
ldi EEdwr,$aa
ldi EEawrh,$00
ldi EEawr,$10
rcall EEWrite ;store $aa in EEPROM location $0010
;***** Read from a random locations
ldi EEardh,$00
ldi EEard,$10
rcall EERead ;read address $10
out PORTB,EEdrd ;output value to Port B
;***** Fill the EEPROM address 1..64 with bit pattern $55,$aa,$55,$aa,...
ldi counter,63 ;init loop counter
clr temp
out EEARH,temp ;EEARH <- $00
clr temp
out EEARL,temp ;EEAR <- $00 (start address - 1)
loop1: ldi EEdwr_s,$55
rcall EEWrite_seq ;program EEPROM with $55
ldi EEdwr_s,$aa
rcall EEWrite_seq ;program EEPROM with $aa
dec counter ;decrement counter
brne loop1 ;and loop more if not done
;***** Copy 10 first bytes of EEPROM to r1-r11
clr temp
out EEARH,temp ;EEARH <- $00
ldi temp,$00
out EEARL,temp ;EEAR <- $00 (start address - 1)
clr ZH
ldi ZL,1 ;Z-pointer points to r1
loop2: rcall EERead_seq ;get EEPROM data
st Z,EEdrd_s ;store to SRAM
inc ZL
cpi ZL,12 ;reached the end?
brne loop2 ;if not, loop more
forever:rjmp forever ;eternal loop
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -