Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

dsPIC data eeprom programming in c?

Status
Not open for further replies.

kinjal_ic

Newbie level 5
Newbie level 5
Joined
Jun 23, 2008
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,363
dspic eeprom

Hi I am new to dsPIc microcontroller. I want to know that how to program dsPIC 30f4011 eeprom memory on runtime? (to store temperature data , calibration data ,data used by firmware)
 

write eeprom word dspic

The place to go is Microchip web site.
There are numerous code examples for download that cover all aspects of pic programming.
 

    kinjal_ic

    Points: 2
    Helpful Answer Positive Rating
eeprom dspic

btbass said:
The place to go is Microchip web site.
There are numerous code examples for download that cover all aspects of pic programming.


I have downloaded the c program for microchip for data eeprom read/write which uses the followin function for eeprom read/write :

_prog_addressT EE_addr;
int temp = 0;

/* initialize a variable to represent the Data EEPROM address */
_init_prog_address(EE_addr, fooArrayInDataEE);

/*Copy array "fooArrayinDataEE" from DataEEPROM to "fooArray2inRAM" in RAM*/
_memcpy_p2d16(fooArray2inRAM, EE_addr, _EE_ROW);

/*Erase a row in Data EEPROM at array "fooArrayinDataEE" */
_erase_eedata(EE_addr, _EE_ROW);
_wait_eedata();

/*Write a row to Data EEPROM from array "fooArray1inRAM" */
_write_eedata_row(EE_addr, fooArray1inRAM);
_wait_eedata();

---------------------------------------------------
These functions dosen't gives how to config. eeprom control registers. (• NVMCON
• NVMADR • NVMADRU • NVMKEY)

in addition the datasheet had provided following things:

data eeprom read

MOV #LOW_ADDR_WORD,W0 ; Init Pointer
MOV #HIGH_ADDR_WORD,W1
MOV W1,TBLPAG
TBLRDL [ W0 ], W4 ; read data EEPROM



data eeprom block erase


; Select data EEPROM block, ERASE, WREN bits
MOV #0x4045,W0
MOV W0,NVMCON ; Initialize NVMCON SFR
; Start erase cycle by setting WR after writing key sequence
DISI #5 ; Block all interrupts with priority <7
; for next 5 instructions
MOV #0x55,W0 ;
MOV W0,NVMKEY ; Write the 0x55 key
MOV #0xAA,W1 ;
MOV W1,NVMKEY ; Write the 0xAA key
BSET NVMCON,#WR ; Initiate erase sequence
NOP
NOP
; Erase cycle will complete in 2mS. CPU is not stalled for the Data Erase Cycle
; User can poll WR bit, use NVMIF or Timer IRQ to determine erasure complete



data eeprom write

; Point to data memory
MOV #LOW_ADDR_WORD,W0 ; Init pointer
MOV #HIGH_ADDR_WORD,W1
MOV W1,TBLPAG
MOV #LOW(WORD),W2 ; Get data
TBLWTL W2,[ W0] ; Write data
; The NVMADR captures last table access address
; Select data EEPROM for 1 word op
MOV #0x4004,W0
MOV W0,NVMCON
; Operate key to allow write operation
DISI #5 ; Block all interrupts with priority <7
; for next 5 instructions
MOV #0x55,W0
MOV W0,NVMKEY ; Write the 0x55 key
MOV #0xAA,W1
MOV W1,NVMKEY ; Write the 0xAA key
BSET NVMCON,#WR ; Initiate program sequence
NOP
NOP
; Write cycle will complete in 2mS. CPU is not stalled for the Data Write Cycle
; User can poll WR bit, use NVMIF or Timer IRQ to determine write complete



--------------------------
Also i don"t know the assembly langauge for dspic.

I need the simplest way to configure these registers in c,such as how to configure the eeprom control register so that custom function may read or write the eeprom. (for example configuring the timer,adc etc....in c)

