1. 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.
    Dismiss Notice

Reading and Writing PIC EEPROM

Discussion in 'Microcontrollers' started by skeeterb, Jun 7, 2009.

  1. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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: Jun 7, 2009
  2. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,160
    Likes:
    340
    Location:
    Brisbane Australia
    ONLINE
    Which pic and which language?

    This is what I use on a 18F1320 in C18.
    Code (text):

    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.
     
    • Like Like x 1
  3. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    Is That C? I'm use to working in Assembly. I'm using a PIC 16F628
     
    Last edited: Jun 7, 2009
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,323
    Likes:
    653
    Location:
    Derbyshire, UK

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

    The datasheet also explains how to do it.
     
  6. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    Yeah, I was looking at the datasheet, it shows a good place for me to start.
     
  7. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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 (text):

    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
     
     
  8. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,160
    Likes:
    340
    Location:
    Brisbane Australia
    ONLINE
    I've had a quick look at your code and see a few confusing bits,

    Code (text):

    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.
     
  9. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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: Jun 12, 2009
  10. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,233
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    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: Jun 12, 2009
  11. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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.
     
  12. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    Getting Stuck in Write

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

    Code (text):

           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
     
     
  13. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,233
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    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.:)
     

    Attached Files:

  14. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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.
     
  15. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,233
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    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.?
     
  16. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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.
     
  17. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,233
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    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.
     
  18. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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: Jun 14, 2009
  19. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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?
     
  20. ericgibbs

    ericgibbs Well-Known Member Most Helpful Member

    Joined:
    Jan 4, 2007
    Messages:
    21,233
    Likes:
    645
    Location:
    Ex Yorks' Hants UK
    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.
     

    Attached Files:

    Last edited: Jun 15, 2009
  21. skeeterb

    skeeterb Member

    Joined:
    Apr 7, 2007
    Messages:
    214
    Likes:
    0
    Location:
    USA
    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)
     

Share This Page