Hi,
OK, this version generates the 60Hz, 50% dutycycle in the background using TMR0 and DT-Ints.
Since we are generating the output I don't see the need to feed the signal back into the PIC to trig on.
Anyway, this compiles and runs on a 16F628 here on my breadboard. It generates the 60Hz output but I haven't actually fed any pulses back into it to see if the actual measurment code works. You'll have to do that yourself. Please note that since we're using interrupts in the background you can not use SEROUT to send the data since the interrupts will mess with the timing. Fortunately the 628/648 have an USART - use it with HSEROUT as in the code.
Let us know how it works out.
Code:
DEFINE NO_CLRWDT 1 ' We need the prescaler for TMR0, can't use the WDT
DEFINE OSC 20 ' Running with a 20MHz x-tal
#CONFIG
__config _HS_OSC & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF
#ENDCONFIG
' Variables needed by DT-INTS (we miss you Darrel!)
wsave VAR BYTE $70 SYSTEM
wsave1 VAR BYTE $A0 SYSTEM
wsave2 VAR BYTE $120 SYSTEM
Time1 VAR WORD ' Time between leading edge of Pulse1 and leading edge of Pulse2
Time2 VAR WORD ' Time between leading edge of Pulse1 and leading edge of Pulse3
Temp VAR BYTE ' Temporary variable, use at will
Measure VAR BIT ' Semaphore to indicate when we want to start a measurment.
TrigOut VAR PortB.3 ' Pin for 60Hz output
Pulse1 VAR PortB.4 ' Input pin for first pulse
Pulse2 VAR PortB.5 ' Input pin for second pulse
TMR1IF VAR PIR1.0 ' Alias to TMR1 interrupt request flag which we use for timeout feature.
INCLUDE "DT_INTS-14.bas"
INCLUDE "ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler TMR0_INT, _ISR, PBP, yes
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
OPTION_REG = %11000111 ' Prescaler assigned to TMR0, 1:256 ratio
TRISB = %11110111 ' Set PortB direction.
@ INT_ENABLE TMR0_INT ; Enable the 120Hz interrupt for the square wave generator.
Main:
Pause 1000
Gosub Capture
IF TMR1IF THEN
HSEROUT["Timeout before capturing both pulses.",13]
ELSE
HSEROUT["Time 1: ", DEC5 Time1, " ticks.",13]
HSEROUT["Time 2: ", DEC5 Time2, " ticks.",13]
ENDIF
Goto Main
'-------------------------------------------------------------------------------
Capture:
Measure = 1
While Measure = 1 : WEND ' Wait untill ISR have created the rising edge and started the timer
'-------------------------------------------------------------------------------
' Now look for the rising edge of the two pulses we're expecting to recieve.
' Once we see the pulse we grab the TMR1 value and store it.
' If we don't get both pulses before the TMR1 overflows (as indicated by
' the TMR1 Interrupt Flag) we abort the operation. This happens after
' 200ns * 2^16 = ~13ms.
DO
' Do we have a rising edge on Pulse1 input?
' Capture value ONLY if we haven't already done so.
IF Pulse1 AND (Time1 = 0) THEN
Time1.HighBYTE = TMR1H
Time1.LowBYTE = TMR1L
' Make sure TMR1L didn't overflow inbetween reading the high and low byte
Temp = TMR1H
If Temp <> Time1.HIGHBYTE THEN
Time1.HighBYTE = TMR1H
Time1.LowBYTE = TMR1L
ENDIF
ENDIF
'-------------------------------------------------------------------------------
' Do we have a rising edge on Pulse2 input?
' Capture value ONLY if we haven't already done so.
IF Pulse2 AND (Time2 = 0) THEN
Time2.HIGHBYTE = TMR1H
Time2.LOWBYTE = TMR1H
' Make sure TMR1L didn't overflow inbetween reading the high and low byte
Temp = TMR1H
If Temp <> Time2.HIGHBYTE THEN
Time2.HighBYTE = TMR1H
Time2.LowBYTE = TMR1L
ENDIF
ENDIF
LOOP UNTIL ((Time1 <> 0) AND (Time2 <> 0)) OR TMR1IF
'-------------------------------------------------------------------------------
RETURN
'-------------------------------------------------------------------------------
ISR:
If TrigOut = 0 THEN ' If trig output is low....
If Measure = 1 THEN ' ...and we want to start a measurment
T1CON.0 = 0 : TMR1IF = 0 ' Stop timer and clear interrupt flag
TMR1H = 0 : TMR1L = 0 ' Clear the time
Time1 = 0 : Time2 = 0 ' Clear measurements
T1CON.0 = 1 ' And start the timer
Measure = 0 ' Let main program know we've set the ball in motion.
ENDIF
TrigOut = 1 ' Set trig output high
ELSE
TrigOut = 0 ' Trig output was high, set it low.
ENDIF
TMR0 = TMR0 + 94 ' Reload TMR0 for 120Hz interrupt rate
@ INT_RETURN
'-------------------------------------------------------------------------------
/Henrik.
Bookmarks