[TUT] [C] Using the EEPROM memory in AVR-GCC

Go To Last Post
356 posts / 0 new

Pages

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks clawson, i saw several other comments to this tutorial with eeprom issues so i thought it'd be ok.
the tutorial quotes:

Quote:
void eeprom_write_block (void *pointer_eeprom, const void *pointer_ram, size_t n)

while eeprom.h void function is:
Quote:
void eeprom_write_block (const void *__src, void *__dst, size_t __n);

warnings corrected, and the output improved:

23456789

but the first byte is corrupted. it should be

123456789

any ideas? thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ahhh ok, after a few trials, basically when Es_month is 4 digits, the response has the 1st byte of Etot corrupted.

For ex:

Etot = 12657;
Es_month = 345;
Ew_month = 789;
12657345789

ok. If

Etot = 12657;
Es_month = 3456;
Ew_month = 789;
26573456789

WRONG. 1's byte corrupted. Should be 12657.

Etot = 12657;
Es_month = 345;
Ew_month = 7896;
126573457896

ok.

Etot = 1265;
Es_month = 3456;
Ew_month = 789;
2653456789

wrong.

Etot = 1265;
Es_month = 34;
Ew_month = 789;
126534789

ok...

Dean mentioned:

Quote:
Remember that in C a zero byte is treated as a null-terminator -- if you have junk data in the first 10 bytes of the string, chances are one might be a terminator which will stop any display of the buffer contents before the contents of the EEPROM read string is reached.

and again a few comments later

Quote:
You need to read/write one more byte to EEPROM than there are characters in the string -- there's a hidden 0x00 byte at the end of each string which terminates it. Without the terminator, your string routines will become confused.

Maybe this could be the problem? I can't find why the 1st byte is getting corrupted when Es_month is a 4 digit number :/

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
char Etot_str[5]; 
char Es_m_str[4]; 
char Ew_m_str[4]; 

These are surely far too small? A string defined as [5] can hold 4 digits and the terminating 0x00. A string defined as [4] can hold just 3 digits and the 0x00. If you try to put a four digit string into [4] it will write over the start of the next string in mmeory.

Personally I always work out the worst case> For example largest itoa() is going to be 5 digits, possibly with sign so 6 characters, then you need room for the 0x00. So 7 characters. To be safe I'd blow the memory budget and just make it [8] or if I was feeling particularly flaithiúl I'd actually make it [10] to be aboslutely positive. Start cutting the [10]s back to [8]s when you thing RAM is getting low. (and test the worst case strings)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
A string defined as [5] can hold 4 digits and the terminating 0x00. A string defined as [4] can hold just 3 digits and the 0x00.

didn't know that! Thank you very much! : )

- Eric

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do somebody know if i could somehow monitor (make readable) my internal EEPROM to the device outside. For example: I have TI PGA309 signal conditioner which requires external EEPROM to read config data. It uses I2C aka TWI for reading. Can i somehow make my Atmega 324 memory readable by PGA309 via TWI?
Thanks!

Estonia, Otepää is the place where you can find me...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can simulate whatever kind of interface the PGA309 expects to use with a microcontroller such as an AVR so the answer is yes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So practically it means mechanically write all the functions: 1)set avr in slave read mode
2)make functions which emulate the prodecure when PGA asks memory location this n that answer with a memory location from AVR eeprom?
Okay then.
It would be simpler to program PGA through UART then...
I just thought maybe there is some shortcut how to do this.

Estonia, Otepää is the place where you can find me...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Question regarding the EESAVE fuse:

I am somewhat new to programming micro controllers, so please excuse me if this is a dumb question...

In my program, I declare several "variables" with the EEMEM attribute. At the beginning of the program, I read the values in (garbage if the EEP file was not downloaded). The user of the program has the capability of changing the values stored in the EEPROM. Scenario: a user sets all of the EEPROM variables to valid values. The board is then turned off. When it is turned on again, the program re-initializes its SRAM equivalent variables from EEPROM. I understand all this (isn't that the point of EEPROM?). However, if I set the ESAVE fuse, make some changes to the program and recompile it, and re-download it to the chip, what does it matter if the EEPROM is overwritten or not? Won't the compiler have given different addresses to my EEMEM variables? How will the program know where the previously saved EEMEM variables are stored?

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's true, however if you place *all* your EEPROM variables into a single struct, as long as the compiler's packing and ordering rules are not changes between versions those variables should always map to the same place.

It's also useful for assembly programmers or manual EEPROM location management, sine in that case you always certain where everything is stored.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That makes sense. If I create a struct with a bunch of settings, I think I would always need to read/write the EEMEM variable to/from EEPROM in its entirety (i.e., couldn't do just one of the subvariables). Is this true?