Previously I had worked with AVR microcontroller ,I its's data sheet they have provided the c code for eeprom read/write.




---------------------
Thanx

Added after 1 minutes:

blueroomelectronics said:
Are you familiar with PIC programming?

no I m beginner for pic but i have worked with AVR microcontroller in C.
 

storing variables in dspic eeprom

Attached are my read write eeprom routines. Just add 'eeprom_rw.s' to your projects Source Files list to link them, and include the 'eeprom_rw.h' header file in your program.

Change the include in the 'eeprom_rw.s' to suit your processor.

.include "p30f2010.inc"

The only thing you may need to change are the base address and the size of the eeprom to suit the processor. Most of them have the same base address of 0x007ffc00.

Change these values in the 'eeprom_rw.s' file to suit.

.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xfc00
.equiv EEPROM_SIZE, 0x0400

Just use them like so

WriteWord(address, data);

data = ReadWord(address);

The code remaps the eeprom base address to 0.
The functions read and write 16 bit words, so the maximum address is (eepromSize / 2)
which in this case is 0 - 512.

So minimum address is:
ReadWord(0);
up to
ReadWord(512);
 
programing dspic´s

btbass Thank you (X 10^99 times) eeprom read/write works ..:D:D

please explain me how the functions:

void WriteWord(uint16_t address, uint16_t data);
uint16_t ReadWord(uint16_t address);

Passes the argument to an assembly file : eeprom_rw.s

i want to modify these functions to read/write a single byte.

---------------------------
Thank you (X 10^99 times)
 

dspic eeprom write example

WriteWord(address, data);
The address is passed in w0 and the data is passed in w1.
ReadWord(address);
The address is passed in w0 and the data is returned in w0.

If you are using Mplab, which I highly recommend, build your file and then view the Program memory window, you can see where the compiler puts the arguments before it makes the call. Use Mplab Sim as the debugger and put w0 and w1 in the watch window. step through the code to see whats happening.

These are 16-bit processors, all the registers are 16 bits wide.
All addresses must be aligned on an even boundry otherwise you will get an illegal address access trap.
I have found it easier to use words as the natural size of variables. It is easy to mask out the bytes you need in your programs.
 
I want to thanks [in late :)] btbass because he helped me so much with his post
 

Thanks. Very good code for init with eeprom.
 

Can someone explain to me how to use the WriteWord function? I am able to read from EEPROM but I can't seem to get it to Write. I am using a dspic30f6014a and I set the EEPROM memory to 0x007ff000, the size is 0xfff correct?

When I use Read(0) I read the value in the EEPROM at 0x7ff000. I have attempted to use WriteWord(0, 0x3039) to place the decimal 12345 into 0x7ff000 but when I do this the EEPROM never updates in the code. I guess I"m confused on what value to use for the address.
 

.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xf000
.equiv EEPROM_SIZE, 0xfff

These are the correct values for the dsPic30f6014a.
So the valid addresses are

WriteWord(0, 0x3039); to WriteWord(4095, 0x3039);

I do not know why it is not working for you?

Try writing to some other address such as WriteWord(10, 0x3039);
 

Ok, maybe it is writing to the EEPROM. If I do this,

WriteWord(10, 0x3039); then

i = Read(10); I get 12345 in i

Would address 10 be equal to address 0x07ff022? 0 would be 0x07ff000 correct?
When I go to View --> EEPROM I don't see the address update. I thought I would.

Thanks for the help.
Greg
 

The 10 is decimal. but it's writing words, so its 0x07ff014

If you are using mplab to view the eeprom, it is not updated in real time, you have to do a read to update it!

I made a mistake with the address range, it's 0 to eeprom size / 2.

0 to 2048.
 

can help me how to store temperature in EEPROM with time stamp?
 

Hi all,
very nice and working code.
I did a small improvements to easy use in ASM/C environment :).

So,
I have some variables in C:
unsigned int var_1;
unsigned int var_2;


