PDA

View Full Version : Using CCP1 and CCP2 in capture mode with Timer1.



Ceetee
- 12th December 2010, 16:30
Greetings to everybody

I have a question regarding the use of the CCP modules on a 16F876.

Currently I am using CCP1 with Timer1 to measure the length of a pulse (rising edge) in the main part of my program and all is fine. What I would now like to be able to do, as a precursor to the main part of the program running, is to measure two different pulses one via CCP1 followed by the second via CCP2. This second pulse is of a different frequency and from another source.

I set up these variables first.


capture VAR PIR1.2 ' CCP1 capture flag
capture2 VAR PIR2.0 ' CCP2 capture flag
overflow VAR PIR1.0 ' Timer1 overflow flag
period var Word ' Pulse 1 Rising edge trigger
period2 var word ' Pulse 2 Rising edge trigger

followed by these constants.


Constants
CCP1CON = %00000101 'Enable the CCP1 capture, every rising edge.
CCP2CON = %00000101 'Enable CCP2 for every capture.


I then call a Gosub routine that loops a number of times (not shown here) and outputs each result to the serial port for use within a pc program.


gratio:
T1CON = %00010000 ' TMR1 prescale=1:4 Timer OFF _ %00010000 1:2
TMR1H = 0 ' Zero the Timer High
TMR1L = 0 ' Zero the Timer Low
capture = 0
capture2 = 0

StartLoop1:
IF (capture = 0) Then StartLoop1 ' Wait here for the first capture
T1CON.0 = 1 ' Start the Timer
capture = 0 ' Reset the capture flag
CaptureLoop1:
IF (capture = 0) Then CaptureLoop1 ' Wait here until captured
period.lowbyte = CCPR1L ' Store the captured value in
period.highbyte = CCPR1H ' period variable

GOSUB ClearTimer

StartLoop2:
IF (capture2 = 0) Then StartLoop2 ' Wait here for the first capture
T1CON.0 = 1 ' Start the Timer
capture2 = 0 ' Reset the capture flag
CaptureLoop2:
IF (capture2 = 0) Then CaptureLoop2 ' Wait here until captured
period2.lowbyte = CCPR2L ' Store the captured value in
period2.highbyte = CCPR2H ' period variable

GOSUB ClearTimer
Hserout [#period," ",#period2,13,10] 'Send result to serial port
RETURN

ClearTimer:
ClearTimer1:
IF (capture = 0) Then cleartimer1 ' Wait for beginning of next period
TMR1L = 0 ' Clear Timer1 low register
TMR1H = 0 ' Clear Timer1 high register
capture = 0 ' Clear capture flag
capture2 = 0 ' Clear capture flag
overflow = 0 ' Clear overflow flag
Return

What I have found is that the capture result is initially correct but the capture2 result is approximately capture+capture2. All further results after the initial loop are incorrect, it is as if the timer is not resetting correctly.

What am I doing wrong?.

I suspect that I have missed something simple, unfortunately I have no idea what it is !.

Any suggestions are welcomed.

Bruce
- 12th December 2010, 18:41
You would probably get better results if you enable 1 capture at a time, stop timer1 before clearing it & entering CaptureLoop2.

Are you trying to measure the period or high-going pulse width?

Ceetee
- 12th December 2010, 23:03
Hi thanks for your reply

I am measuring the period of the incoming pulses.

I have to say I had not considered enabling one CCP at a time. Would I acheive this changing the CCPxCON statement? (x being 1 or 2). Such as CCP1CON = %00000000.

Thanks.

Bruce
- 13th December 2010, 13:06
Would I acheive this changing the CCPxCON statement?
Yes. Enable 1. Wait for capture. Disable 1, Enable 2, wait for capture, etc. It's a good idea to stop Timer1 before clearing it also.

Ceetee
- 13th December 2010, 18:42
Many thanks Bruce for your advice.

I have done as you have suggested, including stopping Timer1 (T1CON = 0) before clearing, and all appears to be operating as it should. I am a happy chappie.....

Once again many thanks. Sorted.....

Chris. :)