From Clawson's post on page 7:

clawson wrote:

#include 
#include 

typedef struct {
  int16_t n;
  char c;
  uint8_t array[10];
  uint32_t l;
} data_type;

data_type copy_in_EEPROM EEMEM;
data_type copy_in_RAM;

int main(void) {
  copy_in_RAM.n = -23456;
  copy_in_RAM.c = 'A';
  copy_in_RAM.l = 0xDEADBEEF;
  memset(copy_in_RAM.array, 0x5A, sizeof(copy_in_RAM.array));
  eeprom_write_block(©_in_RAM, ©_in_EEPROM, sizeof(copy_in_RAM));
  while(1);
}

After that has run the EEPROM will contain those data values I set in the struct{}

If I wanted to read the data from memory into a RAM structure, would the code be:

myStruct EEMEM eepromCopy;
myStruct RAMcopy;

eeprom_read_block((void*)&RAMcopy, (const void*)eepromCopy, sizeof(RAMcopy));

P.S. Since I boorishly forgot to say it in my first post -- thanks for taking the time to put together such a good tutorial.

Science is not consensus. Science is numbers.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

would the code be:

Yes.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

rosvall wrote:
abcminiuser wrote:

(...)

At the moment, we now have access to the eeprom memory, via the routines now provided by eeprom.h. There are three main types of EEPROM access: byte, word and block. Each type has both a write and a read variant, for obvious reasons. The names of the routines exposed by our new headers are:

Quote:

(...)
� void eeprom_read_block (void *pointer_ram, const void *pointer_eeprom, size_t n)
� void eeprom_write_block (const void *pointer_ram, void *pointer_eeprom, size_t n)

(...)

I think you've got the two first arguments to eeprom_write_block in the wrong order.

From eeprom.h:

Quote:

static __inline__ void
eeprom_write_block (void *__dst, const void *__src, size_t __n)

Well... I just tried writing some code using eeprom_write_block and my compiler gave me a warning so I checked and it looks like the order of my eeprom_write_block is back to the original "wrong" order. So which one is correct? :)
Looks like someone is changing things on us hehe.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I currently use the EEPROM to store some program configuration data (i.e. thresholds, durations, ...).
Now I want to adapt the program behaviour by patching some single EEPROM bytes. As far as I know AVR-Studio can only writw down complete EEPROM-files. Which tool can be used to do that? Wouldt be great if someone knows a simple command line tool.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

As far as I know AVR-Studio can only writw down complete EEPROM-files. Which tool can be used to do that? Wouldt be great if someone knows a simple command line tool.

Read the entire eeprom to a .hex - change one byte then write the whole thing back.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks so much for all your helpful tutorials mate.
They are much appreciated especially when you've left your Final Year project this late lol :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sir i am trying to do a line follower and i am not able to program it so pls help me with it

abcminiuser wrote:
Davef,

Damnit, yet another typo. That should indeed be read_word - I'll go fix that now. Amazing that anyone still bothers to read my tutorials with all these silly mistakes!

Quote:
In , eeprom_read_byte and eeprom_write_byte use a u08 pointer for the address. Doesn't this mean you can only access 256 bytes in the EEPROM? What about the remaining 1024-256 = 968 EEPROM bytes in a ATmega32?

That tripped me up too at the start. In AVR-GCC, all pointers are an int in size, two bytes. The pointer typecast only specifies what type of data the pointer is pointing to, not the pointer's size. A (uint8_t*), (uint16_t*) and (uint32_t*) are all identical in size, they just point to increasingly larger datatypes.

For example, (uint8_t*)0x1234 is a pointer two bytes in size, pointing to a byte at the location 0x1234.

