![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
leto
Joined: 02 Aug 2005 Posts: 14
|
Int32 problem |
Posted: Tue Aug 09, 2005 7:04 pm |
|
|
Hi,
I think I have a conversion problem. I just want to fill a int32 array named "test" with external eeprom data. When it dont get me the correct values I tried with a flat variable "tmp" and it was worse.
why if test[i] = tmp it print diferent values ?
Im using a PIC18F452.
Thanks.
Code: |
void LoadReg()
{
long addr;
Int32 tmp;
Int32 test[6];
addr=6;
for (i=0; i <6 i++) {
tmp = read_int32_ext_eeprom(addr);
test[i] = tmp;
addr+=4;
printf("test[%d]=%lu tmp=%lu\n\r", i, test[i], tmp);
}
}
test[0]=570556930 tmp=33686018
test[1]=33561090 tmp=33686018
test[2]=69345794 tmp=33686786
test[3]=488768771 tmp=33686019
test[4]=7873026 tmp=33686018
test[5]=2 tmp=572654082
|
|
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Tue Aug 09, 2005 9:44 pm |
|
|
I just ran a modified version version of your code on a 18F452.
Here is the meat of what I wrote:
Code: |
/*** Functions***/
int32 read_int32_eeprom(int8 address) {
int8 i;
int32 data;
for(i = 0; i < 4; ++i) {
*(&data + i) = read_eeprom(address + i);
}
return data;
}
/*** Main ***/
long int i;
int8 addr;
Int32 tmp;
Int32 test[6];
addr=6;
for (i=0; i <6 ;i++) {
tmp = read_int32_eeprom(addr);
test[i] = tmp;
addr+=4;
printf("test[%lu]=%lu tmp=%lu\n\r", i, test[i], tmp);
}
|
My output was what was expected for reading un-initialized internal EEPROM. I would suspect there is a comm issue with your external EEPROM. If you post your full code one of the experts will probably be able to find the problem. Also, when you post code, cut and paste the code so no typos find there way into the post.
Good Luck,
John |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Tue Aug 09, 2005 10:50 pm |
|
|
the code has 950 lines, anyway here I send you a smaller one.
The problem are two.
1) test[i] = tmp. The compiler can't make a correct casting to int32.
the same occurs doing test[i]=read_int32_ext_eeprom(addr);
2) variable tmp is overlapped with test[0];
thank you
leto
Code: |
#include <18F452.h>
#device *=16
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP, NOCPD
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,stream=PC)
#define EEPROM_SDA PIN_C4
#define EEPROM_SCL PIN_C3
#include<24256.c> // it has #use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL,FORCE_HW,fast)
#include <external_eeprom.c>
void main()
{
long addr;
int8 i;
int32 tmp;
int32 test[6];
addr=6;
for (i=0; i < 6 ; i++) {
tmp = read_int32_ext_eeprom(addr);
test[i] = tmp; // <- here something wrong
printf("test[%d]=%lu tmp=%lu\n\r", i, test[i], tmp);
addr+=4;
}
}
|
[/code] |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Aug 10, 2005 6:59 am |
|
|
Are you sure it is not just your output that it wrong?. You are trying to output 'test[i]', which is a long integer, using %d, which only handles shorts. You will see just the low byte of the value...
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed Aug 10, 2005 7:39 am |
|
|
Hi Ttelmah,
No, I use %d to print the index "i" but %lu to print int32 variable.
I think is a compiler bug. may be i am wrong. look at this:
the problem is with 18f452. I tried the same code with 16f877 and it works fine.
for example:
Code: |
main()
{
int32 test[1];
int i;
i=0;
test[i] = 222222; // using index work wrong with 18f452
// test[0]; // it works fine
printf("test %lu", test[i]);
result: 0
}
|
Thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Aug 10, 2005 7:45 am |
|
|
Look at the register locations using the simulator in MPLAB |
|
![](templates/subSilver/images/spacer.gif) |
MikeValencia
Joined: 04 Aug 2004 Posts: 238 Location: Chicago
|
|
Posted: Wed Aug 10, 2005 7:46 am |
|
|
Ttelmah wrote: | Are you sure it is not just your output that it wrong?. You are trying to output 'test[i]', which is a long integer, using %d, which only handles shorts. You will see just the low byte of the value...
Best Wishes |
I was looking at the original post late last night, and still can't figure out, by inspection alone, why it wouldn't work. Notice that his %d is only printing the index into the array, while he uses %lu for the two int32 values.
As for your first post about the output of the eeprom reading being wrong, I still can't see why test[i] = tmp does not reflect the same values when immediately doing a printf ![Question](images/smiles/icon_question.gif) |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Aug 10, 2005 7:54 am |
|
|
You will notice that I did not use the %d format for the index of the array. My code would not compile until I changed it to the %lu format.
Some suggestions for your next steps in trouble-shooting:
1. Make a skeleton program with just the features you're trying to debug. I would try reading from the internal EEPROM first, before trying external. Use my function and printf statement.
Note: Ttelmah could probably correct me if I'm wrong, but I don't think there is any typecasting happening in the line where you think the problem is. Both of those values/variables are already int32.
2. See item #4 in the following post and provide all the info requested.
http://www.ccsinfo.com/forum/viewtopic.php?t=17013
The experts can usually recognize common problems from earlier compiler versions, etc. (I'm wondering how your code compiled with the %d format in the printf statement and mine would not?)
3. Try not to get fixated on one item that you have convinced yourself is the problem.
4. When you do find the problem and correct it, post any information back here so anybody else that encounters the same problem will have the solution.
Good Luck,
John |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Aug 10, 2005 8:43 am |
|
|
jecottrell wrote: | You will notice that I did not use the %d format for the index of the array. My code would not compile until I changed it to the %lu format.
Some suggestions for your next steps in trouble-shooting:
1. Make a skeleton program with just the features you're trying to debug. I would try reading from the internal EEPROM first, before trying external. Use my function and printf statement.
Note: Ttelmah could probably correct me if I'm wrong, but I don't think there is any typecasting happening in the line where you think the problem is. Both of those values/variables are already int32.
2. See item #4 in the following post and provide all the info requested.
http://www.ccsinfo.com/forum/viewtopic.php?t=17013
The experts can usually recognize common problems from earlier compiler versions, etc. (I'm wondering how your code compiled with the %d format in the printf statement and mine would not?)
3. Try not to get fixated on one item that you have convinced yourself is the problem.
4. When you do find the problem and correct it, post any information back here so anybody else that encounters the same problem will have the solution.
Good Luck,
John |
You are dead right, there is no typecasting in the line shown.
Sorry about thinking the 'L' was missing, I glanced along the line, and missed that the index was also being sent. However %ld, is still wrong, it should be %lu, since int32, defaults to unsigned.
The actual problem is in the read_int32_eeprom function. Adding '1' to a pointer to an int32, points to the _next_ int32, not to the next byte. This is standard C.
What should be done is:
Code: |
/*** Functions***/
int32 read_int32_eeprom(int8 address) {
int8 i;
int32 data;
int8 * addr;
addr=&data;
for(i = 0; i < 4; ++i) {
*(&addr + i) = read_eeprom(address + i);
}
return data;
}
|
This generates a pointer to an int8, which will then increment as expected.
However I'd probably do it instead as:
Code: |
/*** Functions***/
int32 read_int32_eeprom(int8 address) {
int8 i;
union {
int32 data;
int8 b[4];
} temp;
for(i = 0; i < 4; ) {
temp.b[i++] = read_eeprom(address++);
}
return temp.data;
}
|
Which is 'tidier' code, and saves a few bytes (such as incrementing address, rather than performing a two byte addition every time round).
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
jecottrell
Joined: 16 Jan 2005 Posts: 559 Location: Tucson, AZ
|
|
Posted: Wed Aug 10, 2005 9:16 am |
|
|
Ahhhhhh, this is getting good.
First, I have to admit to some very wrong testing I did. I only read from the internal EEPROM to test my theory. Because the internal EEPROM defaults to 0xFF after each reprogram I wouldn't catch any "overlapping" reads......bad, bad, bad, bad.
In the future I promise to always write a known value prior to reading to validate any code.
Big Question:
I modified the external_eeprom.c function to read the internal EEPROM. Is the function contained therein, and the function that is in question here inherently wrong? Or is there just a difference in the way the internal and external EEPROM locations are accessed?
Thanks,
John |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed Aug 10, 2005 9:20 am |
|
|
Im using read_int32_ext_eeprom function located in CCS\drivers directory and Im sure that is work fine, but just when you use a flat int32 variable not an indexed array.
e.g
Code: |
int32 tmp;
tmp=read_int32_ext_eeprom(addr);
|
tmp get the correct value.
however if you assign the result to an array, it works wrong.
Code: |
e.g
int32 tmp[2];
int i;
i=0;
tmp[i] = read_int32_ext_eeprom(addr);
printf( "tmp array is=%lu", tmp[i]);
it works wrong.
|
the same occurs without call to read_int32_ext_eeprom. Just try to do:
Code: |
int32 tmp[2];
int32 flat;
flat=70000;
i=0;
tmp[i] = tmp;
|
it works wrong;
if you use direct indexing it works ok.
Code: |
int32 tmp[2];
int32 flat;
flat=70000;
tmp[0] = tmp;
|
|
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed Aug 10, 2005 9:24 am |
|
|
But remember just with 18F452. 16F877 works fine.
thanks. |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed Aug 10, 2005 10:53 am |
|
|
I did a debug with MPLAB and it doesnt work. I hope you can help me.
just work with flat int32 variable.
thank you. |
|
![](templates/subSilver/images/spacer.gif) |
JPA Guest
|
|
Posted: Wed Aug 10, 2005 11:34 am |
|
|
Reading your discussion, I remember a problem I had with structure assignment.
When doing direct assignement: m = old_m, I had no problem.
When working with pointers or array, tab[i] = m or *(tab+i) = m or ... the assignement was not correct.
As a wraparound, I used the memcopy function and then had no more problem. |
|
![](templates/subSilver/images/spacer.gif) |
Guest
|
|
Posted: Wed Aug 10, 2005 1:27 pm |
|
|
thanks for your comment JPA.
I tried with:
Code: |
int i;
int32 tmp;
int32 test[6];
for (i=0;i<6;i++) {
tmp=read_int32_ext_eeprom( addr );
memcpy (&test[i], &tmp, 4);
}
|
It is working well. So, I suppose that direct assignment to int32 or int16 array doesn't work correctly.
Thank you. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|