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 CCS Technical Support

Saving float value on DS1302
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
MAKInnovation



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

Saving float value on DS1302
PostPosted: Sat Feb 23, 2013 4:04 am     Reply with quote

Dear All;
How can i save a float32 value on DS1302 memory
would i convert float into some other type for saving data on memory locations.
Ashraf
hellopic



Joined: 21 Feb 2013
Posts: 8

View user's profile Send private message

PostPosted: Sat Feb 23, 2013 4:10 am     Reply with quote

Assuming you have enough space ...

uint8 array[sizeof(float)];
memcpy(array,&float_variable,sizeof(float));

Now your float_variable's data is in array, just save that. Cheers.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Sat Feb 23, 2013 4:45 am     Reply with quote

Downside is that you are moving data around unnecessarily. This is where a union comes in:
Code:

union {
   uint8 bytes[4];
   float fval;
} val;

//val.fval is a floating point variable that you can use like any other.

//val.bytes[0] to val.bytes[3] are the individual bytes


Best Wishes
hellopic



Joined: 21 Feb 2013
Posts: 8

View user's profile Send private message

PostPosted: Sat Feb 23, 2013 11:02 am     Reply with quote

I've never used unions but this looks useful, thanks. Can I ask - what other situations would they come in handy?

We can also just access the bytes from the float_value as *((uint8*)&float_value)[0] through *((uint8*)&float_value)[3] but the union thing looks cleaner.
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Sat Feb 23, 2013 12:05 pm     Reply with quote

Anywhere you want to access a value in two (or more) different ways.
Key is of course that the float is accessed just like any other float (no overhead on space or speed), and the same is true of the bytes. If you use fixed indexes (val.byte[0] for example), on most processors it codes as a single instruction.
It is supported in all C's, but (obviously) things like the byte order are processor specific. Pointer accesses tend to take more space (though the optimiser should sort this out).
However your version wouldn't work. You need to increment the pointer after the cast:

*(((uint8 *)&float_value)+3)

To get the third byte.

Best Wishes
jeremiah



Joined: 20 Jul 2010
Posts: 1354

View user's profile Send private message

PostPosted: Sat Feb 23, 2013 4:48 pm     Reply with quote

One instance I often find using unions useful in is message parsing. By creating a struct type that mimics the message and placing it in a union with a byte array, I have an easy means of converting a byte stream directly to a struct, though you have to be careful to make sure the message lines up correctly within the byte array (we use sync bytes to help make this easier).
bkamen



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

View user's profile Send private message

PostPosted: Sun Feb 24, 2013 9:38 pm     Reply with quote

Any time I've needed to save a config,

I build my struct with all my elements and then just rattle through the address of the struct and save it to NV Storage.

Saving it out and then pulling it back in the same order keeps the array intact just fine.
Code:

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

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


Any amount/type of elements can be added to the struct.

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



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 2:04 am     Reply with quote

Thank you Ttelmah;

I use Union code for saving float data on DS1302 and it is working fine.

Now, i want to send my ccs float value over serial line in IEEE 754 float format.

So need a simple conversion routine.

Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 2:10 am     Reply with quote

Doesn't anyone look in the supplied CCS code, before asking?.

ieeefloat.c, contains routines to go both ways. Funny thing is it uses a union....

Best Wishes
MAKInnovation



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Sat Mar 09, 2013 2:15 am     Reply with quote

Smile thank you
I will go through the examples
Ashraf
bkamen



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

View user's profile Send private message

PostPosted: Sun Mar 10, 2013 5:03 pm     Reply with quote

Ttelmah wrote:
Doesn't anyone look in the supplied CCS code, before asking?.


That's a rhetorical question, right?

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



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Wed Mar 13, 2013 2:09 am     Reply with quote

Yes it is and thanks to Ttelmah for emphasizing me to read examples first before asking a question.

Apart from above discussion, i would like to ask modbus related question now.

I have checked with the modbus_slave.c file first this time
and connect 18F452 microcontroller with the PC.
I receive the data on my software with illegal address which is shown below

Tx:01 03 00 00 00 0A C5 CD
Rx:F7 83 02 20 C3

what could be the reason?
I did not change any thing in the example except the following:
Uncheck this line : #define USE_WITH_PC 1

connect these data pins
Code:

#define MODBUS_SERIAL_TX_PIN PIN_C6   // Data transmit pin
#define MODBUS_SERIAL_RX_PIN PIN_C7   // Data receive pin

and made changes in this line
Code:
if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 1) // here address change from 0 to 1

Ashraf
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Wed Mar 13, 2013 3:25 am     Reply with quote

MAKInnovation wrote:
Yes it is and thanks to Ttelmah for emphasizing me to read examples first before asking a question.


Interesting...

Quote:

I have checked with the modbus_slave.c file first this time
and connect 18F452 microcontroller with the PC.
I receive the data on my software with illegal address which is shown below

Tx:01 03 00 00 00 0A C5 CD
Rx:F7 83 02 20 C3

what could be the reason?


Your addressing is the problem.

Modbus_slave.c implements just eight of each datatype: eight coils, eight input and eight holding registers. Any attempt to read a register outside of these will, correctly and in compliance with the Modbus standard, generate an addressing error. This should be obvious, and was for me when I read it carefully enough, from reading the example code.

You are attempting to read coil 10, i.e. 0X000A, but that doesn't "exist" in the slave. So it returns a Modbus address error exception. The example is, in fact, working correctly.

Extending the addressing range of the example is not as simple as it looks. There are "gotchas", so take care.
MAKInnovation



Joined: 16 Nov 2010
Posts: 61

View user's profile Send private message

PostPosted: Wed Mar 13, 2013 4:04 am     Reply with quote

Thanks RF_Developer:
Example is working within 8 numbers but the address should be 01 when reading the receiving frame instead of F7.

Tx: 01 03 00 00 00 06 C5 C8
Rx: F7 03 0C 00 88 00 77 00 66 00 55 00 44 00 33 2F 6C
Ttelmah



Joined: 11 Mar 2010
Posts: 19539

View user's profile Send private message

PostPosted: Wed Mar 13, 2013 4:17 am     Reply with quote

Whoa.
That line _must_ end if zero.

There are two things here. The first part:

modbus_rx.address == MODBUS_ADDRESS

Tests if the address byte received matches your system's modbus address.

The second:

|| modbus_rx.address == 0

Tests if instead it matches the modbus _broadcast_ address (0).

This is part of the modbus spec, and _must not_ be changed.

Your system _must_ receive broadcast messages. If you change the value to 1, it won't......

The address you are to listen for 'other than this', is defined by 'MODBUS_ADDRESS'. This is the one you can change.

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
Goto page 1, 2  Next
Page 1 of 2

 
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