![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
Multiplication in CCS - v.4.093 |
Posted: Mon Aug 23, 2010 12:10 pm |
|
|
Hi all,
I was wondering what is the more accurate way to do a multiplication using CCS...
I am using a PIC18F4550.
I have a DC motor with a tachometer that gives me 3 logical ticks per revolution.
Thus, using an interrupt, i take a count every second, and want to display revolutions:
RPM = (count/3)*60.
(i am using an INT16 for RPM & count, so do i need to cast the other numbers into INT16's?)
Is using this equation adequate enough?
Thanks as always. |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: Multiplication in CCS - v.4.093 |
Posted: Mon Aug 23, 2010 12:21 pm |
|
|
deperkin wrote: | Hi all,
I was wondering what is the more accurate way to do a multiplication using CCS...
I am using a PIC18F4550.
I have a DC motor with a tachometer that gives me 3 logical ticks per revolution.
Thus, using an interrupt, i take a count every second, and want to display revolutions:
RPM = (count/3)*60.
(i am using an INT16 for RPM & count, so do i need to cast the other numbers into INT16's?)
Is using this equation adequate enough?
Thanks as always. |
Well, for one, why don't you simplify to just multiplying by 20 instead of the multiplication and division? Division takes much longer than multiplication.
Then, if you really, really need speed you could try to figure out a way to do it with shifts. 20 is a 16x and a 4x added together so you could do this:
Code: |
RPM = (count << 4) + (count << 2);
|
I don't believe you could do it a whole lot more efficiently than that. |
|
![](templates/subSilver/images/spacer.gif) |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
shifts |
Posted: Mon Aug 23, 2010 1:00 pm |
|
|
Thanks you,
that helps alot.
after my post I did change it to multiply by 20, but will try to shift instead, since I dont believe I am getting an accurate number displayed.
Thanks again. |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: shifts |
Posted: Mon Aug 23, 2010 1:14 pm |
|
|
deperkin wrote: | Thanks you,
that helps alot.
after my post I did change it to multiply by 20, but will try to shift instead, since I dont believe I am getting an accurate number displayed.
Thanks again. |
The two shifts + addition is basically the exact same as multiplying by 20 so if you didn't get an accurate number by multiplying by 20 then you still won't. |
|
![](templates/subSilver/images/spacer.gif) |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
interrupts |
Posted: Mon Aug 23, 2010 1:33 pm |
|
|
I am forced to use an external interrupt because of the other pins being used.
I have:
INT_EXT2
void EXT2_isr(){
disable_interrupts(INT_EXT2); //disable interrupt
cnt++; //recieved input from tachometer
ds1307_get_time(hr,min,sec);
if (sec == (s + 1)){ //modify filter time every second
s = seconds;
enable_interrupts(INT_EXT2);
RPM =(cnt << 4)+(cnt << 2); //muliply by 20 to get RPM
cnt = 0;
}
}
in the above, the ds1307_get_time provides me with the hours, minutes, and seconds from an external RTC... i know that this part works, since I have been using it consistently in another interrupt. (in main I initially set s = seconds)
So I check on every interrupt if one second has gone by, and onces it has, I take my count and multiply by 20.
I should be getting about 2500 rpm, but only get 120 rpm.
I can see on an oscilloscope however that my tachometer is working properly... I must not be getting the interrupts correctly however.
Best regards, |
|
![](templates/subSilver/images/spacer.gif) |
collink
Joined: 08 Jan 2010 Posts: 137 Location: Michigan
|
Re: interrupts |
Posted: Mon Aug 23, 2010 1:49 pm |
|
|
deperkin wrote: | I am forced to use an external interrupt because of the other pins being used.
I have:
INT_EXT2
void EXT2_isr(){
disable_interrupts(INT_EXT2); //disable interrupt
cnt++; //recieved input from tachometer
ds1307_get_time(hr,min,sec);
if (sec == (s + 1)){ //modify filter time every second
s = seconds;
enable_interrupts(INT_EXT2);
RPM =(cnt << 4)+(cnt << 2); //muliply by 20 to get RPM
cnt = 0;
}
}
in the above, the ds1307_get_time provides me with the hours, minutes, and seconds from an external RTC... i know that this part works, since I have been using it consistently in another interrupt. (in main I initially set s = seconds)
So I check on every interrupt if one second has gone by, and onces it has, I take my count and multiply by 20.
I should be getting about 2500 rpm, but only get 120 rpm.
I can see on an oscilloscope however that my tachometer is working properly... I must not be getting the interrupts correctly however.
Best regards, |
Under no circumstances should you be explicitly disabling and enabling interrupts in an interrupt handler. Comment out those lines. Or, better yet get rid of them and never speak of it again.
Also, if I were you I'd move the call to ds1307_get_time(hr,min,sec); out of the handler. Update some global variables for hr, min, sec. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19359
|
|
Posted: Mon Aug 23, 2010 3:29 pm |
|
|
Seriously, you have not got time to be reading the DS1307, inside the interrupt.
Forget this.
Use one of the PIC timers, to generate a 'tick'. Have this decrement a counter if the counter value is non zero (tick_counter)
Then set the value to the number of counts needed for one second (TICKS_PER_SECOND).
Your external interrupt code should be _short_ something like:
Code: |
int1 counts_updated=FALSE;
int16 counts_received=0;
INT_EXT2
void EXT2_isr(){
cnt++; //recieved input from tachometer
if (tick_counter==0) {
counts_updated=true;
counts_received=cnt;
cnt=0; //reset
tick_counter=TICKS_PER_SECOND; //reset the counter
}
}
//Then in your main
if (counts_updated) {
counts_updated=false;
RPM=counts_received*20;
}
|
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
deperkin
Joined: 04 Feb 2009 Posts: 83 Location: PA
|
many thanks |
Posted: Tue Aug 24, 2010 6:52 am |
|
|
Thank you!
This will be very helpful indeed. |
|
![](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
|