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.

How do you synchronize TMRO as counter?

Status
Not open for further replies.

jpanhalt

Well-Known Member
Most Helpful Member
MCU= Microchip mid-or enhanced midrange (e.g., 16F1829 or 16F690)
Language = MPASM

The datasheets recommend "synchronizing" the TMR0 counter to the chip oscillator when in counter mode.

upload_2017-8-19_18-30-8.png


Up to now, I have ignored doing that. A Google search on the procedure yielded non-helpful datasheets, such as DS51682A (not worth looking at). Basically, how do you sample anything at less than a full Tcy? How do you do the synchronization, other than accounting for the two instruction lag?

John
 
I'm not sure exactly what your question is but I have a vague recollection of a procedure to work out what the 2 LSBs were (past tense) of timer0. It was something like switching the prescaller incremented the 2 LSB and you could work out what they were from how many times you had to switch it before timer0 incremented. I've googled it but can't find anything.

Mike.
 
Let me try to clarify.

Background:
I am using TMR0 as a frequency counter to tune the antenna of the AS3935 lightning detector. Basically, the AS3935 outputs the actual antenna resonance frequency as a frequency, not as a digital value, on its interrupt pin. I am using RA2 as the INT pin for most normal operations. As that pin can also be T0CKI, it is convenient to use for measuring the frequency (500 kHz) with TMR1 to actually time the rollover period.

My confusion:
In the past, I just ignored that and have usually used TMR1 for counting, capture, and compare. What caught my eye was the imperative just before the highlighted comment. It seems the user has to do the synchronization, so I searched on that and came up empty. Moreover, my recollection of the Fosc versus instruction cycle was this:
upload_2017-8-20_4-36-41.png


I didn't have a clue about how to "sample the prescaler" at Q2 and Q4 and do anything about it, if I could.

Pommie,
I think you may be referring to a procedure for TMR1 when using Fosc rather than Fosc/4 for its clock. I have actually never tried to use Fosc as the clock as there are so many warnings about doing that, nor have I needed that resolution. For reference, it is in section 21.2.1 (p.178) of the 16F1829 datasheet.

Ian Rogers,
Your post came up while I was working on the above (I write very slowly). Definitely looks interesting and I will review it after breakfast and feeding my dog (Charlie).

John
 
Again thanks for the information. After review, it appears the Ohio.edu lecture describes the "problem," but doesn't say what the user can do to effect synchronization.

upload_2017-8-20_5-36-8.png


I have a feeling most users just ignore that imperative in the datasheet to do something about it. And, so will I. My current plan is to count about 1000 cycles (2 ms), which makes the math easier. Target for the AS3935 is 500 kHz ±3.5% , so being off by a few ticks of the clock won't make a difference (MCU = 32 MHz with 8 MHz ceramic resonator for accuracy and 4xPLL). Tuning of the AS3935 is done by adding or subtracting fixed capacitors (a few pF each) with software, which limits how close to the target one can actually get.

John
 
That section, in a rather poor way, describes why the signal you're counting must adhere to timing parameters 40, 41, and 42 in the timing specs.
 
Thanks Mike,
I suspect this is the right table:
upload_2017-8-20_6-54-40.png


I don't know the exact pulse width put out by the AS3935, but will take a look once I access that mode of the chip. Since the 500 kHz is divided by the AS3935 by a minimum of 16 and maximum of 128 as a prescale (software selected), I suspect its output pulse width will not be a problem.

From the datasheet statement, I never would have guessed that is what it meant.

John
 
Your Tcy is 125-nanoseconds with a 32-MHz clock so the 2-uS period of that 500-kHz signal easily meets the (Tcy+40)/prescaler spec'.
 
Actually, the minimum period of the AS3935 output signal is 32 us (16*2) -- hardly a worry, unless it is a narrow spike, which I doubt . :)

In my reading about this before posting, I found several examples for measuring RF up to about 50 MHz with 16F628A and older chips. Here's a link to just one of several: https://www.radioboatanchor.com/blog/build-your-own-pic-based-frequency-counter.

