Author Topic: Store multi-byte variable in EE with XC8  (Read 8958 times)

0 Members and 1 Guest are viewing this topic.

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Store multi-byte variable in EE with XC8
« on: June 23, 2014, 10:42:10 pm »
Does XC8 have simple syntax for storing and retrieving multi-byte variables to/from the EE ?

I do not want to associate a variable directly with the EE space.  I simply want to store a 16-bit value at an address (uses 2 locations) and get it back.

I know I can do break it up, store high and low byte separately and do the reverse to get it back, but surely there is a multi-byte function already built in?

For Atmel programming I use ee_write_block and ee_read_block for uint16t values (and structures, etc), but can't see anything like that in XC8.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #1 on: June 23, 2014, 11:22:54 pm »
1) use a pointer to convert any data type to char;
2) use size of to store / retrieve successive chars.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #2 on: June 23, 2014, 11:34:02 pm »
Yeah, I could do that but thought that there would be something inbuilt.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #3 on: June 24, 2014, 12:05:10 am »
Just roll your own: infinitely better than what Atmel can offer.
================================
https://dannyelectronics.wordpress.com/
 

Offline zapta

  • Super Contributor
  • ***
  • Posts: 6189
  • Country: us
Re: Store multi-byte variable in EE with XC8
« Reply #4 on: June 24, 2014, 12:08:49 am »
Check section 2.5.9 here http://ww1.microchip.com/downloads/en/DeviceDoc/MPLAB_XC8_C_Compiler_User_Guide.pdf . Seems you can define variables of arbitrary type to reside in the eeprom space. Then I guess you just read/write them as standard C variables.

If you want to have it in a specific address use a pointer as suggested earlier.

typedef __eeprom int eeprom_int;
typedef eeprom_int* eeprom_int_ptr;

*((eeprom_int_ptr) 1234) = 2233;    // assignment, reading in a similar way.

(I am not a Microchip user so the above are all guesses).
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #5 on: June 24, 2014, 12:11:48 am »
I've written a pair of routines for 16 bit values, but haven't got the hang of how to do the pointer / loop method yet.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #6 on: June 24, 2014, 12:32:52 am »
Fairly simple:

1) write a routine that saves the char value pointed to by a pointer to EEPROM - the built-in routines or macros work here.
2) write a loop controlled by size of that invokes the routine you wrote in 1).
3) done.

Do the same with the retrive side as well.

It can deal with any type of data (assuming sufficient eeprom space) and is endian independent.
================================
https://dannyelectronics.wordpress.com/
 

Offline AndyC_772

  • Super Contributor
  • ***
  • Posts: 4208
  • Country: gb
  • Professional design engineer
    • Cawte Engineering | Reliable Electronics
Re: Store multi-byte variable in EE with XC8
« Reply #7 on: June 24, 2014, 08:00:57 am »
Code: [Select]
void eewrite_long (unsigned char ee_addr, unsigned long eedata)
{
unsigned char i, ie;
unsigned char * cptr;
unsigned char eeptr;

cptr = (unsigned char *) &eedata;
ie = interrupt_enable;
interrupt_enable = 0;
for (i = 0; i < 4; i++)
eewrite_byte (ee_addr++, *cptr++);
interrupt_enable = ie;
}

signed long eeread_long (unsigned char ee_addr)
{
unsigned char i;
unsigned char * cptr;
signed long eeresult;

cptr = (unsigned char *) &eeresult;

for (i = 0; i < 4; i++)
*cptr++ = eeread_byte (ee_addr++);

return eeresult;
}

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13695
  • Country: gb
    • Mike's Electric Stuff
Re: Store multi-byte variable in EE with XC8
« Reply #8 on: June 24, 2014, 08:24:27 am »
All you need to do is define the variable with an __eeprom qualifier
Code: [Select]
__eeprom unsigned long var;
I think you may be able to use the @ qualifier to specify a fixed address
Code: [Select]
__eeprom unsigned long var @0x10;
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #9 on: June 24, 2014, 09:39:53 am »
I didn't really want to use the __eeprom qualifier as there's not a direct relationship between the EE data location and where I'm using it.
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #10 on: June 24, 2014, 11:14:31 am »
Code: [Select]
void eewrite_long (unsigned char ee_addr, unsigned long eedata)
When you want to save a float type, you have to rewrite it; when you want to save 100 different struct types, you have to write 100 of such nearly identical functions...

