Continue to Site

# Reading and Writing PIC EEPROM

Status
Not open for further replies.

#### skeeterb

##### Member
I got to thinking about how Hydrogen on Demand will be unique, and I need a way to saving a value of how long a delay should be between the time the lower sensor goes low and how long after the upper sensor goes high to keep from overfilling the cell with electrolyte. I was thinking of using an EEPROM to store that data that would be read and moved to the delay counter that is used when the Refill section of my code is running. I would probably read a switch that tells on an input that would tell my pic to read the other input that would increment the W Register to the desired delay. When the switch to increment the W register goes low it would write the W register to the EEPROM. I'm already thinking of what code to write for the subroutine to set the value to the W Register, but what Registers would be used in the onboard EEPROM and what commands would be used to read and write to the EEPROM registers??

Edit:

I thought about leaving putting the value in code, but I would like to be able to change that value without having to recompile and reprogram the PIC with a new HEX file if I ever change HOD cells and require a different refill time to sufficiently fill the cell to above the Upper Water Level Sensor.

Last edited:

#### Pommie

##### Well-Known Member
Which pic and which language?

This is what I use on a 18F1320 in C18.
Code:
unsigned char ReadEEPROM(unsigned char address){
EECON1=0;                   //ensure CFGS=0 and EEPGD=0
EECON1bits.RD = 1;
return(EEDATA);
}

void WriteEEPROM(unsigned char address,unsigned char data){
char SaveInt;
SaveInt=INTCON;             //save interrupt status
EECON1=0;                   //ensure CFGS=0 and EEPGD=0
EECON1bits.WREN = 1;        //enable write to EEPROM
EEDATA = data;              //and data
INTCONbits.GIE=0;           //No interrupts
EECON2 = 0x55;              //required sequence #1
EECON2 = 0xaa;              //#2
EECON1bits.WR = 1;          //#3 = actual write
INTCON=SaveInt;             //restore interrupts
while(!PIR2bits.EEIF);      //wait until finished
EECON1bits.WREN = 0;        //disable write to EEPROM
}

Mike.

#### skeeterb

##### Member
Is That C? I'm use to working in Assembly. I'm using a PIC 16F628

Last edited:

#### Nigel Goodwin

##### Super Moderator
Check my tutorials, one of the IR ones saves and restores from data EEPROM.

The datasheet also explains how to do it.

#### skeeterb

##### Member
Check my tutorials, one of the IR ones saves and restores from data EEPROM.

The datasheet also explains how to do it.

Yeah, I was looking at the datasheet, it shows a good place for me to start.

#### skeeterb

##### Member
Not Writing to EEPROM

I'm having a problem Writing to the EEPROM using the below bit of code. It is supposed to write the value of the Count1v Register into the EEPROM memory of the PIC. Where am I going wrong??

Code:
EPWrite
banksel 0
movf EEprom_Data,w
banksel EEDATA
movwf EEDATA

banksel EECON1
bcf EECON1,EEPGD
bsf EECON1, WREN

movlw   H'55'           ; magic sequence
movwf   EECON2
movlw   H'AA'
movwf   EECON2

bsf     EECON1,WR
bsf     EECON1,WREN
bcf     EECON1,EEIF     ; clear the interrupt flag

_wloop
btfsc EECON1,EEIF
goto _wloop

banksel EECON1
bcf EECON1, WREN ; disable EEPROM write
banksel 0
return

#### Pommie

##### Well-Known Member
I've had a quick look at your code and see a few confusing bits,

Code:
EPWrite
banksel 0
movf EEprom_Data,w
banksel EEDATA
movwf EEDATA

banksel EECON1
;      bcf EECON1,EEPGD      Doesn't exist!!!
bsf EECON1, WREN

movlw   H'55'           ; magic sequence
movwf   EECON2
movlw   H'AA'
movwf   EECON2

bsf     EECON1,WR
;      bsf     EECON1,WREN     ;not needed
;      bcf     EECON1,EEIF     ; clear the interrupt flag

_wloop
btfss EECON1,EEIF       ;changed
goto _wloop
bcf     EECON1,EEIF     ; clear the interrupt flag

banksel EECON1
bcf EECON1, WREN ; disable EEPROM write
banksel 0
return
The above should work on a 16F628. I don't know where you got that code but it looks like it was written for a 16F88.

BTW, a good way to see if it's working is to read the EEPROM back into your programmer. Note is you're using a Pickit2 or similar you must do a read before it shows up in MPLAB.

Mike.

#### skeeterb

##### Member
Right now, I'm in the testing phase. I'm trying to get the code working before I build my circuit. For some reason my computer won't let me reinstall MPLab and I've been doing all my coding using Windows Notepad. I've been using the MPASMWIN app that was installed with Microsim. I had to copy the directory with the application in it because it was complaining about the length of the directory when it tries to compile. I've been coding/compiling using the Notepad/MPASMWIN combo for a few days now, and it seems to be working and the code works on Oshonsoft's Pic Simulator IDE.

