Measuring frequency:
[code:1:4280413832]$regfile = "m32def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 9600
Const True = 1
Const False = 0
Const Measure_success = 0
Const Measure_timeout = 1
Const Measure_request = 2
Const to_Sec = 1.0 ' timeout in seconds
Const t1_prescale = 1 ' prescaler of timer 1
Const Max_Overflows = int((_XTAL / t1_prescale / 65536) * to_Sec)
Const xtalmul = _XTAL * 100
Const falling_edge = 0
Const rising_edge = 1
Dim Frequency As Long
Dim Capt_prev_val As Word
Dim Capt_curr_val As Word
Dim Measure_result As Long
Dim Capt_result As Word At Measure_result Overlay ' difference of capture is the low-word of Measure_Result
Dim Ovf_result As Word At Measure_result + 2 Overlay ' overflows account for the high-word of Measure_Result
Dim Ovf_ctr As Word
Dim F_str As String * 10
' vars for the state machine
Dim Got_edge As Byte
Dim Measure_status As Byte
' trigger by ICP1 at PD6
Config Timer1 = Timer , Prescale = 1 , Capture Edge = Rising
On Capture1 Isr_capt Nosave
Enable Capture1
On Ovf1 Isr_ovf
Enable Ovf1
Ovf_ctr = 0
Got_edge = False
Tifr = Bits(icf1 , Tov1) ' clear pending interrupts
Enable Interrupts
Print "START"
Wait 1
Measure_status = Measure_request ' trigger first measurement
Do
If Measure_status <> Measure_request Then
If Measure_status = Measure_timeout Then
Print "Timeout No Result "
End If
If Measure_status = Measure_success Then
If Measure_result > 0 Then
Frequency = xtalmul / Measure_result
F_str = Str(frequency)
Print "Frequency: " ; Format(f_str , "00000.00") ; " Hz"
End If
End If
Measure_status = Measure_request ' do another measurement
End If
Waitms 300
Loop
End
Isr_capt:
PUSH R22 ' this reads the ICP register as early as possible
LDS R22, ICR1L
STS {Capt_curr_val}, R22
LDS R22, ICR1H
STS {Capt_curr_val +1}, R22
POP R22
Pushall ' required for the rest of Bascom interrupt code
If Measure_status = Measure_request And Got_edge = True Then ' got a measure request and signal edge found ?
Capt_result = Capt_curr_val - Capt_prev_val ' calculate difference of start and end
Measure_status = Measure_success
If Capt_curr_val < Capt_prev_val Then ' check for real overflow
Decr Ovf_ctr ' boundary crossed, decrease real overflow by one
End If
Ovf_result = Ovf_ctr
End If
Capt_prev_val = Capt_curr_val ' save current capture value
Ovf_ctr = 0 ' reset overflow counter
Got_edge = True
Popall
Return
Isr_ovf:
Incr Ovf_ctr
If Ovf_ctr > Max_Overflows Then
Got_edge = False
Ovf_ctr = 0
Measure_status = Measure_timeout
End If
Return[/code:1:4280413832]
Measuring periods:
[code:1:4280413832]$regfile = "m32def.dat"
$crystal = 16000000
$hwstack = 64
$swstack = 64
$framesize = 64
$baud = 9600
Const True = 1
Const False = 0
Const Measure_success = 0
Const Measure_timeout = 1
Const Measure_request = 2
Const to_Sec = 1.0 ' timeout in seconds
Const t1_prescale = 1 ' prescaler of timer 1
Const Max_Overflows = int((_XTAL / t1_prescale / 65536) * to_Sec)
Const xtaldiv = _XTAL / 1000000
Const falling_edge = 0
Const rising_edge = 1
Dim Duration As Long
Dim Capt_prev_val As Word
Dim Capt_curr_val As Word
Dim Measure_result As Long
Dim Capt_result As Word At Measure_result Overlay ' difference of capture is the low-word of Measure_Result
Dim Ovf_result As Word At Measure_result + 2 Overlay ' overflows account for the high-word of Measure_Result
Dim Ovf_ctr As Word
Dim F_str As String * 10
' vars for the state machine
Dim Measure_status As Byte
' trigger by ICP1 at PD6
Config Timer1 = Timer , Prescale = t1_prescale , Capture Edge = Rising
On Capture1 Isr_capt Nosave
Enable Capture1
On Ovf1 Isr_ovf
Enable Ovf1
Ovf_ctr = 0
Tifr = Bits(icf1 , Tov1) ' clear pending interrupts
Enable Interrupts
Print "START"
Wait 1
Measure_status = Measure_request ' trigger first measurement
Do
If Measure_status <> Measure_request Then
If Measure_status = Measure_timeout Then
Print "Timeout No Result "
End If
If Measure_status = Measure_success Then
If Measure_result > 0 Then
Duration = Measure_result / xtaldiv
F_str = Str(Duration)
Print "Duration: " ; Format(f_str , "000.000") ; " mS"
End If
End If
Measure_status = Measure_request ' do another measurement
End If
Waitms 300
Loop
End
Isr_capt:
PUSH R22 ' this reads the ICP register as early as possible
LDS R22, ICR1L
STS {Capt_curr_val}, R22
LDS R22, ICR1H
STS {Capt_curr_val +1}, R22
POP R22
Pushall ' required for the rest of Bascom interrupt code
If Measure_status = Measure_request Then ' got a measure request
If TCCR1B.ICES1 = falling_edge Then ' got a rising edge and waiting for falling
Capt_result = Capt_curr_val - Capt_prev_val ' calculate difference of start and end
Measure_status = Measure_success
If Capt_curr_val < Capt_prev_val Then ' check for real overflow
Decr Ovf_ctr ' boundary crossed, decrease real overflow by one
End If
Ovf_result = Ovf_ctr
TCCR1B.ICES1 = rising_edge ' re-init to detect rising edge
Else
TCCR1B.ICES1 = falling_edge ' switch to falling edge
End If
End If
Capt_prev_val = Capt_curr_val ' save current capture value
Ovf_ctr = 0 ' reset overflow counter
Popall
Return
Isr_ovf:
Incr Ovf_ctr
If Ovf_ctr > Max_Overflows Then
TCCR1B.ICES1 = rising_edge
Ovf_ctr = 0
Measure_status = Measure_timeout
End If
Return[/code:1:4280413832]
↧