• AVR Freaks

AnsweredDifference between capture and compare modes with examples

Page: < 12345.. > >> Showing page 5 of 13
Author
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/19 20:44:44 (permalink)
+1 (1)
1and0
...
Your if() case has a fault. It will not execute if the compare match occurs just before the CCP1IF=0 statement.

Is that still there?
I pointed out that problem back in post#58.
We shouldn't have to keep pointing out the same problems...
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#81
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/19 21:11:03 (permalink)
0
JorgeF
The manipulation of the CCP and TIMER values, as you are doing will kill any precision of the events generated by the CCP in compare mode.

 
When you clear the TIMER1 count, a number of instruction cycles has already passed since the last TIMER1-CCPR1 match.

Isn't this the actual work of the compare mode? The order of the instructions looks logical to me. And because when I comment the instruction of clearing the timer and code doesn't work so I don't know how to optimize it more.
 
Also turning On/Off the CCP module will add extra instruction cycles.
At first I thought that CCP module should pull the pin low again after the event trigger. The process of the capture mode is that on event trigger, whatever value of the timer should be copied to the CCPR1 register, on the next trigger I get another value and then do the subtraction then I get the timer between the two events.
 
But in the compare mode, it still not completely clear to me of how it works. But here's my understanding of the process:
1. Configure the CCP module to compare mode.
2. Load the value of the compare mode in CCPR1 register.
3. When turning on the timer, the timer starts counting, when it reaches the compare mode, the flag is set and the pin goes high accordingly.
4. Now, if I leave the timer to continue counting then it catches the next compare value after overflowing and the pin still high and I tried to pull it down again but didn't work for me. Also not clearing the timer stops the operation of the process.
5. So the solution as the members told me is to clear the timer and CCP1CON registers.
 
This is the best I could get.
 

For example, when the code reaches the CCP1CON = 0x08 a number off instruction cycles have already elapsed since the execution of the TMR1=0 statement.

But when I comment the "TMR1=0" the code doesn't work:
 
void compare(void)
{
    ADCON0=0x00;ADCON1=0x0f;CMCON=0x07; // disable ADC, comparators
    OSCCON=0x66; // internal oscillator 4MHz
    TRISC=0x00; // port settings most important CCP1 at port C as output
    INTCON=0x00; // compare settings & disable all interrupts
    T1CON=0x00; // TMR1 16-bits
    T3CON=0x00; // adjust TMR1 for capture/compare
    T1CONbits.TMR1ON=1; // turn on timer1
    CCPR1=0x0015;
   while (1)
   {
        CCP1CON=0x08;
        while(PIR1bits.CCP1IF==0); // wait for compare match
        PIR1bits.CCP1IF=0;
        CCP1CON=0x00;
        //TMR1=0; <------------------------------- Clearing TMR1 stops the function of the compare mode
   }
}

 
The result is that the "off" time on the CCP pin generated
 
Isn't that when I clear the CCP1CON?
 
the mode=0x08 will be less than the value in the CCPR registers.
 
Didn't understand this part. How "the mode=0x08 is less than the value in the CCPR registers."?
 
 
While the CCP module is Off (CCP1CON = 0) it releases the control of the output pin  to the digital output buffer (LATC) this results in a number of instruction cycles were the pin state (0/1) is independent of the CCP control.
This is what happens, but what is the problem in this situation?
 
 
 
 
Besides there is a bug in this code, if you want to wait for the CCP1IF flag you must use a "while" loop not an "if" statement.
 
Both versions of "if" and "while" works, but how to know which one is best? Although I'm applying the "while" version.
#82
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/19 21:18:43 (permalink)
0
1and0
Your if() case has a fault. It will not execute if the compare match occurs just before the CCP1IF=0 statement.

Is it better to put "CCP1IF=0" inside the "if" statement? But I get the same results on MPLAB logic analyzer, I don't know if it's the same in real world. But inside the "if" statement is absolutely better.
 
   while (1)
 
 
 
   { 
       CCP1CON=0x08;
       if(PIR1bits.CCP1IF==1) // wait for another compare input signal
       {
 
            PIR1bits.CCP1IF=0; 
            CCP1CON=0x00;TMR1=0;
            CCPR1=0x0015; 
       }
 
   }