Edit:
Pic Simulator has a EEPROM memory viewer that I can look at to see if my data has been written to the EEPROM. Oh and what do I need to change to point the value in Count1v (the value being saved in EEPROM)?

Last edited:

#### ericgibbs

##### Well-Known Member
Right now, I'm in the testing phase. I'm trying to get the code working before I build my circuit. For some reason my computer won't let me reinstall MPLab and I've been doing all my coding using Windows Notepad. I've been using the MPASMWIN app that was installed with Microsim. I had to copy the directory with the application in it because it was complaining about the length of the directory when it tries to compile. I've been coding/compiling using the Notepad/MPASMWIN combo for a few days now, and it seems to be working and the code works on Oshonsoft's Pic Simulator IDE.

Edit:
Pic Simulator has a EEPROM memory viewer that I can look at to see if my data has been written to the EEPROM.

hi,
MPLAB cant handle long file location addresses.

Move your working files to a folder on the main hard drive, name it something like 'MyAsm' that should keep MPLAB happy.

Last edited:

#### skeeterb

##### Member
hi,
MPLAB cant handle long file location addresses.

Move your working files to a folder on the main hard drive, name it something like 'MyAsm' that should keep MPLAB happy.

I copied the MPASMWIN app and all of its include files to the c:\Temp directory where I'm keeping all my working files for the PIC program.

#### skeeterb

##### Member
Getting Stuck in Write

My program seems to be getting stuck when writing to the EEPROM. Where am I going wrong?

Code:
       list      p=16f628A           ; list directive to define processor
#include <p16f628A.inc>       ; processor specific variable definitions
errorlevel   -302             ;hide banking message
;*****
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF
;*****
;internal osc settings
;*****
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;***** VARIABLE DEFINITIONS
w_temp        EQU     0x70              ; variable used for context saving
status_temp   EQU     0x71              ; variable used for context saving
Count1        EQU     0X20              ; First Counter for Delay
Count1v       EQU     0X21              ; Count Storage for Refill Delay
;**********************************************************************
ORG      0x000             ; processor reset vector
goto     Start             ; go to beginning of program
ORG      0x004             ; interrupt vector location
movwf    w_temp            ; save off current W register contents
movf     STATUS,w          ; move status register into W register
movwf    status_temp       ; save off contents of STATUS register
movf     status_temp,w     ; retrieve copy of STATUS register
movwf    STATUS            ; restore pre-isr STATUS register contents
swapf    w_temp,f
swapf    w_temp,w          ; restore pre-isr W register contents
retfie                     ; return from interrupt

Start
clrf     PORTA
clrf     PORTB
MOVLW    0x07
MOVWF    CMCON             ; Turn off comparator
bsf      STATUS,RP0        ; bank one
movlw    0xFF
movwf    TRISA             ; porta all Input
movlw    0x00
movwf    TRISB             ; portb all Output
movlw    0x00              ;See datasheet for prefered
movwf    OPTION_REG        ;settings of OPTION_REG
call     Systest
btfsc    PORTA, 2          ; Check if Setup Switch = 1
call     Setup             ; Go to Setup Subroutine
;movf     Count1v,w
;movwf    Count1
btfss    PORTA,0           ; Check if Upper Sensor = 1
Call     Refill            ; If not go to Refill Subroutine
Goto     Run               ; Then go to Operation Mode

Setup
btfss    PORTA,2           ; If Setup Switch = 0
call     EP_Write          ; Write Count1v Data to EEPROM
btfsc    PORTA,3           ; If Count Switch = 1
incfsz   Count1v,1         ; Increment Count1v by 1
btfsc    PORTA,2           ; If Setup Switch = 1

Systest
call     Delay             ; Call Delay Routine to set Delay time
movlw    0x80              ; Set PortB,7 High the others Low
movwf    PORTB
call     Delay1            ; Call Delay Subroutine
call     Delay             ; Call Delay Routine to set Delay time
movlw    0x40              ; Set PortB,6 High the others Low
movwf    PORTB
call     Delay1            ;Call Delay Subroutine
call     Delay             ; Call Delay Routine to set Delay time
movlw    0x20              ; Set PortB,5 High the others Low
movwf    PORTB
call     Delay             ; Call Delay Routine to set Delay time
call     Delay1            ; Call Delay Subroutine
movlw    0x10              ; Set PortB,4 High the others Low
movwf    PORTB
call     Delay             ; Call Delay Routine to set Delay time
Call     Delay1            ; Call Delay Subroutine
movlw    0xF0              ; Set All Indicators High
movwf    PORTB
call     Delay             ; Call Delay Routine to set Delay time
call     Delay1            ; Call Delay Subroutine
movlw    0x80              ; Turn on Power LED
movwf    PORTB

