![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
leandroguida
Joined: 09 Dec 2008 Posts: 4
|
Math problems |
Posted: Tue Dec 09, 2008 10:00 pm |
|
|
Hello there.
I'm doing a test code to calculate a period of time. Since I'm using a 4MHz crystal, my internal clock is 1Mhz giving me 1uS per cycle.
So here's my idea, if I can count the total cycles, I can get how many uS the process took.
So for this, I created the code below:
Code: | #include <16f877a.h>
#include <stdio.h>
#use delay(clock=4000000)
#fuses HS, NOWDT, NOPROTECT, NOLVP
#use rs232(baud=9600, BITS=8, PARITY=N, STOP=1,x mit=PIN_C6, rcv=PIN_C7)
unsigned int16 tCcp = 0, tCcpAtual = 0;
unsigned int over = 0;
unsigned int32 tTotal, test;
volatile unsigned boolean ccpFlag = false;
#int_ccp1
void ccpH(){
tCcp = CCP_1;
ccpFlag = true;
}
#int_timer1
void timerHandler(){
over++;
}
void main(){
setup_ccp1(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
enable_interrupts(INT_CCP1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(true){
if(ccpFlag){
setup_ccp1(CCP_OFF);
setup_timer_1(T1_DISABLED);
tCcpAtual = tCcp;
test = (over*65535);
tTotal = test+tCcpAtual;
printf("Tempo Captura: \%ld\n\r",tTotal);
ccpFlag = false;
}
delay_us(100);
}
} |
I'm using the PIC16F877A. I'm thinking like that: Since my timer is a 16bit one, when I have a overflow interrupt I'll have counted 65535 uS.
So I increment a 'over' variable to count how many overflow interrupts I had.
Then I get the CCP_1 which is the timer value when the CCP_1 event occurred.
My Total time would be:
Code: | tTotal = (over*65535)+tCcpAtual; |
Where tCcpAtual, as showed in the code, is the CCP_1.
I can't get the right 'over' total overflow time. When I use a normal number, it works. (Like, if I do 10*65535 I'll have 655350). But using the variable 'over', don't work.
What is the problem, is it my variable type ? Is the math instructions wrong?
serial exit is just as a feedback for me. |
|
![](templates/subSilver/images/spacer.gif) |
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Dec 10, 2008 1:10 am |
|
|
The product of two int16 numbers is also int16. over*65535 is calculated as an int16 quantity, discarding the overflowing bits and then assigned to the int32 variable.
I think, that the multiply should be with 0x10000 or 65536 anyway, which reduces the multiply to a shift respectively assignment to high word, achievable e. g. by make32() CCS private function.
Using general C-syntax, a type cast would be the means to clarify your intentions, e. g. (int32)over*65535. |
|
![](templates/subSilver/images/spacer.gif) |
leandroguida
Joined: 09 Dec 2008 Posts: 4
|
Thanks... |
Posted: Wed Dec 10, 2008 5:15 am |
|
|
Thanks a lot. It worked! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Dec 10, 2008 9:24 am |
|
|
As a comment, FvM, is 'dead right', that you would handle this more correctly, and much quicker, using shifts, or make32.
One 'route', that is 'non obvious', if you are not used to C unions, and is very efficient indeed, is to use a union for this. So something like:
Code: |
struct words {
low_word;
high_word;
}
union {
struct words w;
int32 whole;
} timer32;
|
Then in your overflow routine, just increment timer32.w.high_word. Copy your tCcp value into timer32.w.low_word, and the required result should be in timer32.whole.
No arithmetic involved.
Very much faster, and more compact.
Best Wishes |
|
![](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
|