post edited by eagle1 - 2018/07/19 21:24:42
#83
qɥb
Monolothic Member
  • Total Posts : 3332
  • Reward points : 0
  • Joined: 2017/09/09 05:07:30
  • Location: Jupiter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/19 21:28:36 (permalink) ☄ Helpfulby eagle1 2018/07/19 21:30:15
+2 (2)
eagle1
Is it better to put "CCP1IF=0" inside the "if" statement?

Yes.
Only clear it after you have seen it get set.
Right now you are randomly clearing it regularly, and as stated that can cause you to miss seeing it set.

Do you want a precise edge for the CCP output on both the rising edge AND the falling edge, using compare mode?
You can do this by alternating the CCPM mode value between:
0b1000 = Compare mode: initialize CCPx pin low; on compare match, force CCPx pin high (CCPxIF bit is set)

and
0b1001 = Compare mode: initialize CCPx pin high; on compare match, force CCPx pin low (CCPxIF bit is set)

You then never stop or clear the timer register.
You just add the number of timer clocks delays you need to the existing value in CCPR1,
and toggle bit 0 of the CCPM value in CCP1CON.
 
 

This forum is mis-configured so it only works correctly if you access it via https protocol.
The Microchip website links to it using http protocol. Will they ever catch on?
PicForum "it just works"
#84
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 00:14:53 (permalink)
0
qɥbRight now you are randomly clearing it regularly, and as stated that can cause you to miss seeing it set.
You mean even after the modification or the previous code configuration?
 
Do you want a precise edge for the CCP output on both the rising edge AND the falling edge, using compare mode? You can do this by alternating the CCPM mode value between:
OK, I did it and I got different results which is interesting. But also I can do the same with PWM mode, right? I think the PWM is more flexible than this method. Could compare mode with this strategy of toggling the trigger events be more precise than PWM?


You then never stop or clear the timer register.
You just add the number of timer clocks delays you need to the existing value in CCPR1,
and toggle bit 0 of the CCPM value in CCP1CON.


I tried to get the same period on high and low pulses but couldn't, I changed the CCPR1 value to "0x00ff" to get 256 cycles, I know I'm not near the wanted results but for now this is the best I could get.
 
This is the code:
 while (1)
{
CCPR1=0x00ff;
CCP1CON=0x08;
T1CONbits.TMR1ON=1; // turn on timer1
while(PIR1bits.CCP1IF==0); // wait for compare match
PIR1bits.CCP1IF=0;
CCP1CON=0x09;CCPR1=0x00ff;TMR1=0;
while(PIR1bits.CCP1IF==0); // wait for compare match
PIR1bits.CCP1IF=0;
TMR1=0;
}

Here I have to say I must clear "TMR1" in both routines otherwise the function won't work. 
 
 
These are the pulses diagrams:
 
 
post edited by eagle1 - 2018/07/20 00:16:51
#85
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 00:15:26 (permalink)
0

 

#86
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 02:47:02 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:24:17
+1 (1)
eagle1
I tried to get the same period on high and low pulses but couldn't, I changed the CCPR1 value to "0x00ff" to get 256 cycles, I know I'm not near the wanted results but for now this is the best I could get.

Try this:
CCPR1=0x00FF; // load compare value
CCP1CON=0x08;
T1CONbits.TMR1ON=1; // turn on timer1
while (1) {
    CCP1CON=0x08;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value

    CCP1CON=0x09;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value
}

 
#87
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 02:51:48 (permalink) ☄ Helpfulby eagle1 2018/07/20 21:41:00
+1 (1)
... or better yet:
TMR1 = 0;
CCPR1 = 0x0100; // load compare value
CCP1CON = 0x08; // compare mode
T1CONbits.TMR1ON = 1; // turn on timer1
while (1) {
    while (PIR1bits.CCP1IF == 0); // wait for compare match
    PIR1bits.CCP1IF = 0;
    CCPR1H++; // next compare value
    CCP1CONbits.CCP1M0 ^= 1; // toggle compare mode
}

post edited by 1and0 - 2018/07/20 03:31:14
#88
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:00:32 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:25:26
+1 (1)
Hi
 
The 20 instruction cycles added to the pulse width are probably the ones executed between detecting CCP1IF == 1 condition and the TMR1 = 0 statement.
Place a breakpoint just before the TMR1 = 0 statement and check the value of TMR1. I bet you will find a value of 18 or 19 there.
 

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
#89
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:04:43 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:26:05
+1 (1)
Do not clear TMR1 as Jorge said, instead move the compare value as shown in my code above.
 