unsigned int _EEDATA(2) var_1_eep = {0x5678};
unsigned int _EEDATA(2) var_2_eep = {0x1234};

If I would like to write/read it to/from eeprom, I think that very good idea is:

WriteWord(&var_1_eep, var_1);
and
var_1 = ReadWord(&var_1_eep);

This is easier and cleaner - instead of this we need obtain eeprom address of the expected variable.

To do this is very easy, infos in code.
Enjoy :)
Regards
Mariusz


Code:
/*--------------------------------------------------------------------

  Title     : Eeprom read and write routines Version 1.01 
  Filename  : eeprom_rw.s 
  
  Copyright @ BobTheBass

/*------------------------------------------------------------------

  CHANGE HISTORY

  Issue     Modifier  Date      Change Description
  1.0       RW        01/11/07  First Issue
  1.01     MD         11/06/10  (dd/mm/yy)

  Software under version control, 
  see log file for changes.
      
--------------------------------------------------------------------*/
; NEW
; general config for dsPIC30xxx in MPLAB

        .include "p30fxxxx.inc"

; NEW
; compile for absolute C address
; if not needed, comment this line

.equ absolute_C_address, 1

        .global _WriteWord
        .global _ReadWord

;------ eeprom address
; NEW
; conditionals for developing (30F6014A) and target (30F5013) in my case

.ifdef __30F5013
.equiv EEPROM_SIZE, 0x3ff
.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xfC00
.endif

.ifdef __30F6014A
.equiv EEPROM_SIZE, 0xfff
.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xf000
.endif

;------ Memory opType.
        
        .equiv  ERASE_WORD, 0x4044
        .equiv  WRITE_WORD, 0x4004

;------ Write a word to eeprom

_WriteWord:
        push    w4
        mov     #ADDRESS_HI,w4
        mov     w4,TBLPAG
        mov     w4,NVMADRU
        mov     #ADDRESS_LO,w4

;NEW
; simple :)

.ifdef absolute_C_address
		sub 	w0,w4,w0
.endif

        sl      w0,#1,w0
        add     w0,w4,w0
        mov     w0,NVMADR
        rcall   EraseWord
        mov     #WRITE_WORD,w4
        mov     w4,NVMCON
        TBLWTL  w1,[w0]
        rcall   KeySequence
        pop     w4
        return

;------ Read a word from eeprom

_ReadWord:
        push    w4
        mov     #ADDRESS_HI,w4
        mov     w4,TBLPAG
        mov     w4,NVMADRU
        mov     #ADDRESS_LO,w4
        mov     w4,NVMADR

;NEW
; simple :)

.ifdef absolute_C_address
		sub 	w0,w4,w0
.endif

        sl      w0,#1,w0
        add     w0,w4,w4
        tblrdl  [w4],w0
        pop     w4
        return

;------ Erase a word from eeprom 

EraseWord:
        mov     #ERASE_WORD,w4
        mov     w4,NVMCON

;------ Required key sequence for write or erase.

KeySequence:
        disi    #16
        mov     #0x55,w4
        mov     w4,NVMKEY
        mov     #0xaa,w4
        mov     w4,NVMKEY
        bset    NVMCON,#WR
        nop
        nop
K1wait: btsc    NVMCON,#WR 
        bra     K1wait
        return

        .end
        
;------ End of file.
 
downybear said:
Hi all,
very nice and working code.
I did a small improvements to easy use in ASM/C environment :).

So,
I have some variables in C:
unsigned int var_1;
unsigned int var_2;


unsigned int _EEDATA(2) var_1_eep = {0x5678};
unsigned int _EEDATA(2) var_2_eep = {0x1234};

If I would like to write/read it to/from eeprom, I think that very good idea is:

WriteWord(&var_1_eep, var_1);
and
var_1 = ReadWord(&var_1_eep);

This is easier and cleaner - instead of this we need obtain eeprom address of the expected variable.

To do this is very easy, infos in code.
Enjoy :)
Regards
Mariusz


Code:
/*--------------------------------------------------------------------

  Title     : Eeprom read and write routines Version 1.01 
  Filename  : eeprom_rw.s 
  
  Copyright @ BobTheBass

/*------------------------------------------------------------------

  CHANGE HISTORY

  Issue     Modifier  Date      Change Description
  1.0       RW        01/11/07  First Issue
  1.01     MD         11/06/10  (dd/mm/yy)

  Software under version control, 
  see log file for changes.
      
--------------------------------------------------------------------*/
; NEW
; general config for dsPIC30xxx in MPLAB

        .include "p30fxxxx.inc"

; NEW
; compile for absolute C address
; if not needed, comment this line

.equ absolute_C_address, 1

        .global _WriteWord
        .global _ReadWord

;------ eeprom address
; NEW
; conditionals for developing (30F6014A) and target (30F5013) in my case

.ifdef __30F5013
.equiv EEPROM_SIZE, 0x3ff
.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xfC00
.endif

.ifdef __30F6014A
.equiv EEPROM_SIZE, 0xfff
.equiv ADDRESS_HI, 0x007F
.equiv ADDRESS_LO, 0xf000
.endif

;------ Memory opType.
        
        .equiv  ERASE_WORD, 0x4044
        .equiv  WRITE_WORD, 0x4004

;------ Write a word to eeprom

_WriteWord:
        push    w4
        mov     #ADDRESS_HI,w4
        mov     w4,TBLPAG
        mov     w4,NVMADRU
        mov     #ADDRESS_LO,w4

;NEW
; simple :)

.ifdef absolute_C_address
		sub 	w0,w4,w0
.endif

        sl      w0,#1,w0
        add     w0,w4,w0
        mov     w0,NVMADR
        rcall   EraseWord
        mov     #WRITE_WORD,w4
        mov     w4,NVMCON
        TBLWTL  w1,[w0]
        rcall   KeySequence
        pop     w4
        return

;------ Read a word from eeprom

_ReadWord:
        push    w4
        mov     #ADDRESS_HI,w4
        mov     w4,TBLPAG
        mov     w4,NVMADRU
        mov     #ADDRESS_LO,w4
        mov     w4,NVMADR

;NEW
; simple :)

.ifdef absolute_C_address
		sub 	w0,w4,w0
.endif

        sl      w0,#1,w0
        add     w0,w4,w4
        tblrdl  [w4],w0
        pop     w4
        return

;------ Erase a word from eeprom 

EraseWord:
        mov     #ERASE_WORD,w4
        mov     w4,NVMCON

;------ Required key sequence for write or erase.

KeySequence:
        disi    #16
        mov     #0x55,w4
        mov     w4,NVMKEY
        mov     #0xaa,w4
        mov     w4,NVMKEY
        bset    NVMCON,#WR
        nop
        nop
K1wait: btsc    NVMCON,#WR 
        bra     K1wait
        return

        .end
        
;------ End of file.
 

hello btbass i have gone through dcPIC30F3011 data eeprom programming according to your way. but in program WriteWord(address,data) i have taken the address value 0 and data 100 but it is not writing any data anywhere of entire eeprom memory address range but when i have taken the address 0xfc00 (first 16 bit lsb of 0x07ffc00) it starts writing the same address to 0x00 instead of 100. so please let me know where i am doing wrong.
 

I have just done a quick test and the project is attached.
Using mplab sim this works ok.

If you are using hardware debugger, the eeprom memory window is not updated in real time. You have to reload it to see any changes.

Let me know how you get on.
 

Attachments

  • eeprom_test.zip
    40.2 KB · Views: 242

@btbass: thanks a lot for your help, actually the problem was that my compiler was placing data in w2 instead of w1, so i changed w1 to w2 in eeprom_rw.s and it works fine, so again thanks for your kind help.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top