CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

making a 32bit CCP out of CCP4 for a tacho

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

making a 32bit CCP out of CCP4 for a tacho
PostPosted: Sun Jul 22, 2007 5:53 pm     Reply with quote

Hi,
Can anyone out there show me where I am going wrong with this. In the PIC sim it works perfect but on the bench, occasionally the MSB goes walkies and I just end up with an RPM based on the LSB. I need it to be 100% and at this stage am getting a bit frazzled. I did try some code from another post re a 24bit capture but it didn't pan out too well Crying or Very sad
timer is set up with a prescale of 1 and CCP4 is divide by 4,

#int_ccp4
void rpm_isr()
{
disable_interrupts(int_timer1);
if (!bit_test(PIR1,0))
{
rpmlsb = ccp_4;
rpmmsb = timer;
vrpm = make32 (rpmmsb, rpmlsb);
vrpm = (800000000/vrpm);
}
set_timer1(0);
timer=0;
bit_clear(PIR1,0);
enable_interrupts(int_timer1);
}

#INT_TIMER1
void msbrpm_isr() //one timer loop = 6.5ms
{
disable_interrupts(int_ccp4);
if(timer<65535)
{
timer++;
}
enable_interrupts(int_ccp4);
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 6:03 pm     Reply with quote

Post the PIC that you're using, and post your compiler version.
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

version and chip
PostPosted: Sun Jul 22, 2007 7:42 pm     Reply with quote

18F8722 and Version 3.249
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 9:38 pm     Reply with quote

The other code with the 24-bit timer extension should work. I don't want
to do it over again, so I'm just going to say use that code.
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 11:28 pm     Reply with quote

Oh well, I'll try it again, it was just that it was unsteady at higher frequencies,
Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Jul 22, 2007 11:48 pm     Reply with quote

What's the frequency of the input signal ?

Also, what voltage is your PIC running at ?
What are the high and low voltages of the input waveform ?
Is the input waveform a clean signal ? (no noise)
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 2:52 am     Reply with quote

I was running it today at 322hz and 150hz. Voltage is 5V. I'm running the input signal from a tti function generators TTL output at 50% duty and have also tried it from the 600ohm and 50ohm outputs at .3V to 4.5V squarewave. I scoped the crystal, 5V (at the processor), earth and input on our 4ch DSO and can see nothing untoward unfortunately. I cut down the code to run a bare minimum and still no joy. Can you see anything wrong with my code at all? I have a tell tail for max rpm and I set a breakpoint there in my code and had the simulator running for half the day and didn't hit it once, but obviously the bench is different. power is generated from a tti programmable power supply via some spike protection, a 78L05, decoupling caps by the reg and processor. Thanks for taking the time to help. I'm at home at present, but I'll load in you code again tomorrow morning and see if anything has changed as my code is slightly different to when I last tried it. Last time it was unsteady above 300hz but I had a divide by of 1, so it may have been due to interupt latency (just guessing though).
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 3:24 am     Reply with quote

What's the oscillator frequency of your PIC ?
Ttelmah
Guest







PostPosted: Mon Jul 23, 2007 4:24 am     Reply with quote

Some other comments though on what you were trying to do.
There is no point in the disable/enable interrupt lines. Unless you are using high priority interrupts, an interrupt can't interrupt another.
There is unecessary work, in the 'make32'. Just write the words into parts of the int32 - example below.
Big problem though, is the division in the interrupt handler. 32bit division, is slow. Even on a 40Mhz chip, a 32bit division, will take typically 106uSec. Now, having a division here, will imply that interrupts will be disabled in the external code in any similar division routine. I'd be suspicious that this is causing the problem...
Code:

union access {
   int32 lword;
   int16 parts[2];
} counter;
int1 update=false;

#int_ccp4
void rpm_isr(void) {
//surely, if the timer1 interrupt has occured, you just want to
//increment the MSB?.
   if (bit_test(PIR1,0))
      counter.parts[1]=timer+1;
   else
      counter.parts[1]=timer;

   counter.parts[0] = ccp_4;
   vrpm = counter.lword;
   update=true;
 
   set_timer1(0);
   timer=0;
   clear_interrupts(int_timer1);
   enable_interrupts(int_timer1);
}

Then in your main, if 'update' is true, perform the division to get your required number, and clear update.

Best Wishes
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 2:20 pm     Reply with quote

Thanks heaps for the feedback, I'll try that coding change this morning. I am running 10mhz + PLL, so 40mhz and I am using a high priority on CCP4
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 3:32 pm     Reply with quote

I was able to make the code in this post work with a 150 Hz input signal.
http://www.ccsinfo.com/forum/viewtopic.php?t=29963&start=3
I tested it with an 18F452 running at 40 MHz (10 MHz crystal in H4 mode).
To make it work, I had to make the following changes:

1. Change the Timer1 divisor to divide by 2:
Quote:
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2);