Edit: I posted the code before reading Qub's Post #84 just now, so it should be as Qub said. ;)
post edited by 1and0 - 2018/07/20 03:48:58
#90
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:07:46 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:26:32
+1 (1)
Hi
1and0
Do not clear TMR1 as Jorge said, instead move the compare value as shown in my code above.

Where did I said that?
 
I add almost finished to write the same example code you posted, when I noticed you had already done it.
post edited by JorgeF - 2018/07/20 03:08:50

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
#91
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:10:07 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:26:51
+1 (1)
JorgeF
 
Where did I said that?

Hehe, I'm putting words in your mouth.  To get a precised output, don't modify the TMR1 value; otherwise, it will add cycles as you've pointed out.
#92
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:14:08 (permalink) ☄ Helpfulby eagle1 2018/07/20 11:27:15
+2 (2)
Hi
1and0
Hehe, I'm putting words in your mouth. 



Yeah I noticed that.
Don't worry, no hard feelings.
 
BTW my post #89 above, after your ocrrect examples, is to help the OP understand what is really going on when he looks at the output, and why.

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
#93
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 03:23:44 (permalink)
+1 (1)
JorgeF
 
Yeah I noticed that.
Don't worry, no hard feelings.

I just glanced over your post, and my mind made a bit of implied information. ;)
 

BTW my post #89 above, after your correct examples, is to help the OP understand what is really going on when he looks at the output, and why.

Let's hope he understood it now.
#94
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 13:53:53 (permalink)
0
1and0
 
Try this:
CCPR1=0x00FF; // load compare value
CCP1CON=0x08;
T1CONbits.TMR1ON=1; // turn on timer1
while (1) { 
    CCP1CON=0x08;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value

    CCP1CON=0x09;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value
}

 



You're brilliant man! I should learn a lot from this piece of code.
 
Let me try to break the order of your code:
1. You load CCPR1 register "CCPR1=0x00FF;"
2. Configure the CCP module to compare mode "CCP1CON=0x08;". But I have a question about this line, isn't in the beginning of the "while" loop another one? ---> I removed this line and the code works the same results, no change which is interesting, adding a line didn't affect the result but I think that because it's before turning on the timer.
3. Turn on the timer.
4. Start of the loop, you add another compare mode configuration. This one is of course important, so should the one before the loop a duplicated one? -----> Another interesting notice here, this one comes after turning on the timer, but the counting of the timer didn't get affected, still interesting.
5. Wait for the flag, then clear it.
6. Here comes the very interesting one "CCPR1H++;", this is really interesting.
  • I have no idea about manipulating the high register
  • Why the high register instead of the low register? And why even the CCPR1 has to be modified?
  • I thought this would accumulate the a lot of additions to the CCPR1 value. I would really like you to explain to me this part of optimization.
  • Also, when should I apply this method?
#95
eagle1
Super Member
  • Total Posts : 341
  • Reward points : 0
  • Joined: 2014/11/02 03:04:06
  • Location: Saudi Arabia
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 13:57:42 (permalink)
0
JorgeF
The 20 instruction cycles added to the pulse width are probably the ones executed between detecting CCP1IF == 1 condition and the TMR1 = 0 statement.
Place a breakpoint just before the TMR1 = 0 statement and check the value of TMR1. I bet you will find a value of 18 or 19 there.



You told me about missed counts in post #76.
 
On the first TMR1 clear it's 260 on the second it's 258! Hmmm I should think about this more thoroughly.
 

 
 
post edited by eagle1 - 2018/07/20 13:59:52
#96
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 14:14:11 (permalink) ☄ Helpfulby eagle1 2018/07/20 15:26:32
+1 (1)
First, my code in Post #88 is more efficient and results in 256 cycles for the first compare match too, by initializing TMR1=0 and CCPR1=256.
 
eagle1
6. Here comes the very interesting one "CCPR1H++;", this is really interesting.
  • I have no idea about manipulating the high register
  • Why the high register instead of the low register? And why even the CCPR1 has to be modified?
  • I thought this would accumulate the a lot of additions to the CCPR1 value. I would really like you to explain to me this part of optimization.
  • Also, when should I apply this method?

