7
\$\begingroup\$

I am trying to use TMR1 to count TMR0 overflows. To do this I am using TMR1 with gate enabled, and using TMR0 overflow as the gate source.

Using MPLAB SIM, I can see that TMR0 is counting and overflowing. The TMROIF bit in INTCON is being set correctly.

TMR1 counts correctly without the gate enabled, and stops when I enable the gate control - so far so good.

However, TMR0 overflowing does not seem to be triggering the gate. The T1GVAL bit of T1GCON is never set.

I am running TMR1 at Fosc and I have the gate running not in toggle mode or single pulse mode... TMR0 is running at instruction clock / 256, although I presume that this doesn't matter...

Here are my config bits:

__CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_ON & _CP_OFF & _CPD_OFF & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF</code>
__CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _BORV_19 & _LVP_OFF

and here are the relevant lines where I configure TMR1

banksel T1CON
movlw   b'01000001' ; source = Fosc, prescale 1:1, LP osc - no, Timer on
movwf   T1CON

banksel T1GCON
movlw   b'11000001' ; gate enabled, active high, toggle no, pulse mode no, source TMR0
movwf   T1GCON
\$\endgroup\$
12
  • 3
    \$\begingroup\$ Step back and think of the real problem. You can count timer 0 overflows in software, which can then use any RAM bytes it wants as the counter. I don't see a reason that timer 1 needs to do the counting, especially since it is awkward. You are letting one implementation idea drive the design. It should be the other way around. What are you really trying to accomplish? \$\endgroup\$ Oct 6, 2012 at 23:09
  • \$\begingroup\$ Touché, Olin ;) Sage advice, and I have done this. I still want to know why it didn't work the way I was trying though... Perhaps I should rephrase my question... What is this feature for if not something like this? It still seems the more elegant solution... \$\endgroup\$
    – tsiflana
    Oct 7, 2012 at 16:32
  • \$\begingroup\$ What is what feature for? \$\endgroup\$ Oct 7, 2012 at 17:17
  • \$\begingroup\$ The ability to use Timer0 overflow as the Gate for Timer1... \$\endgroup\$
    – tsiflana
    Oct 8, 2012 at 8:01
  • 1
    \$\begingroup\$ The uses are only limited by your imagination. I don't know why the designers added it, but that doesn't matter anyway since it is here. The first thing I thought of was a frequency counter application. Timer 0 is used to open the gate of timer 1 for a known time. The counts accumulated on timer 1 during that time is then proportional to frequency. \$\endgroup\$ Oct 8, 2012 at 12:00

1 Answer 1

8
+50
\$\begingroup\$

I think your problem is based on confusion over exactly what the TMR1 Gate signal actually does. It does not, by itself, cause the timer to count, it merely enables it to count if there are suitable events occurring on its clock input.

It's subtle, but if you look at "FIGURE 21-1: TIMER1 BLOCK DIAGRAM" in the datasheet (p. 179), you'll see the TMR1H/TMR1L register in the middle. All of the logic above that is related to gating, and all of the logic below that is related to clocking. It all comes together at the flip-flop just to the right of the TMR1 register, where the gate signal drives the EN (enable) input of that flip-flop, and the clock signal drives the D (data) input.

What this means is that the output of the flip-flop will toggle (and cause TMR1 to increment) only if the gate signal is high and the clock signal is toggling.

There simply is no way to route overflow events from TMR0 to the clock logic of TMR1, either inside or outside the chip.

EDIT: OK, digging a little deeper (prompted by the comments below), I notice that you have the T1SYNC bit in the T1CON register set to zero. This causes the clock source to be synchronized to Fosc. If that clock source is in fact Fosc itself, the output of the synchronizer will be a constant level — always high or always low, but not toggling.

I believe this is the root cause of your problem. Try setting T1CON to b'01000101'. This should accomplish what you want, assuming that the overflow pulse from TMR0 is exactly one Fosc period long.

\$\endgroup\$
9
  • \$\begingroup\$ Right, I see what you mean and think it is right! I will however wait with the bounty until other people can have responded as well. \$\endgroup\$
    – user17592
    Jan 8, 2013 at 7:20
  • \$\begingroup\$ I don't see how this answers the question. The gate logic should get a pulse with the same duration as one TMR1 clock period (via a tacit pulse synchronizer) when TMR0 oveflows, and the clock logic gets a clock. It should count once at every overflow. So, why would it not work? Perhaps the simulator just fails at it (it is notoriously lacking when simulating peripherals). The OP never said he tried it in hardware. \$\endgroup\$ Jan 8, 2013 at 16:24
  • \$\begingroup\$ @apalopohapa: No, the clock logic does not get a clock. That's the missing piece here. \$\endgroup\$
    – Dave Tweed
    Jan 8, 2013 at 17:55
  • \$\begingroup\$ Ok, lets step back a little. The core of TMR1 is a counter. This counter always counts as long as it gets a clock... (continued on next comment) \$\endgroup\$ Jan 8, 2013 at 18:20
  • \$\begingroup\$ This clock is provided by a D flip-flop. This FF has three inputs: (1) Enable, (2) Data, and HAS to be clocked by the (3) system clock (otherwise the TMR1 would not work at all). Enable comes from the gate logic. D comes from the clock logic. An overflow pulse goes into the gate logic, and ends up at the Enable input. A clock, FOSC, routes via muxes into the D input. I see nothing that prevents FOSC (or any other selectable clock source) from reaching the D input, therefore making the counter count whenever Enable is asserted. \$\endgroup\$ Jan 8, 2013 at 18:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.