|
|
View previous topic :: View next topic |
Author |
Message |
edmundopt
Joined: 08 Dec 2011 Posts: 15 Location: Portugal
|
pic18f array 16bit index |
Posted: Tue Dec 13, 2011 7:33 am |
|
|
Hello again
first I wich to know if this method for measuring time is precise using simulation, I think it is, I'm measuring sum_eight() speed on a Pic18f4620 using CCS 4.124!
Code: |
void sum_eight()
{
// this is just some code using 8 vars
result = make16(tmpA[0],tmpA[1]);
result += make16(tmpA[2],tmpA[3]);
result -= make16(tmpA[4],tmpA[5]);
result += make16(tmpA[6],tmpA[7]);
}
|
definition of the two array
Code: |
unsigned int8 arr[3072];
unsigned int8 tmpA[8];
unsigned int16 result;
|
arr is filled with pattern from 0x00 to 0x06
I have a timer0 with interrupt enabled that increments a 8bit counter if it overflows, but no need to post code here..
testing the code :
Code: |
unsigned int16 p;
short cicleBool;
unsigned int16 tBefore;
unsigned int16 tAfter;
tBefore=get_rtcc();
p=0;
cicleBool=0;
while(!cicleBool)
{
memcpy(tmpA,&arr[p],8);
sum_eight_optimal();
p+=8;
if (p==3072) cicleBool=1;
}
tAfter=get_rtcc();
printf("\n\r t1 %lu, t2 %lu",tBefore,tAfter);
|
please NOTE that arr uses 16bit index 3072
I think there's a problem with this code, because results don't match, and I wish to measure wich is fastest!
the function:
Code: |
void sum_eight_p(unsigned int16 *aP)
{
result = make16(aP[0],aP[1]);
result += make16(aP[2],aP[3]);
result -= make16(aP[4],aP[5]);
result += make16(aP[6],aP[7]);
}
|
the main code:
Code: |
unsigned int16 *arrayPointer;
tBefore=get_rtcc();
p=0;
arrayPointer = &arr[0];
cicleBool=0;
while(!cicleBool)
{
sum_eight_p(arrayPointer);
arrayPointer+=8;
p+=8;
if (p==3072) cicleBool=1;
}
tAfter=get_rtcc();
printf("\n\r t1 %lu, t2 %lu",tBefore,tAfter);
|
can I use the 16bit pointer this way ?? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19546
|
|
Posted: Tue Dec 13, 2011 7:42 am |
|
|
A pointer is _always_ 16bit on a PIC18.
Saying that the pointer _points to_ an int16, implies that it increments by _two_ whenever you increment it, or add a value to it. So:
result = make16(aP[0],aP[1]);
Adds the byte pointed to by the pointer, to the byte _two_ addresses higher.
So, of course the values differ......
In fact with the pointer to an int16, all you need is:
Code: |
void sum_eight_p(unsigned int16 *aP)
{
result = aP[0]+aP[1]-aP{2]+aP[3];
}
|
Since the pointer is already deemed to point to an int16 value.
Best Wishes |
|
|
edmundopt
Joined: 08 Dec 2011 Posts: 15 Location: Portugal
|
|
Posted: Tue Dec 13, 2011 8:28 am |
|
|
so I've got it wrong, the array has a 16bit index, because 3072>255 but the definition of the pointer must be :
Code: |
unsigned int8 arr[3072];
(...)
unsigned int8 *arrayPointer;
|
I was declaring it as unsigned int16 *arrayPointer because of the index, but I realise now that it must be delcared of the same type that points to!
the correct code is :
Code: |
void sum_eight_p(unsigned int8 *aP)
{
result = make16(aP[0],aP[1]);
result += make16(aP[2],aP[3]);
result -= make16(aP[4],aP[5]);
result += make16(aP[6],aP[7]);
}
|
thanks, regards |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Tue Dec 13, 2011 9:06 am |
|
|
edmundopt wrote: | but I realise now that it must be delcared of the same type that points to! |
In C all pointers are addresses to (data) memory. Yes, you should normally declare them to the same type as the varables they point to... but they are just addresses. there is a special non-type for pointers: void *, i.e a pointer to nothing in particular, in other words a memory address. void * pointers have various uses and are often what functions like printf() and argv() use to point to their parameters, which may be of many different types, and malloc() and free() which are used to manage memory dynamically (rarely used on PICs thankfully...).
Why its important to declare your pointers to the "right" type is to do with pointer arithmetic which includes incrementing pointers, indexing from them, adding and subtracting them. This is because all such pointer arithmetic is done in the type of the pointer, so if you increment a int16 * (pointer to int16) then it will point to the next int16, i.e. 2 bytes on, int8 * to the next int8, only one byte on. You can point to whole structures this way, incrementing from one to the next in an array easily without having to worry how big the structures are in bytes. C pointers assume addresses are in bytes, which is generally the case on most processors today, but was not always so historically, and my not be with some speciallised DSP processors.
Also by declaring a pointer as pointing to a particular type you are making your code simpler and much easier to read. The only other useful option is void * but that should only be used where there is clear need for it; Network type applications, memory management and the like.
Remember, there are perhaps more bugs caused by pointers than anything else in C. Be very careful when using pointers!
RF Developer |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Tue Dec 13, 2011 11:07 am |
|
|
Terrific explanation RF_developer. |
|
|
|
|
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
|