Quantcast
Channel: MCS Electronics Forum
Viewing all articles
Browse latest Browse all 20643

BASCOM-AVR : pulse length capture : REPLY

$
0
0
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]

Viewing all articles
Browse latest Browse all 20643

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>