You need something more generic than what you have here.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #11 on: June 24, 2014, 12:22:02 pm »
I've written something along the lines of what you wrote earlier Danny.  It compiled (at work) , but I've not tested it yet.

My working knowledge of pointers and other things in C is somewhat lacking.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13695
  • Country: gb
    • Mike's Electric Stuff
Re: Store multi-byte variable in EE with XC8
« Reply #12 on: June 24, 2014, 12:40:25 pm »
Code: [Select]
void eewrite_long (unsigned char ee_addr, unsigned long eedata)
When you want to save a float type, you have to rewrite it; when you want to save 100 different struct types, you have to write 100 of such nearly identical functions...

You need something more generic than what you have here.
You can write a macro that takes a pointer to the variable and uses sizeof to get its length, then you can just do ee_write(addr, varname) and it will automatically handle the type
Something like
#define writeeeprom(adr,targ) for(i=adr;i!=adr+sizeof(targ);writebyte(i++, (char*)&targ++));
 (not sure if that pointer increment syntax is right, but you get the idea)

If you're writing to something like I2C ee, you'd want your bottom-level read/write code to write multiple bytes in one operation for efficiency, so it would simplify to just passing the address and size of the variable.
« Last Edit: June 24, 2014, 12:47:47 pm by mikeselectricstuff »
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #13 on: June 24, 2014, 03:56:31 pm »
Quote
#define writeeeprom(adr,targ) for(i=adr;i!=adr+sizeof(targ);writebyte(i++, (char*)&targ++));

That isn't a good way to use a macro; and potentially dangerous, depending on how writebyte() is implemented.

You probably want the function to have three parameters:

unsigned int eeprom_addr -> starting address of the eeprom.
void * data_ptr -> pointer to data to be written to / read from eeprom.
unsigned int block_size -> the amount of data to be written to / read from eeprom.

Implementing that would be fairly simple and platform dependent.
================================
https://dannyelectronics.wordpress.com/
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #14 on: June 25, 2014, 06:04:59 am »
Can you access (read/write) individual bytes of multi-byte variables (and structures) in C ?

Does something like this work to operate on the high and low bytes for example?

Code: [Select]
uint16_t variable;
variable[0] = 1;
variable[1] = 2;
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13695
  • Country: gb
    • Mike's Electric Stuff
Re: Store multi-byte variable in EE with XC8
« Reply #15 on: June 25, 2014, 07:33:57 am »
Can you access (read/write) individual bytes of multi-byte variables (and structures) in C ?
Yes - define a union comprising an array of char plus whatever structure you need.
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline David_AVDTopic starter

  • Super Contributor
  • ***
  • Posts: 2797
  • Country: au
Re: Store multi-byte variable in EE with XC8
« Reply #16 on: June 25, 2014, 08:06:37 am »
I was more thinking of variable[ x ] where x is the byte I want.  I take it there's no way to treat the variable like an array of bytes?

I guess what I'm asking is how to I specify the individual byte of a multi-byte variable given a pointer to it?
« Last Edit: June 25, 2014, 08:08:10 am by David_AVD »
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13695
  • Country: gb
    • Mike's Electric Stuff
Re: Store multi-byte variable in EE with XC8
« Reply #17 on: June 25, 2014, 09:11:49 am »
I was more thinking of variable[ x ] where x is the byte I want.  I take it there's no way to treat the variable like an array of bytes?

I guess what I'm asking is how to I specify the individual byte of a multi-byte variable given a pointer to it?
Yes, use a union e.g.

union { unsigned long l;char c[4];} longchar;
longchar.c[n] gives byte n of longchar.l
You can use #defines to hide the union stuff
#define my_long longvar.l
#define my_chars longval.c

If my_long=0x12345678, my_chars[1] would be 0x67


Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Store multi-byte variable in EE with XC8
« Reply #18 on: June 25, 2014, 11:22:28 am »
It is so much easier to use pointers.
================================
https://dannyelectronics.wordpress.com/
 

Offline ecat

  • Frequent Contributor
  • **
  • Posts: 296
  • Country: gb
Re: Store multi-byte variable in EE with XC8
« Reply #19 on: June 25, 2014, 11:41:03 am »
It is so much easier to use pointers.

Assuming...
union { unsigned long l;char c[4];} longchar;

longchar.c is a pointer, and the address assignment is done for you. It's more safe than using a separate pointer and does not require the extra RAM space, though it is perhaps not as flexible.

If my_long=0x12345678, my_chars[1] would be 0x67

56 in old money ;) my_chars[0] would be 78 if my pic endien-ness is correct.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf