Page 1 of 1

How can I concatenate 4 bytes ?

Posted: 13 Sep 2010 09:34
by Olivia
How can I concatenate 4 bytes ?

I know strcat.
But that is only doing 2 bytes at a time.

Thanks

Re: How can I concatenate 4 bytes ?

Posted: 13 Sep 2010 17:23
by Sparky1039
If this is only data and not string chars then one way is to use a union. If you look at this older thread it will show how to combine 2-bytes into an int. In your case it's 4-bytes into a long, so adjust the union size and member count accordingly.
http://www.mikroe.com/forum/viewtopic.php?f=88&t=25930

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 12:24
by Olivia
No, I can't make it work.

I have 4 bytes from this chip DS1682
at addresses
0x05 low
0x06 middle low
0x07 middle high
0x08 high

I want to put all of them in a big long and then divide it by 4 and display it on LCD.

Can someone help me?

Thanks.

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 12:48
by Kalain
Hi,

Have a look at hi, Higher and Highest (lo, lower, lowest) instructions in help file.
You will find what you are looking for.

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 13:08
by jumper
try this way

Code: Select all

unsigned long Long_data =0 absolute 0x10;
unsigned short low_byte =0 absolute 0x10;
unsigned short middle_low =0 absolute 0x11;
unsigned short middle_high =0 absolute 0x12;
unsigned short high_byte =0 absolute 0x13;

Read each byte into the correct variable and then you have your Long variable added together in the RAM memory by "misstake".

It is not a very nice solution but it will do the job. If you make your own function and pass the variables to it and let it return the long result it is not such a bad idea..

Code: Select all

my_long_value=Make_Long(var1,var2,var3,var4);

or

Code: Select all

unsigned long my_var=0;

my_var=high_byte;
my_var=(my_var << 8) + middle_high;
my_var=(my_var << 8) +middle_low;
my_var=(my_var << 8) + low_byte;
my_var will now contain all the bytes in the order Higest, high, lower, lowest.

Just make sure to use the ( ) in the right places or it will not work

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 16:27
by Dany
jumper wrote:

Code: Select all

unsigned long my_var=0;

my_var=high_byte;
my_var=(my_var << 8) + middle_high;
my_var=(my_var << 8) +middle_low;
my_var=(my_var << 8) + low_byte;
I do not know about C, but in mikroPascal one can do the following:

Code: Select all

Highest(my_var) := high_byte;
Higher(my_var) := middle_high;
Hi(my_var) := middle_low;
Lo(my_var) := low_byte.
Normally it is not possible to use a "procedure" name at the left hand side of the assignment sign (:=), but here is an execption: the procedures are inline and can take a value apparently (in mP that is, to be checked in mC).

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 16:31
by Olivia
Thank you jumper

It is working now.

See, I'm not that stupid, I'm stupider than that.

I have tried jumper's solution previously (on my own idea), and it did not work.
Because I shifted it the other way.

jumper's solution:

Code: Select all

etc = (aad<<32)+(aac<<16)+(aab<<8)+aaa;
LongToStr(etc/4, txt);  //need to divide by 4, as the chip is incrementing in quarter-second
Glcd_Write_Text(txt, 1,7,1) ;
works almost perfect.

I say almost, because it seems my chip is 1 second faster per minute.
Which it should not be. It's supposed to be more accurate than a 32k crystal.

and I was shifting it the other way:

Code: Select all

etc = (aad>>32)+(aac>>16)+(aab>>8)+aaa;
That's why I lost 2 days.

Now, anybody can give me a clue, why is going 1 sec faster/min?

And another question, please:
I do not want the display to show me only seconds, which in time might be:
1073741823 seconds
How do I display it this way:
years:months:days:hours:min?

Thank you for help.

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 16:55
by jumper

Code: Select all


unsigned char sec;                                      // sec number variables
unsigned char minutes;                                // min
unsigned char hours;                                    // hours
char TIME[10]=" 00:00:00" absolute 0x20;     
char hours_s[3] absolute 0x20;                     //  string variables 
char minutes_s[3] absolute 0x23;                  //  
char sec_s[3]absolute 0x26;                        //


unsigned char day;                                    // day
unsigned char month;                                //month
unsigned char year;

char DATE[10]=" 09/05/07" absolute 0x30;
char year_s[3] absolute 0x30;
char month_s[3] absolute 0x33;
char day_s[3]absolute 0x36;


void Update_time(){

           // split your long seconds variable into years, months ,days, hours, min and secs and put them into the hours, minutes and sec bytes

           ByteToStr(hours,hours_s);
           if (hours_s[1]==' ') hours_s[1]='0';
           ByteToStr(minutes,minutes_s);
           minuter_s[0]=':';
           if (minutes_s[1]==' ') minutes_s[1]='0';
           ByteToStr(sec,sec_s);
           sec_s[0]=':';
           if (sec_s[1]==' ') sec_s[1]='0';

           ByteToStr(year,year_s);
           if (year_s[1]==' ') year_s[1]='0';
           ByteToStr(month,month_s);
           month_s[0]='/';
           if (month_s[1]==' ') month_s[1]='0';
           ByteToStr(day,day_s);
           day_s[0]='/';
           if (day_s[1]==' ') day_s[1]='0';


            GLCD_write_text(DATE, 0, 1, 1) ;
           GLCD_write_text(TIME,70, 1, 1) ;
}

This code was from an old clock application.....

BUT :-)

This will help you regain some of the 2 days you lost but still I hope you try to study the code and not just copy/paste it into your project. You would still need to understand what the code does for beeing able to adjust it to your needs..

There are probably a million better ways to to this but hey.. if it works it is a good start.

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 17:19
by jumper
Regarding your concern about the 1 sec per minute lost.. well look at the datasheet. Doesn't it say
Calibrated, Temperature-Compensated RC Time
Base Accurate to 2% Typical
1 sec per min is a little bit better than 2% and probably not much you can do about that unless you get a better time base i.e AC power line. And this 1 sec will probably drift with temperature so you can probably not remove it with a calculated formula.

So, make a SAFE circuit to detect zero crossings and connect to your generator and then every zero crossing will generate an event on the ds-chip you use today. Hopefully the generator outputs a constant FQ or you have bigger problems than just loosing a few seconds.

Just make sure you don't kill yourself when you connect to the high power AC line!

Or just live with the +-14 hours per month running time unless you use this time for billing purposes and not just for service intervals. If it is for service then to get the proper staff to do the service will affect the end result much more than your 2% error...

Re: How can I concatenate 4 bytes ?

Posted: 14 Sep 2010 17:26
by Sparky1039
Here is the union method. No shifting or adding required.

Code: Select all

union U32_		// place this above "main" somewhere
  {
     unsigned long dblword;   // For accessing the whole 32-bit unsigned long
     unsigned char byte[4];  // For accessing all 32-bits as individual bytes
  };
  
...
...
  
void dispMyLong (unsigned char aad, unsigned char aac, unsigned char aab, unsigned char aaa)
{
union U32_ Bytes2long;  // create an instance of the declared union called 'Bytes2long' in this function
unsigned char txt [12];

   		// combine bytes
    Bytes2long.byte[3] = aad;  // high byte
    Bytes2long.byte[2] = aac;  // mid-high byte
    Bytes2long.byte[1] = aab;  // mid-low byte
    Bytes2long.byte[0] = aaa;  // low byte

	LongToStr ((Bytes2long.dblword / 4), txt);  //need to divide by 4, as the chip is incrementing in quarter-second
	Glcd_Write_Text(txt, 1,7,1) ;
}