Counting Timer0 and Timer1 overflows without any interrupt handler


Results 1 to 33 of 33

Threaded View

  1. #15
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default Re: Counting Timer0 and Timer1 overflows without any interrupt handler

    For this project ... you should not be using interrupts.
    Especially not ON INTERRUPT. There's no guaranteed timing with ON INTERRUPT.

    207 isn't a good value to load in the Timer.
    Since the Timer will normally overflow in 65536 counts, you just need to set bit-7 of the high byte to make it overflow in 32768 counts.
    With a 32768 Hz crystal, it will overflow in exactly 1 second.

    Timer1 doesn't free-run. You need to stop and start it so that you can synchronize the Timer0 Gate output with Timer1's 1 second window.

    Since the PIC's changed now, the oscillator's changed and interrupts are introduced ...
    I think I'll just post my code for the 877A simulation in post #5.
    Hopefully you can convert it for your needs with a different PIC.

    Code:
    ; DT_FREQy.pbp
    ;
    ; Created     : Mon Feb 3 2014
    ; Processor   : PIC16F877A
    ; Compiler    : PicBasic Pro 3.0
    
    ;----[Device Configuration]--(See manual section 4.9)---------------------------
    #CONFIG
      __config  _HS_OSC & _WDT_OFF & _PWRTE_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _WRT_OFF & _DEBUG_OFF & _CP_OFF
    #ENDCONFIG
    
    ;----[DEFINEs]------------------------------------------------------------------
    DEFINE OSC 20
    
    DEFINE LCD_DREG PORTD         ; LCD data port
    DEFINE LCD_DBIT 4             ; LCD data starting bit 0 or 4
    DEFINE LCD_RSREG PORTD        ; LCD register select port
    DEFINE LCD_RSBIT 2            ; LCD register select bit
    DEFINE LCD_EREG PORTD         ; LCD enable port
    DEFINE LCD_EBIT 3             ; LCD enable bit
    DEFINE LCD_BITS 4             ; LCD bus size 4 or 8
    DEFINE LCD_LINES 2            ; LCD Number lines on LCD
    DEFINE LCD_COMMANDUS 2000     ; LCD Command delay time in us
    DEFINE LCD_DATAUS 50          ; LCD Data delay time in us
    
    ;----[Aliases]------------------------------------------------------------------
    Timer1    VAR WORD EXT : @Timer1 = TMR1L
    TMR0IF    VAR INTCON.2
    TMR0CS    VAR OPTION_REG.5
    TMR1IF    VAR PIR1.0
    TMR1CS    VAR T1CON.1         ; Timer1 Clock Source Select bit
    T1OSCEN   VAR T1CON.3         ; Timer1 Oscillator Enable Control bit
    TMR1ON    VAR T1CON.0         ; Timer1 On bit
    T1OSI     VAR PORTC.1         ; 32768 Hz input pin
    PSCLKOUT  VAR PORTA.3         ; pin to clock out the remaining prescaler
    PSA       VAR OPTION_REG.3    ; Prescaler Assignment bit
    
    ;----[Variables]----------------------------------------------------------------
    Result     VAR WORD[2]        ; Final 32-bit Frequency measurement
    T0overflow VAR Result[1]      ; Counts Timer0 overflows (HighWord of the result)
    T0value    VAR Result.BYTE1   ; Final Timer0 value
    PScount    VAR Result.BYTE0   ; Final Timer0 Prescaler value
    
    FreqHigh   VAR WORD           ; Top five digits of the decimal result
    FreqLow    VAR WORD           ; Bottom 3 digits of the decimal result
    MeasCount  VAR WORD           ; Counts number of measurements
    
    ;----[Initialize]---------------------------------------------------------------
    ADCON1 = 7                    ; All Digital
    CMCON  = 7
    T1OSCEN = 1                   ; Start Timer1 oscillator
    PAUSE 250                     ; LCD Power-Up delay 
    LCDOUT $FE,1,"DT's FREQy"
    MeasCount = 0                 ; clear the measurement count
    
    ;----[Main Program Loop]--------------------------------------------------------
    Main:
        GOSUB MeasureFreq         ; Get a Frequency Measurement
        GOSUB DisplayFreq         ; Display the Frequency
    
        MeasCount = MeasCount + 1 ; increment and display measurement count
        LCDOUT $FE,$94,"Meas = ", DEC MeasCount
    GOTO Main
    
    ;----[Measure frequency on T0CKI]-----------------------------------------------
    MeasureFreq:
        LOW PSCLKOUT          ; prevent signal from getting to Timer0
        PSA = 0               ; Prescaler is assigned to the Timer0 module
        TMR0CS = 1            ; Transition on T0CKI pin
        TMR1CS = 1            ; Timer1 Clock source = T1CKI (T1OSC)
        TMR1ON = 0            ; Stop Timer1
        TMR0IF = 0            ; Clear Timer0 overflow flag
        T0overflow = 0        ; Clear Timer0 overflow count
        TMR0 = 0              ; Clear Timer0 value
    
        Timer1 = $FFFF        ; Timer1 overflows on next cycle of 32768 Hz clock
        TMR1IF = 0            ; Clear Timer1 overflow flag
        TMR1ON = 1            ; Start Timer1 1 sec. period
        WHILE !TMR1IF : WEND  ; Synchronize to 32768 clock
        INPUT PSCLKOUT        ; Start counting freq input
        Timer1.15 = 1         ; Set Timer1 to 32768 for 1 Sec. period
        TMR1IF = 0            ; Clear Timer1 overflow flag
    
        WHILE !TMR1IF         ; while 1 sec. window is open  ---|
            IF TMR0IF THEN    ; count TMR0 overflows            | This section
                T0overflow = T0overflow + 1  ;                  | does the actual
                TMR0IF = 0                   ;                  | 1-Sec measurement
            ENDIF                            ;                  | Window
        WEND                                 ;               ---|
        LOW PSCLKOUT           ; Stop further counting
        T0value = TMR0         ; get Timer0 value
    
        PScount = 0            ; Clock out remaining prescaler
        WHILE TMR0 = T0value   ; until TMR0 value changes
            HIGH PSCLKOUT
            PAUSEUS 3
            LOW PSCLKOUT
            PAUSEUS 3
            PScount = PScount + 1
        WEND
        PScount = -PScount     ; negate to get prescaler count
    RETURN
    
    ;----[Display frequency on LCD]-------------------------------------------------
    DisplayFreq
        R2 = Result            ; Load Result into PBP's system vars for DIV32
        R0 = Result[1]
        FreqHigh = DIV32 1000  ; get left most 5 digits
        FreqLow = R2           ; remainder (R2) is right 3 digits
    
        LCDOUT $FE,$C0,"Freq = "
        IF FreqHigh > 0 THEN                        ; if any left digits
            LCDOUT DEC FreqHigh, DEC3 FreqLow,"   " ; display both left and right
        ELSE                                        ;  otherwise 
            LCDOUT DEC FreqLow,"     "              ; display only right digits
        ENDIF
    RETURN
    
    END
    Last edited by Darrel Taylor; - 17th February 2014 at 20:34.
    DT

Similar Threads

  1. Expanding Timer1 counting range
    By sycluap in forum mel PIC BASIC Pro
    Replies: 14
    Last Post: - 3rd February 2014, 23:00
  2. PIC18 timer0 interrupt handler, still not getting it
    By ImAnEE in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 30th April 2011, 01:25
  3. DT-INTs Interrupt handler question
    By circuitpro in forum mel PIC BASIC Pro
    Replies: 1
    Last Post: - 8th January 2010, 01:06
  4. Synchronising Timer0 and Timer1
    By manxman in forum mel PIC BASIC Pro
    Replies: 8
    Last Post: - 10th April 2008, 00:12
  5. 16F690 TIMER0 and TIMER1
    By nickdaprick in forum mel PIC BASIC
    Replies: 2
    Last Post: - 18th April 2007, 15:49

Members who have read this thread : 1

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts