How can I concatenate 4 bytes ?

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
Olivia
Posts: 39
Joined: 12 Feb 2010 12:31

How can I concatenate 4 bytes ?

#1 Post by Olivia » 13 Sep 2010 09:34

How can I concatenate 4 bytes ?

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

Thanks

Sparky1039
Posts: 1179
Joined: 24 Nov 2005 20:07
Location: Colorado, USA

Re: How can I concatenate 4 bytes ?

#2 Post by Sparky1039 » 13 Sep 2010 17:23

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

Olivia
Posts: 39
Joined: 12 Feb 2010 12:31

Re: How can I concatenate 4 bytes ?

#3 Post by Olivia » 14 Sep 2010 12:24

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.

Kalain
Posts: 1093
Joined: 11 Mar 2005 18:26
Location: Aubenas, France

Re: How can I concatenate 4 bytes ?

#4 Post by Kalain » 14 Sep 2010 12:48

Hi,

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

jumper
Posts: 466
Joined: 07 Mar 2007 14:36

Re: How can I concatenate 4 bytes ?

#5 Post by jumper » 14 Sep 2010 13:08

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

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: How can I concatenate 4 bytes ?

#6 Post by Dany » 14 Sep 2010 16:27

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).
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

Olivia
Posts: 39
Joined: 12 Feb 2010 12:31

Re: How can I concatenate 4 bytes ?

#7 Post by Olivia » 14 Sep 2010 16:31

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.

jumper
Posts: 466
Joined: 07 Mar 2007 14:36

Re: How can I concatenate 4 bytes ?

#8 Post by jumper » 14 Sep 2010 16:55

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.

jumper
Posts: 466
Joined: 07 Mar 2007 14:36

Re: How can I concatenate 4 bytes ?

#9 Post by jumper » 14 Sep 2010 17:19

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...
Last edited by jumper on 14 Sep 2010 17:29, edited 1 time in total.

Sparky1039
Posts: 1179
Joined: 24 Nov 2005 20:07
Location: Colorado, USA

Re: How can I concatenate 4 bytes ?

#10 Post by Sparky1039 » 14 Sep 2010 17:26

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) ;
}

Post Reply

Return to “mikroC PRO for PIC General”