mikromedia for PIC24EP on discount
It is currently 30 Sep 2014 23:11

All times are UTC + 1 hour




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: 13 Sep 2010 09:34 
Offline

Joined: 12 Feb 2010 12:31
Posts: 39
How can I concatenate 4 bytes ?

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

Thanks


Top
 Profile  
 
PostPosted: 13 Sep 2010 17:23 
Offline

Joined: 24 Nov 2005 20:07
Posts: 892
Location: Colorado, USA
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


Top
 Profile  
 
PostPosted: 14 Sep 2010 12:24 
Offline

Joined: 12 Feb 2010 12:31
Posts: 39
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.


Top
 Profile  
 
PostPosted: 14 Sep 2010 12:48 
Offline

Joined: 11 Mar 2005 18:26
Posts: 1065
Location: Aubenas, France
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


Top
 Profile  
 
PostPosted: 14 Sep 2010 13:08 
Offline

Joined: 07 Mar 2007 14:36
Posts: 271
try this way


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..

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



or
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


Top
 Profile  
 
PostPosted: 14 Sep 2010 16:27 
Offline

Joined: 18 Jun 2008 11:43
Posts: 3286
Location: Nieuwpoort, Belgium
jumper wrote:
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:
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.
(happy user of mP PRO for PIC and dsPIC30/33 and PIC24, PicFlash2, RTClock, Max232 board, Ethernet PROTO board, MMC/SD Card Proto board, Yo2Lio's and Janni's libs)
http://www.rosseeld.be/DRO/PIC/index.htm


Top
 Profile  
 
PostPosted: 14 Sep 2010 16:31 
Offline

Joined: 12 Feb 2010 12:31
Posts: 39
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:
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:
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.


Top
 Profile  
 
PostPosted: 14 Sep 2010 16:55 
Offline

Joined: 07 Mar 2007 14:36
Posts: 271

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.


Top
 Profile  
 
PostPosted: 14 Sep 2010 17:19 
Offline

Joined: 07 Mar 2007 14:36
Posts: 271
Regarding your concern about the 1 sec per minute lost.. well look at the datasheet. Doesn't it say
Quote:
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.

Top
 Profile  
 
PostPosted: 14 Sep 2010 17:26 
Offline

Joined: 24 Nov 2005 20:07
Posts: 892
Location: Colorado, USA
Here is the union method. No shifting or adding required.
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) ;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: Exabot [Bot] and 6 guests


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 post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group