CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

(SOLVED) Saving a 16bit signed integer in eeprom.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Diode



Joined: 27 Jul 2012
Posts: 35

View user's profile Send private message

(SOLVED) Saving a 16bit signed integer in eeprom.
PostPosted: Tue Dec 04, 2012 12:37 pm     Reply with quote

I'm having some difficulties with saving 16 bit signed integers in the eeprom of a pic18F2523.

The idea is to periodically store some data in the internal eeprom. My code is working fine for unsigned int16 data but as soon as I try to use it for a signed int16 it doesn't work anymore.

Here is the declaration of the variables:
Code:

int8 setpoint_lowbyte;
int8 setpoint_highbyte;
signed int16  setpoint;


The eeprom function:
Code:

Setpoint_lowByte = ((setpoint >> 0) & 0xFF);
Setpoint_highByte = ((setpoint >> 8) & 0xFF);
write_eeprom(eeprom_address+6,setpoint_lowByte);
write_eeprom(eeprom_address+7,setpoint_highByte);
SETPOINT = ((setpoint_highByte << 8));
SETPOINT = SETPOINT |  (setpoint_lowbyte);


Let's assume setpoint is 275. If I declare setpoint as int16 (unsigned by default) highbyte is 1 and lowbyte is 19, this is correct.

When I declare setpoint as signed int16 highbyte remains 0 and lowbyte is 19.

Does anyone know why this happens with signed int16 data? All help will be appreciated.


Last edited by Diode on Wed Dec 05, 2012 9:37 am; edited 1 time in total
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 1:10 pm     Reply with quote

There's kind of an easier way if you're interested...


I make a struct called "config"...

Code:

struct {
    unsigned int byte1;
    unsigned int byte2;
    signed int16 word1;
} config;


then I have a routine that looks like this

Code:

// ============================
// load_save_config( mode ) : load_save_config routine
//
void config_load_save ( int rw ) {
   int i;

   for (i=0;i<=(sizeof(system_config)-1);++i) {
      switch (rw) {
         case load : *(( (int8 *) &config) + i) = read_eeprom(i);
                  break;

         case save : write_eeprom( i, *(( (int8 *) &config) + i) );
                  break;
      }
   }
}

_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
Diode



Joined: 27 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 1:25 pm     Reply with quote

Thanks for your reply. I'm a "beginner" in C programming so your solution might be a bit hard to understand for me.

If I understand it correct you have made a for_loop to write the different addresses of the eeprom. The RW is a read/write bit depending of it's value you read or write the data.

Then you do something with pointers and that's the part where I get lost.
bkamen



Joined: 07 Jan 2004
Posts: 1611
Location: Central Illinois, USA

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 1:32 pm     Reply with quote

Diode wrote:
Thanks for your reply. I'm a "beginner" in C programming so your solution might be a bit hard to understand for me.

If I understand it correct you have made a for_loop to write the different addresses of the eeprom. The RW is a read/write bit depending of it's value you read or write the data.

Then you do something with pointers and that's the part where I get lost.


It's probably mandatory then that you read up more on C and also get the book "The C Programming Language" written by Dennis Ritchie and Brian Kernighan -- the guys who invented C.

Correct: The RW bit tells the function whether to load the struct config with EEPROM contents or to SAVE the struct config contents to EEPROM.

The loop automatically sizes against config's number of bytes and then saves/loads those bytes to/from EEPROM.

Remember that a variable stores values (contents) but also must live in memory (location).

A pointer is the value of that location. (its address)

Again, I can't stress/recommend getting that book enough.

-Ben
_________________
Dazed and confused? I don't think so. Just "plain lost" will do. :D
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 2:32 pm     Reply with quote

Hi,

You didn't post your compiler version, so I won't test your code. I will note,
however, that CCS does provide a canned function, Make8(), that will
extract the bytes from either an int16 or an int32, so you might give that a
try and see if it solves your problem? This function, and companion functions
like Make16() are described in the manual.

Good Luck!

John
Diode



Joined: 27 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 3:33 pm     Reply with quote

Ben, I will look for the book you mentioned. I have a book about C but this one is more focused on C for computers.
The book I have describes the use of pointers but it still is a bit vague to me. Probably wise to read it a few times again.

John, the compiler version is 4.013. Just had a quick look at the help function and it seems to do exactly what I need. Tomorrow I will try make8 and make16 to see if it solves the problem.

Both thanks a lot for the help.

Bas (from the Netherlands)
ezflyr



Joined: 25 Oct 2010
Posts: 1019
Location: Tewksbury, MA

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 4:46 pm     Reply with quote

Hi Bas,

You should be aware that your compiler version is one of the very early
version 4 releases of the compiler, and predates by quite a bit the first
'stable' releases for version 4. Keep that in mind as you develop your code
Very Happy !

John
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Tue Dec 04, 2012 5:30 pm     Reply with quote

ezflyr wrote:
... and predates by quite a bit the first 'stable' releases for version 4.
I would state that stronger: if anything works in 4.013 than you should be considered lucky. The first versions that started to work more or less reliable required CCS to release 60 more versions, that is to say that from around 4.073 the compiler became usable again.

Either downgrade to v3.249 that was a very good version but lacks the new v4 features, or upgrade to one of the newer versions.
Diode



Joined: 27 Jul 2012
Posts: 35

View user's profile Send private message

PostPosted: Wed Dec 05, 2012 2:11 am     Reply with quote

John, seen the post of ckielstra I must be lucky that it works at all Very Happy
At least your comment about the make8 and make16 functions solved my problem, it works fine now. Even in version 4.013
These functions perform the same function as the code I wrote but apparently I have made a mistake somewhere.

I have heard before that my version was not one of the best versions made. First I want to finish this project and then I will see.
In general I'm quite satisfied with the compiler and ICD-64 programmer of CCS.

Thanks for the help, I was struggling quite a long time with this problem and now it is solved within a few hours!
Ttelmah



Joined: 11 Mar 2010
Posts: 19368

View user's profile Send private message

PostPosted: Wed Dec 05, 2012 2:52 am     Reply with quote

As a general comment, shifts are always dangerous with signed numbers. K&R has the comment 'the result is undefined if the right expression is negative'. The problem is what you do with the sign. This depends on the processor.
For storing numbers, if you needed to use shifts, and work with signed numbers, you are actually better to convert the number to unsigned before shifting and similarly on the re-assembly, do the work with unsigned values, and then put them back to signed again afterwards.
Generally though, a Union, is a more 'universal' solution, while with CCS, the make8, and make16 functions avoid the overheads of shifting at all. Smile

Have to re-iterate that 4.013, is an 'accident waiting to happen'. Things _will_ have a habit of having inexplicable failures with this. Some basic stuff did work (funnily in this, it was perhaps better than some of the versions up around 4.050), but it was no more than an alpha test release, in terms of being even remotely 'useable'.....

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group