This is a problem when dealing with pointers to the AVR's flash memory, since in some AVRs this overflows an int. Because of this, pointers to flash addresses are still two bytes in size but the pointer is word rather than byte aligned, so an increase of one in the pointer's address corresponds to a jump of two bytes.

If I can think of enough material for this I might make it into a short tutorial since it seems to be such a prevalent issue.

- Dean :twisted:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

trying to do a line follower

Then kindly explain what on earth the post you quoted or this entire thread has to do with your question?!? This thread is about using EEPROM with the avr-gcc compiler.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've read this thread and now know how to use EEMEM to have the compiler generate a .eep file to 'initialise' basic eeprom variable, and arrays.

I am using an 'overall structure' to hold all my eeprom variables.

I need to initialise an array of structures within the outer structure

typedef struct INNER_STRUCT1 {
  uint8_t var1;  
  uint8_t var2;
  int8_t  var3;
} innerStruct1_t;

typedef struct INNER_STRUCT2 {
  uint8_t var1;  
  uint8_t var2;
  int8_t  var3;
} innerStruct2_t;

typedef struct OUTER_STRUCT {
  uint8_t        outerVar1;
  uint8_t        outerVar1;
  uint8_t        outerVar1;  
  innerStruct1   innerVars1[5];
  innerStruct2   innerVars2[5];
} outerVars_t;

So when I use

outerVars_t   EEMEM   EE_Vars = {22,100,12,?help;

is it possible initialise the inner array of structures?
or is there a better way of doing this?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
outerVars_t   EEMEM   EE_Vars = {
 22,
 100,
 12,
 { 
   { is1_var1_val, is1_var2_val, is1_var3_val }, // iV1[0] 
   { is1_var1_val, is1_var2_val, is1_var3_val }, // iV1[1] 
   { is1_var1_val, is1_var2_val, is1_var3_val }, // iV1[2] 
   { is1_var1_val, is1_var2_val, is1_var3_val }, // iV1[3] 
   { is1_var1_val, is1_var2_val, is1_var3_val }  // iV1[4] 
 },
 { 
   { is2_var1_val, is2_var2_val, is2_var3_val }, // iV2[0] 
   { is2_var1_val, is2_var2_val, is2_var3_val }, // iV2[1] 
   { is2_var1_val, is2_var2_val, is2_var3_val }, // iV2[2] 
   { is2_var1_val, is2_var2_val, is2_var3_val }, // iV2[3] 
   { is2_var1_val, is2_var2_val, is2_var3_val }  // iV2[4] 
 }
};

If your C compiler supports C99 you can also use named initializers:

outerVars_t   EEMEM   EE_Vars = {
 .outerVar1 = 22,
 .innerVars1[3].var2 = 0xF3,
 .innerVars2[1].var3 = -17
};

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you Cliff :) - it's obvious when you see it written down, but I just couldn't get my head round it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks to info.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Everyone,
I have a very simple question. Would these eeprom instructions work for the avr atmega1284p microcontroller.The datasheet is below ,please kindly have a look as i am a newbie and understand very little of programming language

http://www.atmel.com/Images/8059...

Please kindly respond as soon as possible as i need to learn this programming and then write the code for my greenhouse project. Thank you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
I have a very simple question. Would these eeprom instructions work for the avr atmega1284p microcontroller.

I have a very simple answer: Yes. :D

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

help me pls! for my bugs (

EEMEM char ok_test[] = "Test Ok!\n\r";
EEMEM char copy_right[]="8-bit Test device super puper multi pulti, C 2012 Vr.SuperWriter";

void SendStr(char *string)
{
while (*string!='\0')	/
	{
	SendByte(*string);		
	string++;		/
	}			
}

void SendByte(char byte)		
{
while(!(UCSRA & (1<<UDRE)));	
UDR=byte;			
}
int main(void)
{
	USART_Init(51);
	char *u;
        string[]=""
	u=string;

	eeprom_read_block(u,ok_test,sizeof(ok_test));
	SendStr(u);
        eeprom_read_block(u,copy_right,sizeof(copy_right));
	SendStr(u);
	

In terminal correct writing message Test Ok!
but next message endlessly repeated ((
Another said that if eeprom_read_block(u,copy_right,16) displays correctly the first 16 characters
Where did I go wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

eeprom_read_block(u,ok_test,sizeof(ok_test));

u is a pointer but is only pointing at ONE BYTE of allocated storage?!? I'm not going to count all the characters in copy_right[] but maybe try something like:

int main(void)
{
   USART_Init(51);
   char u[50];
...

But why make a RAM copy anyway? Why not make SendStr() read direct from EEPROM? (if you might also have a SendStr() to read from RAM then add an E or something):

void SendStrE(char *string)
{
  while (eeprom_read_byte(string) != '\0')  
   {
   SendByte(eeprom_reasd_byte(string));      
   string++;      /
   }         
} 

int main(void) {
  USART_Init(51);
  SendStrE(ok_test);
  SendStrE(copy_right);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (eeprom_read_byte(string) != '\0')

Compiler error:
Error 1 invalid conversion from 'char*' to 'const uint8_t*'

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm a newbie. Other than the non-volatility, are there other reasons why you would use EEPROM instead of flash? Flash also stores data without power applied, corect?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I'm a newbie. Other than the non-volatility, are there other reasons why you would use EEPROM instead of flash? Flash also stores data without power applied, corect?

Flash can only be written in pages (batches of 128 or so byte blocks) and can only be modified from the bootloader section of the chip. The EEPROM is byte addressable, and can be altered from anywhere. Special fuses in the newer chips allow the EEPROM contents to be preserved between application reprogrammings, while any custom flash data would be destroyed.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HI
i have a qustion!

when i use void eeprom_update_byte (uint8_t *__p, uint8_t __value); or like this function?

or when are these beter to use ?

and can i use e.g,
void eeprom_write_byte (uint8_t *__p, uint8_t __value);

insted
void eeprom_update_byte (uint8_t *__p, uint8_t __value);

?

thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Always use the update function - it takes a few extra cycles (not very many at all) but will skip the writing of EEPROM cells that are already in the desired state. That means that you will generally save time overall if most of the bytes' values haven't changed, and it will save the lifespan of the EEPROM.

The write functions are provided for backwards compatibility and shouldn't be used in new applications.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks alot for rapid answer!

Quote:

The write functions are provided for backwards compatibility and shouldn't be used in new applications.

now, i "should" or "must" use the update function insted The write functions for any application ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

now, i "should" or "must" use the update function instead The write functions for any application ?

There is no absolute truth re this, no one single dictated way to do things. Dean already explained the pros and cons of both set of functions. Let's try again:

The update set of functions execute slightly slower, but generally imposes less wear on the EEPROM.

The write set of functions execute slightly faster, but potentially wears down the EEPROM faster. When it is said about some function that it "should not be used in new applications" this often means that there is a plan to remove the function eventually.

With that information you are absolutely free to pick either the write or the update version of the functions, and then be prepared for the consequences of your choice:

If you have extremely tight demands on performance you might go for the write functions, but when they are possibly removed from avrlibc you will have to implement your own. If such tight demands are not present, you of-course go with the update versions because they impose less wear on EEPROM and they will most likely remain in avrlibc for the foreseeable future.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks a lot.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note that the time required to read the EEPROM is very little, when compared to the time required to write to it - so if your data to write doesn't change much, you can actually save time overall with the update functions as well as preserve the EEPROM's lifespan. I'd say that using the write functions over the update functions would be something done 1% of the time, and as a general rule the update functions should always be used unless you absolutely know what you are doing.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello, I was trying in many ways to figure out where I was wrong, please, help. This is my code:

	GetAbsPos(101,&Apos);
	eeprom_write_block((const void*)&Apos, (void*)&EEVar, sizeof(long));

	/*for(uint8_t i=0;i<4;i++)
	{
		uint8_t Data;
		Data=Pomocna;
		__EEPUT((i+10),Data);
		Pomocna>>=8;
		
	}*/
	MotorStop(101);
	
	}

Whatever I tried, there was nothing in .eep file.
I tried and Optimization -Os. I included eeprom.h header, and nothing.Defined EEVar as EEMEM.
I am new in all this, and I got assignment to program robot! :?

Thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Whatever I tried, there was nothing in .eep file.

There is nothing in what you show that would create a .eep file??

You appear to be using eeprom_write_block(). (BTW that should be eeprom_update_block() these days). That is a run time function it does not create fixed .eep data at compile time.

If you wrote something like

char text[] EEMEM = "Hello world";
struct {
  int n;
  char c;
  long l;
} eedata EEMEM = {
  12345,
  'A',
  0xBABEFACE
};

then either of those WOULD create .eep data.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I must correct myself. I defined EEVar like EEMEM, and I've gotten .eep but full with zeros. I have no write in EEPROM!

Thank you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Short of a crystal ball I don't know how it's possible to help you without seeing the code you are talking about. If I use the code I showed above I get:

E:\avr>type test.eep
:1000000048656C6C6F20776F726C6400393041CE3C
:03001000FABEBA7B
:00000001FF

E:\avr>avr-objdump -s test.eep

test.eep:     file format ihex

Contents of section .sec1:
 0000 48656c6c 6f20776f 726c6400 393041ce  Hello world.90A.
 0010 fabeba                               ...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Here is a code:


#include 
long EEMEM Putanja1;
long EEVar;
long ReadLongFromEeprom(void)
{
   long temp;
   eeprom_read_block((void*)&temp, (const void*)&EEVar, sizeof(long));
   return(temp);
}

int main()
{
do{	ADCSRA|=(1<<ADSC);//i use Sharp sensor for 
//detectio, and this all works exept writing in //EEPROM
	if (ADC>=500)
	{
	GetAbsPos(101,&Motor1AbsPos);//here i get 
//value of counter
	eeprom_update_block ((const void *)&Motor1AbsPos, (void *)&EEVar, sizeof(long));
	MotorStop(101);
	break;
	}
}while(1);
while(1);
}

Thanks :)

Last Edited: Sat. Apr 14, 2012 - 08:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
   ADCSRA|=(1<<ADSC);//i use Sharp sensor for
//detectio, and this all works exept writing in //EEPROM
   if (ADC>=500) 

You aren't waiting for the conversion to complete? Make that:

   ADCSRA|=(1<<ADSC);//i use Sharp sensor for
//detectio, and this all works exept writing in //EEPROM
   while(ADCSRA & (1<<ADSC)); // wait while the bit remains high
   if (ADC>=500) 

Anyway on the EEPROM thing:

long EEMEM Putanja1;
long EEVar;
long Motor1AbsPos;

long ReadLongFromEeprom(void)
{
   long temp;
   eeprom_read_block((void*)&temp, (const void*)&EEVar, sizeof(long));
   return(temp);
} 

(a) nothing here would create a .eep file

(b) as nothing else is done to write to the EEPROM one has to assume it contains all 0xFF after a chip erase

(c) the read_block call is wrong. Why using _block_ when it's a 23bit "dword" you are reading anyway? eeprom_read_dword() would seem the more obvious call to read the 4 bytes of a "long". As written the call is:

eeprom_read_block((void*)&temp, (const void*)&EEVar, sizeof(long));

OK, the destination is fine - temp is "long" and the 3rd parameter is passing sizeof(long) so this will be reading 4 bytes. However the source address for that read is wrong. You are using the address of EEVar yet this is a RAM based variable? Surely what you intended to read from here was "Putanja1" so its the address of that (which is an address in EEPROM as that variable is declared as EEMEM) that you should be passing.

If you want a .eep file and you want it to have an initial value then use something like:

long EEMEM Putanja1 = 12345678;
long Motor1AbsPos;

long ReadLongFromEeprom(void)
{
   long temp;
   eeprom_read_block((void*)&temp, (const void*)&Putanja1, sizeof(long));
   return(temp);
} 

When you build this program a .eep file will then be created. If you program that into the AVR's EEPROM when you also put the program code in then the eeprom_read_block will then read 12345678 back from the "Putanjal" location and store it into "temp". However as I say eeprom_read_dword() is a more obvious function so:

long EEMEM Putanja1 = 12345678;
long Motor1AbsPos;

long ReadLongFromEeprom(void)
{
   return eeprom_read_dword((void*)&Ptanjal);
} 

will do what you require here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have a few more questions:

1.
I ran first part where I put some data in EEPROM, and loaded code into FLASH and EEPROM,than I comment that part and ran "Read" part. So, do I have to program again EEPROM, each time when I load code in FLASH? (Probably silly question, but i didn't work with EEPROM before)
2.
And, when I look hex. editor there is something like
:040000006400000098
:00000001FF
where "64" is initial EEMVE variable like Address, but what is this "98" ?

Thank you for your explanation, it help me a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
but what is this "98"
It's the inverted checksum of the line. Not data.

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figure it out and finally- all works!

Thank you all. This is one fantastic forum! :D

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Again, I have a problem. I want to put 2 Arrays in EEPROM, and after to read them. I am certain that data are correct written into EEPRom (the .eep seys so because I defined Arrey[13] and in .eep found 4 lines with smth like arrey- the number I only used), but when I want to read them, there is a problem.
Did I correctly call "Read" function:

	eeprom_read_block ((void *)&Array, (const void *)ArrayEE, sizeof ArrayEE[0]);
	eeprom_read_block ((void *)&Value, (const void *)&ValueEE, sizeof ValueEE[0]);

I also tried instead of ArrayEE with &ArrayEE, but nothing. I defined smthEE like EEMEM.
Also there is a chance that I wrote smth bad in "for" loop, if it's that case, please just tell me, so I can try to fix that. Here is a code:

for(i=0;i<13;i++)
{
	for(j=0;j<13;j++)
	{
		if((i==j))
		{
			SetAbsPos(101,0);
			switch(Array[i])
			{
				case 1:
					SetSpeed(0,100,101);
					MotorStart(1,0,0);
					_delay_ms(100);
					GetAbsPos(101,&Motor1AbsPos);
					while(Motor1AbsPos<=Value[j])
					{
						
						SetAbsPos(101,Motor1AbsPos);
						_delay_ms(100);
						GetAbsPos(101,&Motor1AbsPos);
					}
					break;

Thanks, again.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Why read the whole array into RAM? Why not pick up the element you need one at a time? Anyway if you really want to read the whole array you do not want

sizeof ArrayEE[0]

That's only the size of a single element not the whole array.

Anyway here's a simple example reading the elements of an array one at a time:

#include 

uint8_t eedata[] EEMEM = { 17, 89, 109, 214, 5, 226, 82 };

for (int i=0; i < 7; i++) {
  PORTB = eeprom_read_byte(&eedata[i]);
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok! I'll try. Thank you for quick answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I updated the tutorial PDF contents on my site the other day to reflect the API changes made to the EEPROM library over the last few years. Download the PDF from here for the latest version:

http://fourwalledcubicle.com/AVR...

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am sorry to bother you again, but it seems that I can't put an array in EEPROM, I've read Dean's tutorial and I think I understood how it works, but it won't to read/write in EEPROM. Is there something else I can do that not include program, some adjustments in maybe AVR Studio 4 or ISP communication?

Thank you. :oops:

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should produce a minimal but complete, clean building and runnable program that demonstrates the problems you describe. Ideally we're talking about perhaps 20 lines of code. Post that program here and we can help.

You are aware of that AVR Studio 4 has a checkbox for if the EEPROM contents should be preserved or ereased dirung flash programming?

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I checked that box. Here is code:

#include
#include 
long Value[13];
int EEMEM ArrayEE[13];
long EEMEM ValueEE[13];
int Array [13];
int main()
{
/*
do{
	senzor=Senzori();
	Array[k]=senzor;
switch (senzor)
{

}//switch
}while(senzor!=5);
	eeprom_update_block ((const void *)&Array, (void *)&ArrayEE, 13);
	eeprom_update_block ((const void *)&Value, (void *)&ValueEE, 13);
_delay_ms(10);
*/
uint16_t Red;
uint32_t Vrednost;
for(i=0;i<13;i++)
{
Red=eeprom_read_word ((const uint16_t *)&ArrayEE[i]);
Vrednost= eeprom_read_dword ((const uint32_t *)&ValueEE[i]);
	
	switch (Red)
	{
	}// switch
while(1);
}//main

I checked the Array and it form good values, but the problem is that it won't to put in EEPROM, I've been looking that code for days, but I couldn't find where I'm wrong?

Last Edited: Sat. Apr 14, 2012 - 07:37 PM

Pages