CCPR1 is consisting of two 8-bit registers CCPR1H and CCPR1L. Incrementing the high byte increases the 16-bit CCPR1 register by 256; that is, it is the same as
CCPR1 += 256;

but should be more efficient.  The compiler might be smart enough to generate the same code, or not.
post edited by 1and0 - 2018/07/20 14:18:59
#97
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 14:21:15 (permalink)
0
Hi
 
Its not my c ode but I think I can explain it.
eagle1
1and0
Try this:
CCPR1=0x00FF; // load compare value
CCP1CON=0x08;
T1CONbits.TMR1ON=1; // turn on timer1
while (1) { 
    CCP1CON=0x08;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value
    CCP1CON=0x09;
    while(PIR1bits.CCP1IF==0); // wait for compare match
    PIR1bits.CCP1IF=0;
    CCPR1H++; // next compare value
}


You're brilliant man! I should learn a lot from this piece of code.
 
Let me try to break the order of your code:
1. You load CCPR1 register "CCPR1=0x00FF;"

You did mention a count of 255 in one of your atempts, here it is.
eagle1 
2. Configure the CCP module to compare mode "CCP1CON=0x08;". But I have a question about this line, isn't in the beginning of the "while" loop another one? ---> I removed this line and the code works the same results, no change which is interesting, adding a line didn't affect the result but I think that because it's before turning on the timer.

The first line "CCP1CON = 0x08" sets the start mode, its necessary because the CCP must be configured before you start the Timer.
Inside the while(1) loop the mode alternates between 0x08 and 0x09 in order to generate a correct square wave, that is why upon program start you see a duplicate "CCP1CON = 0x08. If you look at the "while(1)" loop there are no duplicates. 
eagle1  
3. Turn on the timer.
4. Start of the loop, you add another compare mode configuration. This one is of course important, so should the one before the loop a duplicated one? -----> Another interesting notice here, this one comes after turning on the timer, but the counting of the timer didn't get affected, still interesting.

When CCP1CON == 0x08 a match event generates a raising edge of the output pin.
When CCP1CON == 0x09 a match generates a falling edge of the output pin.
Alternating the 2 modes your output will be a square wave of period = 2*CCPR count.
eagle1  
5. Wait for the flag, then clear it.
6. Here comes the very interesting one "CCPR1H++;", this is really interesting.
  • I have no idea about manipulating the high register
  • Why the high register instead of the low register? And why even the CCPR1 has to be modified?
  • I thought this would accumulate the a lot of additions to the CCPR1 value. I would really like you to explain to me this part of optimizations
  • Also, when should I apply this method?

What is intended is to generate a match event every 256 clocks.
In order to let the Timer run free so there are no lost clocks, we advance the match count to the next 256 interval.
This way we have match events at every 256 counts (256, 512, 768, .....) without interfering with the timer count.
 
The high byte (CCPR1H) its because 256 = 0x0100, so we skip adding 0x00 to the low byte and just add 0x01 to the high byte.
 
HIH
 
 

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
#98
JorgeF
Super Member
  • Total Posts : 3340
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 14:24:29 (permalink)
0
Hi
eagle1
 

 

Its because the Timer keeps counting after the match event.
 
EDIT ADD:
The value you find in this test will change from match event to march event, it depends on how many instructions the PIC executed since the when the match happens and when the code reaches the "if" statement that detecs it.
In this test were only 3 instruction cycles, because you are in a tigh loop (while).
On the other version with the "if" you found 20 instructions that was more or less the size of the loop.
 
post edited by JorgeF - 2018/07/20 14:37:16

Best regards
Jorge
 
I'm here http://picforum.ric323.com too!
And it works better....
#99
1and0
Access is Denied
  • Total Posts : 9525
  • Reward points : 0
  • Joined: 2007/05/06 12:03:20
  • Location: Harry's Gray Matter
  • Status: offline
Re: I want to know the difference between capture and compare modes with examples 2018/07/20 14:32:23 (permalink)
0
eagle1
On the first TMR1 clear it's 260 on the second it's 258! Hmmm I should think about this more thoroughly.

Take a look at the disassembly. As Jorge said, the timer keeps counting after the compare match. If the compare match occurs at the BTFSS PIR1,CCP1IF instruction it'll be 258. If the match occurs at the BRA instruction it'll be 260.
Page: < 12345.. > >> Showing page 5 of 13
Jump to:
© 2019 APG vNext Commercial Version 4.5