Attached is a flowchart that is created with Flowocde V6
Flowchart is not all my work so credit to Sean who use to work at Matrix.
The objective is to use CCP (Capture Compare & Pulse width modulation) function of a 16F1937.
This should also work for a majority of microcontrollers that have a 16bit timer 1 interrupt and CCP.
Eblocks used:
Eb006 v9 Programmer with J18&J19 set to A6&A7
Eb005 2x16 LCD connected to portD
EB070USB Test pod
Target device = 16F1937
Oscillator mode : Internal @ 32MHz
Pulse/ Frequency input connected to CCP1 (port C2)
Pulse / Frequency range = 7143ms/70Hz to 5uS/100000Hz
For an example, connected the USB Test Pod to port C and set frequency going to pin C2 at 50KHz:
The LCD displayed:
Accuracy was very good for the range stated above.
ICT was also displaying correct pulse duration of 10uS:
For any users not yet got Flowcode V6, you can down download a 30day trial From here
How CCP works to measure pulse with is:
when CCP interrupt is first triggered (by a positive edge going to port C2) then Timer1 is enabed (t1con = 0x01;) and timer1 is set for falling edge (ccp1con = 0x04; ).
When falling edge occurs, timer1 CCP interrupt service routine is again accessed, the values stored in ccpr1h & ccpr1l 8 bit CCP registers are converted in to 16bit unsigned integer that is supported by Flowcode6
The secret of converting to a pulse width is using the value from the CCP register and diving by 8 this works because with prescaler set to 1:1 each count in duration is 1/(32MHz/4) = 125nS then x 8 = 1uS = 8 time longer.
Therefore after the value of ccpr1h & ccpr1l registers are divided by 8 (ControlVal = PulseWidth >> 3 ) the result is directly in microseconds.
Hope this helps if trying to use CCP interrupt to measure pulse width or frequencies.
Martin
Pulse & Frequency meter using CCP FC6
-
- Matrix Staff
- Posts: 9521
- Joined: Sat May 05, 2007 2:27 pm
- Location: Northamptonshire, UK
- Has thanked: 2585 times
- Been thanked: 3815 times
Pulse & Frequency meter using CCP FC6
- Attachments
-
- Pulse & frequency Meter using CCP R1_v6.fcfx
- (9.7 KiB) Downloaded 1254 times
Martin
Re: Pulse & Frequency meter using CCP FC6
Hello everyone
I would like to put this program on a 18f87k22 , I would like to know what are the changes to be done on the block that controls the interrupt , I tried to make some changes but I can not make it work always shows 0Hz
thank you
I would like to put this program on a 18f87k22 , I would like to know what are the changes to be done on the block that controls the interrupt , I tried to make some changes but I can not make it work always shows 0Hz
thank you
Re: Pulse & Frequency meter using CCP FC6
Hi,
Looking to use this CCP method but in FC8, the sample FC does not compile correctly.
With the change of compiler in FC8 (I think) could that be a part ofthe issue?
the custom interupt sets register bits with a method i've not used before, is this still valid?
any ideas?
Looking to use this CCP method but in FC8, the sample FC does not compile correctly.
With the change of compiler in FC8 (I think) could that be a part ofthe issue?
the custom interupt sets register bits with a method i've not used before, is this still valid?
Code: Select all
ccp1con =0x05; //capture on rising edge of CCP1
pir1.CCP1IF = 0; // Clear pending CCP1 interrupts
pie1.CCP1IE = 1; // Enable CCP1 interrupts
intcon.PEIE = 1; // Enable peripheral interrupts
intcon.GIE = 1; // Enable global interrupts
Re: Pulse & Frequency meter using CCP FC6
So... I may have just found a different route to the same result and uses the same register values but this worked for me.
Changes in the CCP1 Interrupt component.
Enable Code
and handler code
then rewrote the C code boxes in the CCP1isr macro in capitals. Not sure if that is essential but it compiled OK after that.
I'm using it on a ECIO40P so just playing about with the scaler and offset values in 'Main' and stuff to output correct numbers.
Changes in the CCP1 Interrupt component.
Enable Code
Code: Select all
CCP1CON = 0x05; //capture on rising edge of CCP1
PIR1 = PIR1 & ~(1<<2); // Clear CCP1IF
PIE1 = PIE1 | 0x04; // Set CCP1IE
INTCON = INTCON | 0x40; //Enable peripheral interrupts
INTCON = INTCON | 0x80; // Enable global interrupts
and handler code
Code: Select all
if ((PIR1 >>2)&1)
{
FCM_%n(); // call selected macro
PIR1 = PIR1 & ~(1<<2); // Clear CCP1IF Flag
}
I'm using it on a ECIO40P so just playing about with the scaler and offset values in 'Main' and stuff to output correct numbers.