Like you said, the datasheet comment that prompted me to start this thread could have been written more clearly. Now, I feel more comfortable ignoring it.

John
 
I don't believe that the synchronous mode is useful for high frequencies, because the PIC won't be able to count pulses that come in any faster than one per processor cycle. In fact, probably no faster than half that, for reliable operation.

Every PIC based frequency counter that I've come across uses the same counting technique which can be traced back to Microchip Appnote 592. It uses Timer 0 with the 8 bit prescaler in asynchronous mode. I've built my own frequency counters using this same algorithm, and I can't find any fault with the method. It gates the input signal precisely for the specified time, and counts the incoming signal pulses during that period. The only drawback that I can see is that because the gate control is not synchronized to start on a state change of the input signal, the count will will vary from one measurement to the next by ±1/2 bit in the least significant digit. In other words, the displayed count will vary from one measurement to the next between 500 and 501, for a true frequency value of 500. To eliminate this, it's necessary to synchronize the gate to the input signal, but this is not the same kind of synchronization that they are referring to in the various appnotes and datasheets, and there is no way to achieve this kind of synchronization without adding external logic.

Edit: Appnote 592: https://ww1.microchip.com/downloads/en/AppNotes/00592d.pdf
 
Last edited:
I don't believe that the synchronous mode is useful for high frequencies, because the PIC won't be able to count pulses that come in any faster than one per processor cycle. In fact, probably no faster than half that, for reliable operation.
Agreed.. I've seen frequency counters that measure 10x more than the TOSC accurately, So I'm with Bob... I'll keep using asynchronous..
 
Hi Bob and Ian,

I have used asynchronous mode and TMR1 to measure frequency and duty cycle in the past. My initial post here was more simple than that. I just didn't understand the "Microchiplish" of that comment.

As for my project per se, namely using various command modes to control the tuning and operation of the AS3935 device, this particular aspect is just 1 of the 16 modes that I have chosen to implement. In fact, there are four frequency measurement modes for different oscillators, so whatever solution there is for this one will probably work for the other three. I have the other 12 modes pretty much nailed down.

For some reason, AMS requires that the antenna resonance be tuned to ±3.5% of the target frequency of 500 kHz. As default, it outputs that frequency divided by 16 on the INT pin of the chip. One can pick other binary divisors up to 128. So, the target frequency on that pin can be set to 31.250 kHz ( 32 us period) to 3.9 kHz (256 us period). With my MCU at 32 MHz, that leaves me 256 to 2048 Tcy per cycle for housekeeping and math. It is not really high speed. Rather than using TMR0 as a prescale, I can effectively just set to chip to 1:128 as my prescale and use TMR1 directly. However, as for most of my projects, I do have a purpose, but the main reason for pursuing them is the challenge of getting something new to work.

Now, back to using TMR0 to gate TMR1...
The simplest approach is to use the rollover to start and stop TMR1 to get the period and frequency. But, I want to be more elegant than that, if possible. Using capture directly with TMR1 is another option, and I have have used that quite a bit in other projects. It is Plan B.

My initial idea here was to use the overflow pulse from TMR0 to create a capture-like event while allowing TMR1 to run continuously or be gated by hardware. My interpretation of TMR1 timing is that the rollover event should be no different than any other event as T1G_IN is a common path:

upload_2017-8-21_8-49-32.png


Initially, I was attracted to using the "toggle mode" or the "single-pulse and toggle combined mode," described below:

upload_2017-8-21_8-20-14.png

upload_2017-8-21_8-21-37.png
I have been unable to get either to work in simulation with MPLab SIM. In my very limited experience, namely with the 12F1840 and 16F1519 chips, I found that MPLab SIM simulation worked with the 16F1519 for capture, but not with the 12F1840. So, I am beginning to wonder whether the problem in simulation may be a function of that debugger.

