Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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:
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 
    EEADR = address;
    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
    EEADR = address;            //setup Address
    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.
 
Is That C? I'm use to working in Assembly. I'm using a PIC 16F628
 
Last edited:
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.
 
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
            movf EEPROM_ADR,w ; load with value in w
            banksel EEADR
            movwf EEADR
            clrf EEADRH
            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
 
I've had a quick look at your code and see a few confusing bits,

Code:
EPWrite
            movf EEPROM_ADR,w ; load with value in w
            banksel EEADR
            movwf EEADR
            clrf EEADRH
            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.
 
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:
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:
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.
 
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
EEPROM_ADDR   Equ     0x00        ; Address of EEPROM byte used
    ;**********************************************************************
             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
             bcf      STATUS,RP0        ; return to bank 0
             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
             goto     Setup             ; Return to top of Subroutine
             return                     ; Return to main program                

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
             RETURN                     ;Return to main program

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
             Goto     Run               ; Return to Top 

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
             goto     Refill            ; If Not Return to Top of subroutine
             Return                     ; Return to previous point

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

Delay1:        
         decfsz   Count1,1          ;Decrement Count1 1
         goto     Delay1            ;If Count1 > 0 Return to top
             Return                     ;Return to Previous point
EP_Write
             movfw    Count1v        ; read current value
          bsf      STATUS,RP0     ; Bank 1
         bsf      EECON1,WREN     ; Enable write
         movwf    EEDATA        ; set EEPROM data
         movlw    EEPROM_Addr
         movwf    EEADR        ; set EEPROM address
         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

EP_READ
             BSF      STATUS, RP0       ; Bank 1
             MOVLW    EEPROM_ADDR       ;
             MOVWF    EEADR             ; Address to read
             BSF      EECON1, RD        ; EE Read
             MOVF     EEDATA, W         ; W = EEDATA
             BCF      STATUS, RP0       ; Bank 0
             RETURN

            END
 
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: 497
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.
 
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.?
 
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.
 
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.
 
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:
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?
 
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:
Added a EEProm read Macro.
 

Attachments

  • EEP_WR_RD1.asm
    3 KB · Views: 377
Last edited:
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.

Latest threads

New Articles From Microcontroller Tips

Back
Top