Run
movlw    0xC0              ; Set Operation Mode
btfss    PORTA,0           ; Check if Upper Sensor = 1
movlw    0xE0              ; Set Warning Mode
movwf    PORTB             ; Move to PortB
btfss    PORTA,1           ; Check if Lower Sensor = 1
call     Delay             ; Then Goto Delay1 Subroutine
btfss    PORTA,1           ; Check If Lower Sensor = 1
Call     Refill            ; Go to Refill Subroutine

Refill
movlw    0xB8              ; Set Refill Mode
btfsc    PORTA,0           ; Check If Upper Sensor = 1
movlw    0xC0              ; Then Set Operation Mode
movwf    PORTB             ; Move to PORTB
btfsc    PORTA,1           ; Check If Lower Sensor = 1
call     Delay1            ; Then Go To Delay Subroutine
btfss    PORTA,0           ; Check If Upper Sensor = 1

Delay:
movlw    0x05              ; Set Counter to 05H
movwf    Count1

Delay1:
decfsz   Count1,1          ;Decrement Count1 1
EP_Write
movfw    Count1v        ; read current value
bsf      STATUS,RP0     ; Bank 1
bsf      EECON1,WREN     ; Enable write
movwf    EEDATA        ; set EEPROM data
movlw    0x55
movwf    EECON2         ; Write 55h
movlw    0xAA
movwf    EECON2         ; Write AAh
bsf      EECON1,WR     ; Set WR bit
; begin write
bcf      STATUS,RP0     ; Bank 0

btfss    PIR1,EEIF            ; wait for write to complete.
goto     \$-1
bcf      PIR1,EEIF       ; and clear the 'write complete' flag
bsf      STATUS,RP0     ; Bank 1
bcf      EECON1,WREN    ; Disable write
bcf      STATUS,RP0     ; Bank 0
retlw    0x00
Return

BSF      STATUS, RP0       ; Bank 1
BSF      EECON1, RD        ; EE Read
MOVF     EEDATA, W         ; W = EEDATA
BCF      STATUS, RP0       ; Bank 0
RETURN

END

#### ericgibbs

##### Well-Known Member
hi skeeter,

Look at this cut down version of your program.
Its only the EE Write function, run it in MPLAB.
It fills the EEPROM from 0h thru 7Fh with 0h to 7Fh.

This should check out the EE write in simulation.

#### Attachments

• skeet2.asm
2.9 KB · Views: 463

#### skeeterb

##### Member
still locking up in the write portion of the program. I'm still using Oshonsoft PIC Simulator IDE to test my program, and it still gets stuck in the same area.

#### ericgibbs

##### Well-Known Member
still locking up in the write portion of the program. I'm still using Oshonsoft PIC Simulator IDE to test my program, and it still gets stuck in the same area.

hi,
I used Oshonsoft for the cut down version of the program, it ran OK.

Did you try the one I posted as a test.?

#### skeeterb

##### Member
I didn't realize it because it was working slowly at normal. I watched it and upped to ultimate to really see the work being done.

#### ericgibbs

##### Well-Known Member
I didn't realize it because it was working slowly at normal. I watched it and upped to ultimate to really see the work being done.

hi,
The sim will run much slower than real life.

For the sim what I do is to insert a 'return' at the start of any delay subroutine.

Always use 'Ultimate' where possible, did you use the EEPROM memory editor to see the writing action.?

If you wish, post your final asm program and I will give it a run thru the sim.

#### skeeterb

##### Member
The code below is the current code. I haven't changed anything since I hit this snag.its the one marked not writing to eeprom

Last edited:

#### skeeterb

##### Member
I've gotten it to read and write to the EEPROM. But I realized there was another value that I may want to commit to the EEPROM. This one will be the timeout value for the prestart indicator test. Right now I've got it set in code, but if I want to change it, I would have to change the source code and re-program the PIC, but I want to use the same method of writing the second value to the EEPROM. I've been looking at the code you edited down for a sample, Eric, and I think I figured out a method of advancing to the next bit and writing the next value into the EEPROM. Is there any advice you would like to add to help me write the timeout value to the EEPROM?

#### ericgibbs

##### Well-Known Member
Eric, and I think I figured out a method of advancing to the next bit and writing the next value into the EEPROM. Is there any advice you would like to add to help me write the timeout value to the EEPROM?

hi Skeeter,
Look at this EEPROM write asm file, runs in Oshonsoft.

Uses two Macro's, one for data to EEProm and the other for register contents to EEProm.

EDIT:

#### Attachments

• EEP_WR_RD1.asm
3 KB · Views: 332
Last edited:

#### skeeterb

##### Member
Eric, I'm having trouble with using macros. I'm getting 2 error messages when I try to compile it. Those error messages repeat 12 times, that's about how many times I use the macro to try to read from the EEPROM.

Warning[207] C:\TEMP\CONTROL.ASM 97 : Found label after column 1. (RDD_EE)
Error[108] C:\TEMP\CONTROL.ASM 97 : Illegal character (0)

Status
Not open for further replies.

Replies
12
Views
1K
Replies
9
Views
5K
Replies
70
Views
6K
Replies
25
Views
1K
Replies
10
Views
2K