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




Bookmarks