Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16f628 compare function 1 less than required.

Status
Not open for further replies.

dr pepper

Well-Known Member
Most Helpful Member
I'm using a pic16f628 as a frequency divider as part of a pll.
I want a division ratio of 99.
I have configured tmr1 to take pulses from rb6 and in synchronous mode (no choice in the latter).
The I have configured the ccp module to create a special event when theres a match between ccpr1 and tmr1, and causes tmr1 to reset and sets ccpr1if interrupt flag, my software at this point doesnt use interrupts it polls the ccpr1if bit (its not doing anything else and it runs at 20mc's so its not missing pulses).
To get a division ratio of 99 I have to load tmr1 with 98, in fact any ratio I want I have to subtract one from.
Maybe its too late at night for me to suss this, why is it happening?,
 
I think it is this, it's in the data sheet but even knowing it's in there took me a minute to find it

The special event trigger output of the CCP occurs immediately upon a match between TMR1H, TMR1L register pair and CCPR1H, CCPR1L register pair. The TMR1H, TMR1L register pair is not reset until the next rising edge of the TMR1 clock.

So you have an extra count like this (edit: Compare register is set to 5 in this example - not doing all 99 :)

TMR1 special event.jpg
 
Last edited:
To get a division ratio of 99 I have to load tmr1 with 98, in fact any ratio I want I have to subtract one from.

when you count from 0 to 98, there are 99 values you have to go through.
 
when you count from 0 to 98, there are 99 values you have to go through.

That's not correct in this case. The first rising edge counts 1, second counts 2.... so the special event trigger does trigger on the 99th rising edge if the compare register is set to 99. It's the fact the TMR1 register is not reset until the next (100th) rising edge.
 
That's not correct in this case. The first rising edge counts 1, second counts 2.... so the special event trigger does trigger on the 99th rising edge if the compare register is set to 99. It's the fact the TMR1 register is not reset until the next (100th) rising edge.

I believe that the counter is reset to zero on compare match.. not to one. So every cycle from 0 to 98 goes through 99 values.

I'm not sure the way you are thinking this. But, to me it is simple. The counter is zero based.

Same thing happens with C arrays. The last index of 99 element array is 98. This is because array indexing is zero based.

The datasheet quote only explains the accurate timing of the event in the counter cycle. This affects the phase of the event. Not the length of the event period.
 
Last edited:
Whenever a question like this comes up I like to think of extremes. Say you load the compare with one? The timer will count to one and will then reset on the next pulse. It will effectively count 0, 1, 0, 1 ..... As misterT said, to count from 0 to 1 goes through 2 numbers.

Mike.
 
Check the drawing in my first post.
TMR1 starts with a count of 0.
First rising edge clocks TMR1, counter = 1
Second rising edge clocks TMR1, counter = 2
Third rising edge clocks TMR1, counter = 3
and so on.....

As soon as the value in TMR1 counter matches the CCP register the special event is triggered. So if you had 99 in the CCP registers it would trigger at 99 clocks. If that also reset the TMR1 to zero, the divide ratio would be correct but it doesn't. The TMR1 isn't reset until the next rising edge so you have an extra clock
 
Check the drawing in my first post.
TMR1 starts with a count of 0.
First rising edge clocks TMR1, counter = 1
Second rising edge clocks TMR1, counter = 2
Third rising edge clocks TMR1, counter = 3
and so on.....

As soon as the value in TMR1 counter matches the CCP register the special event is triggered. So if you had 99 in the CCP registers it would trigger at 99 clocks. If that also reset the TMR1 to zero, the divide ratio would be correct but it doesn't. The TMR1 isn't reset until the next rising edge so you have an extra clock

After an event, the first rising edge resets the counter to zero. Second rising edge counter=1, third rising edge counter=2.. so on. You can call the zero "an extra count" if you like. What ever works best for your brain. I don't like to think that way.. doesn't work for me.
 
I concede, you're right, that is a better way of expressing it.

I'm thinking of it as an event counter rather than a divider and since the O/P is using it as a divider I've just confused the issue.
 
Thanks guys, I get that now.
Geko I think your way.
I assumed that the comparator special event reset o/p wasnt synced to the tmr1s clock and as soon as there was a match it resets the tmr1, it does at first state this in the data sheet, then it goes on to clarify that the reset occurs on the next clock, it seems I got caught up in microchip snafu.
 
Thanks guys, I get that now.
Geko I think your way.
I assumed that the comparator special event reset o/p wasnt synced to the tmr1s clock and as soon as there was a match it resets the tmr1, it does at first state this in the data sheet, then it goes on to clarify that the reset occurs on the next clock, it seems I got caught up in microchip snafu.

I don't mind that you think it differently, but if you really think about the details, the event must be fired the same time the counter changes to compare value. Imagine that a marathon is supposed to start at 2:00 pm.. it must make sense that you fire the start gun exactly when the clock changes from 1:59 to 2:00.

And I hope it is logical to you that the next counter value after the compare value is zero.

The counter cycle must also include the compare match value. It cannot reset to zero before that.. otherwise it would be impossible to do the comparison. Or the comparison would have to be made against zero, and that leads to all kinds of problems, because then you would have hard time distinguishing overflow event from compare event.
 
If I was to use a 4017 and divide by 3 then I'd connect the 2 o/p to the reset so the first 2 pulses would be 0 and 1, then the third would trigger a reset, seeing as the reset time for the chip is very low it can be ignored, every third pulse would be 0.
What the pic is doing is spending a whole clock pulse for the reset, going to 0 at the next clock pulse.
I can see this being important for the structure of the micro and clock timings for interrupts etc.
Maybe I still didnt get it.

Thankyou for understanding some of use see this different, I'm self taught on pics so I have all kinds of bad habits.
 
If I was to use a 4017 and divide by 3 then I'd connect the 2 o/p to the reset so the first 2 pulses would be 0 and 1, then the third would trigger a reset, seeing as the reset time for the chip is very low it can be ignored, every third pulse would be 0.

Of course the PIC could be designed to function that way also, but the logic design would be more complex, less flexible, and would not actually achieve any new functionality. And you would also lose one count from the full range (max. 255 counts instead of 256 on 8bit counter)

EDIT: In the above description you are comparing against 2 to divide by 3. That is exactly what you would do on a PIC. Did you mean that if you want to divide by 2, you would wire the 2 o/p to reset? That is how the clock prescalers work in PIC. (Well, not exactly, but the principle is the same. They actually just use the second counter bit as clock output when dividing by 2. This is why all prescaling options are powers of two.)
 
Last edited:
Seems I did get it.
I meant connect op2 (which would be count3 starting from 0) to reset to divide by 3.
Maybe you got mixed up with 2 being the third count from 0, hard work innit.

P.S I'd planned on using 2 pics as freq dividers, one for a 200kc input and another for a 10mc input, but it seems that the pic cant handle 10mc's on timer1, the code that works fine on 200kc gives sporadic o/p freq on 10mc's.
I thought you could clock timer 1 up to 50mc's, maybe thats with the prescaler diving it down before it gets to the timer.

Edit: sussed the above, to use the ccp1 module in compare mode you have to sync the timer1 to the incomming clock pulses, the pic's crystal is 20mc's so the instruction clock will be 5mc's, my external signal is 10mcs, so the external clock is higher than the instruction clock, the sync circuit is messing up because timer1's clock freq is too high, how do I get round this one then?
 
Last edited:
Seems I did get it.
I meant connect op2 (which would be count3 starting from 0) to reset to divide by 3.
Maybe you got mixed up with 2 being the third count from 0, hard work innit.

Oh, right.. the 4017 is a decade counter. I was thinking about a "regular" counter register. Should have checked the chip type.

P.S I'd planned on using 2 pics as freq dividers, one for a 200kc input and another for a 10mc input, but it seems that the pic cant handle 10mc's on timer1, the code that works fine on 200kc gives sporadic o/p freq on 10mc's.
I thought you could clock timer 1 up to 50mc's, maybe thats with the prescaler diving it down before it gets to the timer.

I rarely see those units.. does 200 kc mean "200 kilocyckles per second" which is 200 kHz. And 10mc = 10 MHz?
 
I have not used PICs very much, but I believe there are problems with synchronization when the counter input signal is very high.

Because the PICs max operating clock is 20 Mhz, this means that instructions are executed at 5 Mhz rate. I believe that interrupts must be synced to that clock. So synchronization to is one source of error.

Maybe you can setup the timer as PWM generator with external clock input. Then all you need to do is to adjust the pwm frequency and make sure the duty is as close to 50% as possible.. I'm not sure if this can be done, but this would eliminate the need for interrupts. The PWM module would just run automaticaly in the background.

I don't know if using PWM generator would eliminate the need for synchronization.. probably not, because there are still comparisons etc. that the peripheral needs to perform.

At least, whatever you do, make sure you have turned the synchronization off:
T1SYNC
1 = Do not synchronize external clock input


EDIT: Ok I found this line in the datasheet:

In Asynchronous Counter mode, Timer1
cannot be used as a time base for capture
or compare operations.

So, that is bad news for you.
 
Last edited:
I read the datasheet some more.. I think it is possible to use PWM mode with asynchronous clock input to the timer1.. I'm not sure. I let somebody with more experience with PICs to clarify that. But, if it is possible, then that would be what I'd use.
 
I think 10mc's, sorry mhz is alittle too high for the pic.
Yes you can run pwm out of sync.
However I have breadboarded a pair of 'hc390's to divide by 10,000, this does the trick I now have 1kc from 10mc, 2 chips instead of 1, but I think going to extremes with the pic isnt necessary, besides theres allready 1 pic in this project.

I did however sort out the initial problem, getting 1kc from 198kc, using a pic and tmr1 with the ccp module, this would have been an ache with discrete logic.
 
Now I'm little confused why you are dividing an external signal to achieve these frequencies. Can't you just use the PIC to generate these frequencies without the external clock. Or, if you need accurate frequencies than can be achieved with crystals, then clock the PIC itself from the 10 Mhz reference signal.

EDIT: Apparently I assumed that the input clocks are constant frequency. If they are variable frequency, then I understand what you are doing. It just sounds like they are constant frequency.. because of the way you talk about them.
 
Sorry yes I'd better tell you what I'm up to, I'm building a frequency standard.

I have built a simple receiver circuit to receive a lf radio carrier, this is amplified and squared and fed into the pic which divides it down to 1kc, a seperate 10mc xtal osc with a varactor as one of the loading caps is also divided down to 1kc, these 2 are then fed into a pll which generates a dc correction voltage which is applied to the varactor and locks the 10mc osc to the carrier.

I'm using the pic as a divider mainly because I want a pic to do other things in the project, and it saves 2 counter ic's and a logic gate ic doing so.
 
Status
Not open for further replies.

Latest threads

Back
Top