Randy Day said:
This is my first attempt to write to eeprom
using a pic18f2455. Obviously it isn't
working.
Most of it is straight out of the datasheet;
can anyone point out what I'm missing? Thanks.
;write serial number to EEPROM
; EEADR initial value is 4
; MOVWF EEADR ; Lower bits of Data Memory Address to write
DECF EEADR ; decrement EEPROM address for ser# storage
MOVF NIBBLE_TEMP, W ; ser# value to store
MOVWF EEDATA ; Data Memory Value to write
BCF EECON1, EEPGD ; Point to DATA memory
BCF EECON1, CFGS ; Access EEPROM
BSF EECON1, WREN ; Enable writes
BCF INTCON, GIE ; Disable Interrupts
MOVLW 55h ; Required Sequence
MOVWF EECON2 ; Write 55h
MOVLW 0AAh ;
MOVWF EECON2 ; Write 0AAh
BSF EECON1, WR ; Set WR bit to begin write
; User code execution
BTFSC EECON1, WR
GOTO $-2
; test for write errors (WRERR) would go here...
BCF EECON1, WREN ; Disable writes on write complete (EEIF set) BSF
INTCON, GIE ; Enable Interrupts
===============================================================================
It is very helpful to have a debugger such as the ICD2, but it costs about
$150, so might be out of reach for a hobbyist. The software simulator is
extremely powerful, however, and you might be able to track down your
problem in that way.
You can try some of the following code. I am using a PIC18F242. I think it
works for EEPROM, but now I write to Program Flash Memory, which I think is
recommended as more reliable:
EEPROMread:
MOVLW DATA_EE_ADDR ;
MOVWF EEADR ; Data Memory Address to read
BCF EECON1, EEPGD ; Point to DATA memory
BCF EECON1, CFGS ; Access program FLASH or Data EEPROM memory
BSF EECON1, RD ; EEPROM Read
MOVF EEDATA, W ; W = EEDATA
RETURN
EEPROMwrite:
MOVLW DATA_EE_ADDR ;
MOVWF EEADR ; Data Memory Address to read
MOVLW DATA_EE_DATA ;
MOVWF EEDATA ; Data Memory Value to write
BCF EECON1, EEPGD ; Point to DATA memory
BCF EECON1, CFGS ; Access program FLASH or Data EEPROM memory
BSF EECON1, WREN ; Enable writes
BCF INTCON, GIE ; Disable interrupts
MOVLW 55h ;
MOVWF EECON2 ; Write 55h
MOVLW 0AAh ;
MOVWF EECON2 ; Write AAh
BSF EECON1, WR ; Set WR bit to begin write
BSF INTCON, GIE ; Enable interrupts
; user code execution
BCF EECON1, WREN ; Disable writes on write complete (EEIF set)
RETURN
;Read a block of data from CODE_ADDR into BUFF_ADDR length BUFF_LEN
FlashRead:
BSF EECON1, EEPGD ; Point to Program Flash memory
BCF EECON1, CFGS ; Access program FLASH or Data EEPROM memory
BCF INTCON, GIE ; Disable interrupts
MOVFF CODE_ADDR_UPPER, TBLPTRU ; Load TBLPTR with the base
MOVFF CODE_ADDR_HIGH, TBLPTRH
MOVFF CODE_ADDR_LOW, TBLPTRL
MOVFF BUFFER_ADDR_HIGH, FSR0H ; point to flash buffer
MOVFF BUFFER_ADDR_LOW, FSR0L
MOVFF BUFFER_LEN, COUNTER ;Initialize byte counter
READ_BYTE
TBLRD*+ ; read into TABLAT and increment
MOVF TABLAT, W ; get data
MOVWF POSTINC0
DECFSZ COUNTER
BRA READ_BYTE
EndReadFlash
BSF INTCON, GIE ; Enable interrupts
RETURN
;Write a block of data from BUFF_ADDR into CODE_ADDR length BUFF_LEN
FlashWrite:
MOVFF BUFFER_LEN, COUNTER_HI ; number of bytes to write
MOVFF BUFFER_ADDR_HIGH, FSR0H ; point to flash buffer
MOVFF BUFFER_ADDR_LOW, FSR0L
RRNCF COUNTER_HI,F
RRNCF COUNTER_HI,F
RRNCF COUNTER_HI,F ;Divide by 8
MOVF COUNTER_HI, W
ANDLW b'00011111' ;Mask off rotated bits
MOVWF COUNTER_HI
MOVFF BUFFER_ADDR_HIGH, FSR0H ; point to buffer
MOVFF BUFFER_ADDR_LOW, FSR0L
PROGRAM_LOOP
MOVLW 8 ; number of bytes in holding register
MOVWF COUNTER
WRITE_WORD_TO_HREGS
MOVF POSTINC0, W ; get low byte of buffer data
MOVWF TABLAT ; present data to table latch
TBLWT+* ; write data, perform a short write
; to internal TBLWT holding register.
DECFSZ COUNTER ; loop until buffers are full
BRA WRITE_WORD_TO_HREGS
PROGRAM_MEMORY
BSF EECON1,EEPGD ; point to FLASH program memory
BCF EECON1,CFGS ; access FLASH program memory
BSF EECON1,WREN ; enable write to memory
BCF INTCON,GIE ; disable interrupts
MOVLW 55h
MOVWF EECON2 ; write 55h
MOVLW 0AAh
MOVWF EECON2 ; write AAh
BSF EECON1,WR ; start program (CPU stall)
BSF INTCON,GIE ; re-enable interrupts
DECFSZ COUNTER_HI ; loop until done
BRA PROGRAM_LOOP
BCF EECON1,WREN ; disable write to memory
RETURN
ERASE_BLOCK
MOVFF CODE_ADDR_UPPER, TBLPTRU ; load TBLPTR with base address of memory
block
MOVFF CODE_ADDR_HIGH, TBLPTRH
MOVFF CODE_ADDR_LOW, TBLPTRL
BSF EECON1,EEPGD ; point to FLASH program memory
BCF EECON1,CFGS ; access FLASH program memory
BSF EECON1,WREN ; enable write to memory
BSF EECON1,FREE ; enable Row Erase operation
BCF INTCON,GIE ; disable interrupts
MOVLW 55h
MOVWF EECON2 ; write 55h
MOVLW 0AAh
MOVWF EECON2 ; write AAh
BSF EECON1,WR ; start erase (CPU stall)
BSF INTCON,GIE ; re-enable interrupts
TBLRD*- ; dummy read decrement
return