2. Change the numerator in the frequency equation to 5 MHz:
Quote:
frequency = (int16)(5000000L / current_ccp_delta);


Then I connected a function generator to pin C2 (CCP1 input pin) and
set it for a little below 150 Hz. Then I slowly adjusted the fine tuning
knob upwards in frequency. Here's the result, displayed in a terminal window:
Quote:

148 Hz
148 Hz
148 Hz
148 Hz
149 Hz
149 Hz
149 Hz
149 Hz
150 Hz
150 Hz
150 Hz
151 Hz
151 Hz
151 Hz
151 Hz

Note that the example code in the link uses CCP2 to create a test signal
for the tachometer (which takes its input from CCP1). I didn't use CCP2
in this test. I used an external B&K function generator to create the
150 Hz input signal for the tachometer.

The reason for changing the Timer1 pre-scaler is:
With a 40 MHz oscillator frequency, Timer1 runs at 10 MHz.
With a 150 Hz input signal, Timer1 will count up to:
Code:

10 MHz
------- = 66667 counts
150 Hz

This is greater than the maximum size of the 16-bit Timer1, which
can only count up to 65535.

The solution is to setup Timer1 to use a pre-scaler of 2. Then it will
only count up at a rate of 5 MHz. With a 150 Hz input, the count value is:
Code:

 5 MHz
------- = 33333 counts
150 Hz

This value is easily contained within the 16-bit Timer1. This also adds
a considerable amount of slack, so you can use an input signal that
is lower than 150 Hz by a fair amount without hitting any limits.

To implement this, you need to make the two changes shown at the
start of this post. You set the Timer1 pre-scaler to 2 and you change the
numerator in the frequency calculation to be 5 MHz (instead of 10 MHz).

This also shows why you had a problem. With a signal of roughly 150 Hz,
you're right in the vicinity of overflowing Timer1. That's probably why
things appeared to be flakey to you. But with the changes shown above,
it works very well.
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 4:16 pm     Reply with quote

thanks for your efforts. I need to measure from 16hz to 600hz. I have changed my code to the previously mentioned code above...

#int_ccp4
void rpm_isr(void) {
disable_interrupts(int_timer1);
if (bit_test(PIR1,0))
counter.parts[1]=timer+1;
else
counter.parts[1]=timer;

counter.parts[0] = ccp_4;
vrpm = counter.lword;
update=true;

set_timer1(0);
timer=0;
bit_clear(PIR1,0);
enable_interrupts(int_timer1);
}


#INT_TIMER1
void msbrpm_isr()
{
disable_interrupts(int_ccp4);
if(timer<65535)
{
timer++;
}
enable_interrupts(int_ccp4);
}

and again, on the simulator it is perfect, but on the bench it turns to custard, so essentially, just to save you any hassle as I am absolutely sure you have much better things to do Smile, in your opinion, is this a hardware thing or settings/software thing. If you can just please point me in the best direction, I'll go forward and hopefully sort it. With the above code it is steady everywhere but intermittently jumps to rediciously high revs e.g. 38373 presently with 385hz which is meant to and normally does display 7699rpm,

Thanks again for all your efforts

p.s. when is the dsPIC compiler going to be released
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 4:37 pm     Reply with quote

You keep changing your requirements. The new lower frequency of
16 Hz would require a 24-bit timer. I posted the changes to make that
work, later on in the thread that I linked to above. I'm out of time.
I can't afford to spend any more time on this thread.
Ray



Joined: 22 Jul 2007
Posts: 12
Location: Australia

View user's profile Send private message

PostPosted: Mon Jul 23, 2007 4:49 pm     Reply with quote

thanks Ttelmah for that code, I've put it in and after I sorted a little mistake on my part Confused it is working brilliantly, your a genius, thanks for that
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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