My current plan is to strip the program to just this part,remove the AS3935 module (Out of an abundance of caution, I don't want to apply an external signal to its INT pin.) and proceed with hardware debugging. Failing at that, I will just use the capture mode and TMR1 alone.

Any advice on getting either of the two modes just mentioned to work using the TMR0 overflow signal would be greatly appreciated.

Regards, John

EDIT: 11:56 AM local Set up hardware simulation (signal generator + ICD3). Have only tested the single-pulse and toggle combined mode. Works as expected with input to TMR0. That is, on first rollover of TMR0, TMR1 starts and on second rollover, it stops. Monitored both TMR0 and polled T1GVAL.

Using MPLab SIM I got nothing. For example, T1GVAL never changed.
 
Last edited:
Since the subject came up here, I thought I would post some code rather than start a new thread. The following works, but is just one of several versions that can be used. Refer to the timing diagram for the "single-pulse and toggle combined mode" in my post #13.

Code:
GetFreq
;NOTES:
;    1) Other signals are available for testing end, i.e., T1GGO, T1GVAL (x2).
;    TMR1GIF can also trigger an interrupt.  See: timng diagram in DS.
;    2) TMR1 can also accept a pulse directly without using THR0 as its prescaler.
;    3) One can test TMR1IF for rollowver to extend range to lower frequencies.
;    4) As shown here, lowest frequency is about 32 kHz without rollover to TMR1.

     bcf       INTCON,GIE     ;be sure interrupts are off                       |B?                              
     movlb     1              ;OPTION_REG                                       |B1  
     bsf       OPTION_REG,5   ;set TMR0 to counter on T0CKI, incr on L-->H      |B1
     bsf       OPTION_REG,3   ;prescaler not assinged to TMR0, equals 1:1       |B1
                              ;initial Option_Reg = 0x0C (1100 0000)  
     movlb     0              ;T1CON                                            |B0 
     clrf      T1CON          ;clock = instruction clock, bit<0> is on/off
     bsf       T1CON,0        ;turn TMR1 clock on and let run
     clrf      T1GCON         ;
     movlw     b'11010001'    ;gate enable,polarity,single pulse,TMR0 rollover
     movwf     T1GCON         ;
     bsf       T1GCON,5       ;DS warning: do not change toggle mode at same 
                              ;time as changing polarity                          
 GetTMR1                      ;all registers |B0                                                
     bcf       PIR1,TMR1GIF    ;
     clrf      TMR1L          ;
     clrf      TMR1H          ;
     bsf       T1GCON,3       ;T1GGO/done S/W set, H/W clear    
     btfss     PIR1,TMR1GIF  
     bra       $-1    
   
;Display results
     movlw     0x0C           ;clear screen
     call      Put232         ;returns in |B0
     DelayCy   (5*msecs)      ;
     RegPrint  TMR1H          ;
     RegPrint  TMR1L          ;
;Cycle back
     bra       GetTMR1        ;

John
 
Last edited:
UPDATE:
I spent an inordinate amount of time over the weekend and yesterday messing with 32-bit by 16-bit division routines, which was needed to get 5-digit BCD. Got one I liked and my conversion time decreased from a bit over a 1000 Tcy to about half that for typical divisions (e.g., 0x61A80000 ÷ 0x5106 took 516 Tcy). My routine will give a 32-bit quotient. That is, I can divide a 32-bit dividend by 1; although, it is a lengthy process (little over 1000 Tcy) and not really necessary.

Bottom line, with the input set at 31250.0 Hz, readout should be 500.00. Actual was 499.98 and 500.00, which alternated. "Tuning" the calibrated input to 31250.6 Hz gave a very steady 500.00 output. Got a video of it, but discovered I needed to use an off-site host as a link.

Overall, I am pretty happy with the stability of this approach. A related thread about tuning the MCU crystal is here: https://www.electro-tech-online.com/threads/pulling-a-ceramic-resonator.151742/

John
 
Didn't realize you wanted 32 binary to BCD. Have you looked into the double dabble algorithm.

Mike.
 
The actual BIN to BCD is only 16 bit in this instance.

The 32-bit division routine is for my collection of routines. I wanted the 32 bit divide 16 bit to 32 bit for potential use later.

John
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top